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());
        }
    }
}