GeneratorCopyTest.java
package com.fasterxml.jackson.core.write;
import java.io.*;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Set of basic unit tests for verifying that copy-through methods
* of {@link JsonGenerator} work as expected.
*/
class GeneratorCopyTest
extends JUnit5TestBase
{
private final JsonFactory JSON_F = sharedStreamFactory();
@Test
void copyRootTokens()
throws IOException
{
JsonFactory jf = JSON_F;
final String DOC = "\"text\\non two lines\" true false 2.0 null 1234567890123 ";
JsonParser jp = jf.createParser(new StringReader(DOC));
StringWriter sw = new StringWriter();
JsonGenerator gen = jf.createGenerator(sw);
JsonToken t;
while ((t = jp.nextToken()) != null) {
gen.copyCurrentEvent(jp);
// should not change parser state:
assertToken(t, jp.currentToken());
}
jp.close();
gen.close();
assertEquals("\"text\\non two lines\" true false 2.0 null 1234567890123", sw.toString());
}
@Test
void copyArrayTokens()
throws IOException
{
JsonFactory jf = JSON_F;
final String DOC = "123 [ 1, null, [ false, 1234567890124 ] ]";
JsonParser jp = jf.createParser(new StringReader(DOC));
StringWriter sw = new StringWriter();
JsonGenerator gen = jf.createGenerator(sw);
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
gen.copyCurrentEvent(jp);
// should not change parser state:
assertToken(JsonToken.VALUE_NUMBER_INT, jp.currentToken());
assertEquals(123, jp.getIntValue());
// And then let's copy the array
assertToken(JsonToken.START_ARRAY, jp.nextToken());
gen.copyCurrentStructure(jp);
// which will advance parser to matching close Array
assertToken(JsonToken.END_ARRAY, jp.currentToken());
jp.close();
gen.close();
assertEquals("123 [1,null,[false,1234567890124]]", sw.toString());
}
@Test
void copyObjectTokens()
throws IOException
{
JsonFactory jf = JSON_F;
final String DOC = "{ \"a\":1, \"b\":[{ \"c\" : null, \"d\" : 0.25 }] }";
JsonParser jp = jf.createParser(new StringReader(DOC));
StringWriter sw = new StringWriter();
JsonGenerator gen = jf.createGenerator(sw);
assertToken(JsonToken.START_OBJECT, jp.nextToken());
gen.copyCurrentStructure(jp);
// which will advance parser to matching end Object
assertToken(JsonToken.END_OBJECT, jp.currentToken());
jp.close();
gen.close();
assertEquals("{\"a\":1,\"b\":[{\"c\":null,\"d\":0.25}]}", sw.toString());
// but also sort of special case of field name plus value
jp = jf.createParser(new StringReader("{\"a\":1,\"b\":null}"));
sw = new StringWriter();
gen = jf.createGenerator(sw);
gen.writeStartObject();
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
gen.copyCurrentStructure(jp);
gen.writeEndObject();
jp.close();
gen.close();
assertEquals("{\"a\":1}", sw.toString());
}
@Test
void copyNumericTokensExactly()
throws Exception
{
JsonFactory jf = JSON_F;
final String DOC = a2q("{ 'a':0.123456789123456789123456789, 'b':[" +
"{ 'c' : null, 'd' : 0.123456789123456789123456789 }] }");
try(JsonParser jp = jf.createParser(new StringReader(DOC))) {
StringWriter sw = new StringWriter();
try (JsonGenerator gen = jf.createGenerator(sw)) {
assertToken(JsonToken.START_OBJECT, jp.nextToken());
gen.copyCurrentStructureExact(jp);
// which will advance parser to matching end Object
assertToken(JsonToken.END_OBJECT, jp.currentToken());
}
assertEquals(
a2q("{'a':0.123456789123456789123456789,'b':[" +
"{'c':null,'d':0.123456789123456789123456789}]}"),
sw.toString()
);
}
try(JsonParser jp = jf.createParser(new StringReader("0.123456789123456789123456789"))) {
StringWriter sw = new StringWriter();
try (JsonGenerator gen = jf.createGenerator(sw)) {
assertToken(JsonToken.VALUE_NUMBER_FLOAT, jp.nextToken());
gen.copyCurrentStructureExact(jp);
assertToken(JsonToken.VALUE_NUMBER_FLOAT, jp.currentToken());
}
assertEquals("0.123456789123456789123456789", sw.toString());
}
}
}