blob: 337453116082811b19f3280518e3e0751e03bfd0 [file] [log] [blame]
package com.fasterxml.jackson.databind.util;
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.util.JsonParserSequence;
public class TestTokenBuffer extends com.fasterxml.jackson.test.BaseTest
{
/*
/**********************************************************
/* Basic TokenBuffer tests
/**********************************************************
*/
/**
* Test writing of individual simple values
*/
public void testSimpleWrites() throws IOException
{
TokenBuffer buf = new TokenBuffer(null, false); // no ObjectCodec
// First, with empty buffer
JsonParser jp = buf.asParser();
assertNull(jp.getCurrentToken());
assertNull(jp.nextToken());
jp.close();
// Then with simple text
buf.writeString("abc");
// First, simple text
jp = buf.asParser();
assertNull(jp.getCurrentToken());
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
assertEquals("abc", jp.getText());
assertNull(jp.nextToken());
jp.close();
// Then, let's append at root level
buf.writeNumber(13);
jp = buf.asParser();
assertNull(jp.getCurrentToken());
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
assertEquals(13, jp.getIntValue());
assertNull(jp.nextToken());
jp.close();
buf.close();
}
public void testSimpleArray() throws IOException
{
TokenBuffer buf = new TokenBuffer(null, false); // no ObjectCodec
// First, empty array
assertTrue(buf.getOutputContext().inRoot());
buf.writeStartArray();
assertTrue(buf.getOutputContext().inArray());
buf.writeEndArray();
assertTrue(buf.getOutputContext().inRoot());
JsonParser jp = buf.asParser();
assertNull(jp.getCurrentToken());
assertTrue(jp.getParsingContext().inRoot());
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertTrue(jp.getParsingContext().inArray());
assertToken(JsonToken.END_ARRAY, jp.nextToken());
assertTrue(jp.getParsingContext().inRoot());
assertNull(jp.nextToken());
jp.close();
buf.close();
// Then one with simple contents
buf = new TokenBuffer(null, false);
buf.writeStartArray();
buf.writeBoolean(true);
buf.writeNull();
buf.writeEndArray();
jp = buf.asParser();
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
assertTrue(jp.getBooleanValue());
assertToken(JsonToken.VALUE_NULL, jp.nextToken());
assertToken(JsonToken.END_ARRAY, jp.nextToken());
assertNull(jp.nextToken());
jp.close();
buf.close();
// And finally, with array-in-array
buf = new TokenBuffer(null, false);
buf.writeStartArray();
buf.writeStartArray();
buf.writeBinary(new byte[3]);
buf.writeEndArray();
buf.writeEndArray();
jp = buf.asParser();
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertToken(JsonToken.START_ARRAY, jp.nextToken());
// TokenBuffer exposes it as embedded object...
assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, jp.nextToken());
Object ob = jp.getEmbeddedObject();
assertNotNull(ob);
assertTrue(ob instanceof byte[]);
assertEquals(3, ((byte[]) ob).length);
assertToken(JsonToken.END_ARRAY, jp.nextToken());
assertToken(JsonToken.END_ARRAY, jp.nextToken());
assertNull(jp.nextToken());
jp.close();
buf.close();
}
public void testSimpleObject() throws IOException
{
TokenBuffer buf = new TokenBuffer(null, false);
// First, empty JSON Object
assertTrue(buf.getOutputContext().inRoot());
buf.writeStartObject();
assertTrue(buf.getOutputContext().inObject());
buf.writeEndObject();
assertTrue(buf.getOutputContext().inRoot());
JsonParser jp = buf.asParser();
assertNull(jp.getCurrentToken());
assertTrue(jp.getParsingContext().inRoot());
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertTrue(jp.getParsingContext().inObject());
assertToken(JsonToken.END_OBJECT, jp.nextToken());
assertTrue(jp.getParsingContext().inRoot());
assertNull(jp.nextToken());
jp.close();
buf.close();
// Then one with simple contents
buf = new TokenBuffer(null, false);
buf.writeStartObject();
buf.writeNumberField("num", 1.25);
buf.writeEndObject();
jp = buf.asParser();
assertNull(jp.getCurrentToken());
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertNull(jp.getCurrentName());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals("num", jp.getCurrentName());
// and override should also work:
jp.overrideCurrentName("bah");
assertEquals("bah", jp.getCurrentName());
assertToken(JsonToken.VALUE_NUMBER_FLOAT, jp.nextToken());
assertEquals(1.25, jp.getDoubleValue());
// should still have access to (overridden) name
assertEquals("bah", jp.getCurrentName());
assertToken(JsonToken.END_OBJECT, jp.nextToken());
// but not any more
assertNull(jp.getCurrentName());
assertNull(jp.nextToken());
jp.close();
buf.close();
}
/**
* Verify handling of that "standard" test document (from JSON
* specification)
*/
public void testWithJSONSampleDoc() throws Exception
{
// First, copy events from known good source (StringReader)
JsonParser jp = createParserUsingReader(SAMPLE_DOC_JSON_SPEC);
TokenBuffer tb = new TokenBuffer(null, false);
while (jp.nextToken() != null) {
tb.copyCurrentEvent(jp);
}
// And then request verification; first structure only:
verifyJsonSpecSampleDoc(tb.asParser(), false);
// then content check too:
verifyJsonSpecSampleDoc(tb.asParser(), true);
tb.close();
jp.close();
}
public void testAppend() throws IOException
{
TokenBuffer buf1 = new TokenBuffer(null, false);
buf1.writeStartObject();
buf1.writeFieldName("a");
buf1.writeBoolean(true);
TokenBuffer buf2 = new TokenBuffer(null, false);
buf2.writeFieldName("b");
buf2.writeNumber(13);
buf2.writeEndObject();
buf1.append(buf2);
// and verify that we got it all...
JsonParser jp = buf1.asParser();
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals("a", jp.getCurrentName());
assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals("b", jp.getCurrentName());
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
assertEquals(13, jp.getIntValue());
assertToken(JsonToken.END_OBJECT, jp.nextToken());
jp.close();
buf1.close();
buf2.close();
}
/*
/**********************************************************
/* Tests to verify interaction of TokenBuffer and JsonParserSequence
/**********************************************************
*/
public void testWithJsonParserSequenceSimple() throws IOException
{
// Let's join a TokenBuffer with JsonParser first
TokenBuffer buf = new TokenBuffer(null, false);
buf.writeStartArray();
buf.writeString("test");
JsonParser jp = createParserUsingReader("[ true, null ]");
JsonParserSequence seq = JsonParserSequence.createFlattened(buf.asParser(), jp);
assertEquals(2, seq.containedParsersCount());
assertFalse(jp.isClosed());
assertFalse(seq.hasCurrentToken());
assertNull(seq.getCurrentToken());
assertNull(seq.getCurrentName());
assertToken(JsonToken.START_ARRAY, seq.nextToken());
assertToken(JsonToken.VALUE_STRING, seq.nextToken());
assertEquals("test", seq.getText());
// end of first parser input, should switch over:
assertToken(JsonToken.START_ARRAY, seq.nextToken());
assertToken(JsonToken.VALUE_TRUE, seq.nextToken());
assertToken(JsonToken.VALUE_NULL, seq.nextToken());
assertToken(JsonToken.END_ARRAY, seq.nextToken());
/* 17-Jan-2009, tatus: At this point, we may or may not get an
* exception, depending on how underlying parsers work.
* Ideally this should be fixed, probably by asking underlying
* parsers to disable checking for balanced start/end markers.
*/
// for this particular case, we won't get an exception tho...
assertNull(seq.nextToken());
// not an error to call again...
assertNull(seq.nextToken());
// also: original parsers should be closed
assertTrue(jp.isClosed());
jp.close();
buf.close();
seq.close();
}
/**
* Test to verify that TokenBuffer and JsonParserSequence work together
* as expected.
*/
@SuppressWarnings("resource")
public void testWithMultipleJsonParserSequences() throws IOException
{
TokenBuffer buf1 = new TokenBuffer(null, false);
buf1.writeStartArray();
TokenBuffer buf2 = new TokenBuffer(null, false);
buf2.writeString("a");
TokenBuffer buf3 = new TokenBuffer(null, false);
buf3.writeNumber(13);
TokenBuffer buf4 = new TokenBuffer(null, false);
buf4.writeEndArray();
JsonParserSequence seq1 = JsonParserSequence.createFlattened(buf1.asParser(), buf2.asParser());
assertEquals(2, seq1.containedParsersCount());
JsonParserSequence seq2 = JsonParserSequence.createFlattened(buf3.asParser(), buf4.asParser());
assertEquals(2, seq2.containedParsersCount());
JsonParserSequence combo = JsonParserSequence.createFlattened(seq1, seq2);
// should flatten it to have 4 underlying parsers
assertEquals(4, combo.containedParsersCount());
assertToken(JsonToken.START_ARRAY, combo.nextToken());
assertToken(JsonToken.VALUE_STRING, combo.nextToken());
assertEquals("a", combo.getText());
assertToken(JsonToken.VALUE_NUMBER_INT, combo.nextToken());
assertEquals(13, combo.getIntValue());
assertToken(JsonToken.END_ARRAY, combo.nextToken());
assertNull(combo.nextToken());
buf1.close();
buf2.close();
buf3.close();
buf4.close();
}
}