• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.util;
2 
3 import java.io.*;
4 import java.math.BigDecimal;
5 import java.math.BigInteger;
6 import java.util.UUID;
7 
8 import com.fasterxml.jackson.core.*;
9 import com.fasterxml.jackson.core.JsonParser.NumberType;
10 import com.fasterxml.jackson.core.exc.InputCoercionException;
11 import com.fasterxml.jackson.core.io.SerializedString;
12 import com.fasterxml.jackson.core.util.JsonParserSequence;
13 
14 import com.fasterxml.jackson.databind.*;
15 
16 public class TestTokenBuffer extends BaseMapTest
17 {
18     private final ObjectMapper MAPPER = objectMapper();
19 
20     static class Base1730 { }
21 
22     static class Sub1730 extends Base1730 { }
23 
24     /*
25     /**********************************************************
26     /* Basic TokenBuffer tests
27     /**********************************************************
28      */
29 
testBasicConfig()30     public void testBasicConfig() throws IOException
31     {
32         TokenBuffer buf;
33 
34         buf = new TokenBuffer(MAPPER, false);
35         assertEquals(MAPPER.version(), buf.version());
36         assertSame(MAPPER, buf.getCodec());
37         assertNotNull(buf.getOutputContext());
38         assertFalse(buf.isClosed());
39 
40         buf.setCodec(null);
41         assertNull(buf.getCodec());
42 
43         assertFalse(buf.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN));
44         buf.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
45         assertTrue(buf.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN));
46         buf.disable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
47         assertFalse(buf.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN));
48 
49         buf.close();
50         assertTrue(buf.isClosed());
51     }
52 
53     /**
54      * Test writing of individual simple values
55      */
testSimpleWrites()56     public void testSimpleWrites() throws IOException
57     {
58         TokenBuffer buf = new TokenBuffer(null, false); // no ObjectCodec
59 
60         // First, with empty buffer
61         JsonParser p = buf.asParser();
62         assertNull(p.currentToken());
63         assertNull(p.nextToken());
64         p.close();
65 
66         // Then with simple text
67         buf.writeString("abc");
68 
69         p = buf.asParser();
70         assertNull(p.currentToken());
71         assertToken(JsonToken.VALUE_STRING, p.nextToken());
72         assertEquals("abc", p.getText());
73         assertNull(p.nextToken());
74         p.close();
75 
76         // Then, let's append at root level
77         buf.writeNumber(13);
78         p = buf.asParser();
79         assertNull(p.currentToken());
80         assertToken(JsonToken.VALUE_STRING, p.nextToken());
81         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
82         assertEquals(13, p.getIntValue());
83         assertNull(p.nextToken());
84         p.close();
85         buf.close();
86     }
87 
88     // For 2.9, explicit "isNaN" check
testSimpleNumberWrites()89     public void testSimpleNumberWrites() throws IOException
90     {
91         TokenBuffer buf = new TokenBuffer(null, false);
92 
93         double[] values1 = new double[] {
94                 0.25, Double.NaN, -2.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY
95         };
96         float[] values2 = new float[] {
97                 Float.NEGATIVE_INFINITY,
98                 0.25f,
99                 Float.POSITIVE_INFINITY
100         };
101 
102         for (double v : values1) {
103             buf.writeNumber(v);
104         }
105         for (float v : values2) {
106             buf.writeNumber(v);
107         }
108 
109         JsonParser p = buf.asParser();
110         assertNull(p.currentToken());
111 
112         for (double v : values1) {
113             assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
114             double actual = p.getDoubleValue();
115             boolean expNan = Double.isNaN(v) || Double.isInfinite(v);
116             assertEquals(expNan, p.isNaN());
117             assertEquals(0, Double.compare(v, actual));
118         }
119         for (float v : values2) {
120             assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
121             float actual = p.getFloatValue();
122             boolean expNan = Float.isNaN(v) || Float.isInfinite(v);
123             assertEquals(expNan, p.isNaN());
124             assertEquals(0, Float.compare(v, actual));
125         }
126         p.close();
127         buf.close();
128     }
129 
130     // [databind#1729]
testNumberOverflowInt()131     public void testNumberOverflowInt() throws IOException
132     {
133         try (TokenBuffer buf = new TokenBuffer(null, false)) {
134             long big = 1L + Integer.MAX_VALUE;
135             buf.writeNumber(big);
136             try (JsonParser p = buf.asParser()) {
137                 assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
138                 assertEquals(NumberType.LONG, p.getNumberType());
139                 try {
140                     p.getIntValue();
141                     fail("Expected failure for `int` overflow");
142                 } catch (InputCoercionException e) {
143                     verifyException(e, "Numeric value ("+big+") out of range of int");
144                 }
145             }
146         }
147         // and ditto for coercion.
148         try (TokenBuffer buf = new TokenBuffer(null, false)) {
149             long big = 1L + Integer.MAX_VALUE;
150             buf.writeNumber(String.valueOf(big));
151             try (JsonParser p = buf.asParser()) {
152                 // NOTE: oddity of buffering, no inspection of "real" type if given String...
153                 assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
154                 try {
155                     p.getIntValue();
156                     fail("Expected failure for `int` overflow");
157                 } catch (InputCoercionException e) {
158                     verifyException(e, "Numeric value ("+big+") out of range of int");
159                 }
160             }
161         }
162     }
163 
testNumberOverflowLong()164     public void testNumberOverflowLong() throws IOException
165     {
166         try (TokenBuffer buf = new TokenBuffer(null, false)) {
167             BigInteger big = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
168             buf.writeNumber(big);
169             try (JsonParser p = buf.asParser()) {
170                 assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
171                 assertEquals(NumberType.BIG_INTEGER, p.getNumberType());
172                 try {
173                     p.getLongValue();
174                     fail("Expected failure for `long` overflow");
175                 } catch (InputCoercionException e) {
176                     verifyException(e, "Numeric value ("+big+") out of range of long");
177                 }
178             }
179         }
180     }
181 
testParentContext()182     public void testParentContext() throws IOException
183     {
184         TokenBuffer buf = new TokenBuffer(null, false); // no ObjectCodec
185         buf.writeStartObject();
186         buf.writeFieldName("b");
187         buf.writeStartObject();
188         buf.writeFieldName("c");
189         //This assertion succeeds as expected
190         assertEquals("b", buf.getOutputContext().getParent().getCurrentName());
191         buf.writeString("cval");
192         buf.writeEndObject();
193         buf.writeEndObject();
194         buf.close();
195     }
196 
testSimpleArray()197     public void testSimpleArray() throws IOException
198     {
199         TokenBuffer buf = new TokenBuffer(null, false); // no ObjectCodec
200 
201         // First, empty array
202         assertTrue(buf.getOutputContext().inRoot());
203         buf.writeStartArray();
204         assertTrue(buf.getOutputContext().inArray());
205         buf.writeEndArray();
206         assertTrue(buf.getOutputContext().inRoot());
207 
208         JsonParser p = buf.asParser();
209         assertNull(p.currentToken());
210         assertTrue(p.getParsingContext().inRoot());
211         assertToken(JsonToken.START_ARRAY, p.nextToken());
212         assertTrue(p.getParsingContext().inArray());
213         assertToken(JsonToken.END_ARRAY, p.nextToken());
214         assertTrue(p.getParsingContext().inRoot());
215         assertNull(p.nextToken());
216         p.close();
217         buf.close();
218 
219         // Then one with simple contents
220         buf = new TokenBuffer(null, false);
221         buf.writeStartArray();
222         buf.writeBoolean(true);
223         buf.writeNull();
224         buf.writeEndArray();
225         p = buf.asParser();
226         assertToken(JsonToken.START_ARRAY, p.nextToken());
227         assertToken(JsonToken.VALUE_TRUE, p.nextToken());
228         assertTrue(p.getBooleanValue());
229         assertToken(JsonToken.VALUE_NULL, p.nextToken());
230         assertToken(JsonToken.END_ARRAY, p.nextToken());
231         assertNull(p.nextToken());
232         p.close();
233         buf.close();
234 
235         // And finally, with array-in-array
236         buf = new TokenBuffer(null, false);
237         buf.writeStartArray();
238         buf.writeStartArray();
239         buf.writeBinary(new byte[3]);
240         buf.writeEndArray();
241         buf.writeEndArray();
242         p = buf.asParser();
243         assertToken(JsonToken.START_ARRAY, p.nextToken());
244         assertToken(JsonToken.START_ARRAY, p.nextToken());
245         // TokenBuffer exposes it as embedded object...
246         assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
247         Object ob = p.getEmbeddedObject();
248         assertNotNull(ob);
249         assertTrue(ob instanceof byte[]);
250         assertEquals(3, ((byte[]) ob).length);
251         assertToken(JsonToken.END_ARRAY, p.nextToken());
252         assertToken(JsonToken.END_ARRAY, p.nextToken());
253         assertNull(p.nextToken());
254         p.close();
255         buf.close();
256     }
257 
testSimpleObject()258     public void testSimpleObject() throws IOException
259     {
260         TokenBuffer buf = new TokenBuffer(null, false);
261 
262         // First, empty JSON Object
263         assertTrue(buf.getOutputContext().inRoot());
264         buf.writeStartObject();
265         assertTrue(buf.getOutputContext().inObject());
266         buf.writeEndObject();
267         assertTrue(buf.getOutputContext().inRoot());
268 
269         JsonParser p = buf.asParser();
270         assertNull(p.currentToken());
271         assertTrue(p.getParsingContext().inRoot());
272         assertToken(JsonToken.START_OBJECT, p.nextToken());
273         assertTrue(p.getParsingContext().inObject());
274         assertToken(JsonToken.END_OBJECT, p.nextToken());
275         assertTrue(p.getParsingContext().inRoot());
276         assertNull(p.nextToken());
277         p.close();
278         buf.close();
279 
280         // Then one with simple contents
281         buf = new TokenBuffer(null, false);
282         buf.writeStartObject();
283         buf.writeNumberField("num", 1.25);
284         buf.writeEndObject();
285 
286         p = buf.asParser();
287         assertNull(p.currentToken());
288         assertToken(JsonToken.START_OBJECT, p.nextToken());
289         assertNull(p.currentName());
290         assertToken(JsonToken.FIELD_NAME, p.nextToken());
291         assertEquals("num", p.currentName());
292         // and override should also work:
293         p.overrideCurrentName("bah");
294         assertEquals("bah", p.currentName());
295 
296         assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
297         assertEquals(1.25, p.getDoubleValue());
298         // should still have access to (overridden) name
299         assertEquals("bah", p.currentName());
300         assertToken(JsonToken.END_OBJECT, p.nextToken());
301         // but not any more
302         assertNull(p.currentName());
303         assertNull(p.nextToken());
304         p.close();
305         buf.close();
306     }
307 
308     /**
309      * Verify handling of that "standard" test document (from JSON
310      * specification)
311      */
testWithJSONSampleDoc()312     public void testWithJSONSampleDoc() throws Exception
313     {
314         // First, copy events from known good source (StringReader)
315         JsonParser p = createParserUsingReader(SAMPLE_DOC_JSON_SPEC);
316         TokenBuffer tb = new TokenBuffer(null, false);
317         while (p.nextToken() != null) {
318             tb.copyCurrentEvent(p);
319         }
320 
321         // And then request verification; first structure only:
322         verifyJsonSpecSampleDoc(tb.asParser(), false);
323 
324         // then content check too:
325         verifyJsonSpecSampleDoc(tb.asParser(), true);
326         tb.close();
327         p.close();
328 
329 
330         // 19-Oct-2016, tatu: Just for fun, trigger `toString()` for code coverage
331         String desc = tb.toString();
332         assertNotNull(desc);
333     }
334 
testAppend()335     public void testAppend() throws IOException
336     {
337         TokenBuffer buf1 = new TokenBuffer(null, false);
338         buf1.writeStartObject();
339         buf1.writeFieldName("a");
340         buf1.writeBoolean(true);
341 
342         TokenBuffer buf2 = new TokenBuffer(null, false);
343         buf2.writeFieldName("b");
344         buf2.writeNumber(13);
345         buf2.writeEndObject();
346 
347         buf1.append(buf2);
348 
349         // and verify that we got it all...
350         JsonParser p = buf1.asParser();
351         assertToken(JsonToken.START_OBJECT, p.nextToken());
352         assertToken(JsonToken.FIELD_NAME, p.nextToken());
353         assertEquals("a", p.currentName());
354         assertToken(JsonToken.VALUE_TRUE, p.nextToken());
355         assertToken(JsonToken.FIELD_NAME, p.nextToken());
356         assertEquals("b", p.currentName());
357         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
358         assertEquals(13, p.getIntValue());
359         assertToken(JsonToken.END_OBJECT, p.nextToken());
360         p.close();
361         buf1.close();
362         buf2.close();
363     }
364 
365     // Since 2.3 had big changes to UUID handling, let's verify we can
366     // deal with
testWithUUID()367     public void testWithUUID() throws IOException
368     {
369         for (String value : new String[] {
370                 "00000007-0000-0000-0000-000000000000",
371                 "76e6d183-5f68-4afa-b94a-922c1fdb83f8",
372                 "540a88d1-e2d8-4fb1-9396-9212280d0a7f",
373                 "2c9e441d-1cd0-472d-9bab-69838f877574",
374                 "591b2869-146e-41d7-8048-e8131f1fdec5",
375                 "82994ac2-7b23-49f2-8cc5-e24cf6ed77be",
376         }) {
377             TokenBuffer buf = new TokenBuffer(MAPPER, false); // no ObjectCodec
378             UUID uuid = UUID.fromString(value);
379             MAPPER.writeValue(buf, uuid);
380             buf.close();
381 
382             // and bring it back
383             UUID out = MAPPER.readValue(buf.asParser(), UUID.class);
384             assertEquals(uuid.toString(), out.toString());
385 
386             // second part: As per [databind#362], should NOT use binary with TokenBuffer
387             JsonParser p = buf.asParser();
388             assertEquals(JsonToken.VALUE_STRING, p.nextToken());
389             String str = p.getText();
390             assertEquals(value, str);
391             p.close();
392         }
393     }
394 
395     /*
396     /**********************************************************
397     /* Tests for read/output contexts
398     /**********************************************************
399      */
400 
401     // for [databind#984]: ensure output context handling identical
testOutputContext()402     public void testOutputContext() throws IOException
403     {
404         TokenBuffer buf = new TokenBuffer(null, false); // no ObjectCodec
405         StringWriter w = new StringWriter();
406         JsonGenerator gen = MAPPER.createGenerator(w);
407 
408         // test content: [{"a":1,"b":{"c":2}},{"a":2,"b":{"c":3}}]
409 
410         buf.writeStartArray();
411         gen.writeStartArray();
412         _verifyOutputContext(buf, gen);
413 
414         buf.writeStartObject();
415         gen.writeStartObject();
416         _verifyOutputContext(buf, gen);
417 
418         buf.writeFieldName("a");
419         gen.writeFieldName("a");
420         _verifyOutputContext(buf, gen);
421 
422         buf.writeNumber(1);
423         gen.writeNumber(1);
424         _verifyOutputContext(buf, gen);
425 
426         buf.writeFieldName("b");
427         gen.writeFieldName("b");
428         _verifyOutputContext(buf, gen);
429 
430         buf.writeStartObject();
431         gen.writeStartObject();
432         _verifyOutputContext(buf, gen);
433 
434         buf.writeFieldName("c");
435         gen.writeFieldName("c");
436         _verifyOutputContext(buf, gen);
437 
438         buf.writeNumber(2);
439         gen.writeNumber(2);
440         _verifyOutputContext(buf, gen);
441 
442         buf.writeEndObject();
443         gen.writeEndObject();
444         _verifyOutputContext(buf, gen);
445 
446         buf.writeEndObject();
447         gen.writeEndObject();
448         _verifyOutputContext(buf, gen);
449 
450         buf.writeEndArray();
451         gen.writeEndArray();
452         _verifyOutputContext(buf, gen);
453 
454         buf.close();
455         gen.close();
456     }
457 
_verifyOutputContext(JsonGenerator gen1, JsonGenerator gen2)458     private void _verifyOutputContext(JsonGenerator gen1, JsonGenerator gen2)
459     {
460         _verifyOutputContext(gen1.getOutputContext(), gen2.getOutputContext());
461     }
462 
_verifyOutputContext(JsonStreamContext ctxt1, JsonStreamContext ctxt2)463     private void _verifyOutputContext(JsonStreamContext ctxt1, JsonStreamContext ctxt2)
464     {
465         if (ctxt1 == null) {
466             if (ctxt2 == null) {
467                 return;
468             }
469             fail("Context 1 null, context 2 not null: "+ctxt2);
470         } else if (ctxt2 == null) {
471             fail("Context 2 null, context 1 not null: "+ctxt1);
472         }
473         if (!ctxt1.toString().equals(ctxt2.toString())) {
474             fail("Different output context: token-buffer's = "+ctxt1+", json-generator's: "+ctxt2);
475         }
476 
477         if (ctxt1.inObject()) {
478             assertTrue(ctxt2.inObject());
479             String str1 = ctxt1.getCurrentName();
480             String str2 = ctxt2.getCurrentName();
481 
482             if ((str1 != str2) && !str1.equals(str2)) {
483                 fail("Expected name '"+str2+"' (JsonParser), TokenBuffer had '"+str1+"'");
484             }
485         } else if (ctxt1.inArray()) {
486             assertTrue(ctxt2.inArray());
487             assertEquals(ctxt1.getCurrentIndex(), ctxt2.getCurrentIndex());
488         }
489         _verifyOutputContext(ctxt1.getParent(), ctxt2.getParent());
490     }
491 
492     // [databind#1253]
testParentSiblingContext()493     public void testParentSiblingContext() throws IOException
494     {
495         TokenBuffer buf = new TokenBuffer(null, false); // no ObjectCodec
496 
497         // {"a":{},"b":{"c":"cval"}}
498 
499         buf.writeStartObject();
500         buf.writeFieldName("a");
501         buf.writeStartObject();
502         buf.writeEndObject();
503 
504         buf.writeFieldName("b");
505         buf.writeStartObject();
506         buf.writeFieldName("c");
507         //This assertion fails (because of 'a')
508         assertEquals("b", buf.getOutputContext().getParent().getCurrentName());
509         buf.writeString("cval");
510         buf.writeEndObject();
511         buf.writeEndObject();
512         buf.close();
513     }
514 
testBasicSerialize()515     public void testBasicSerialize() throws IOException
516     {
517         TokenBuffer buf;
518 
519         // let's see how empty works...
520         buf = new TokenBuffer(MAPPER, false);
521         assertEquals("", MAPPER.writeValueAsString(buf));
522         buf.close();
523 
524         buf = new TokenBuffer(MAPPER, false);
525         buf.writeStartArray();
526         buf.writeBoolean(true);
527         buf.writeBoolean(false);
528         long l = 1L + Integer.MAX_VALUE;
529         buf.writeNumber(l);
530         buf.writeNumber((short) 4);
531         buf.writeNumber(0.5);
532         buf.writeEndArray();
533         assertEquals(aposToQuotes("[true,false,"+l+",4,0.5]"), MAPPER.writeValueAsString(buf));
534         buf.close();
535 
536         buf = new TokenBuffer(MAPPER, false);
537         buf.writeStartObject();
538         buf.writeFieldName(new SerializedString("foo"));
539         buf.writeNull();
540         buf.writeFieldName("bar");
541         buf.writeNumber(BigInteger.valueOf(123));
542         buf.writeFieldName("dec");
543         buf.writeNumber(BigDecimal.valueOf(5).movePointLeft(2));
544         assertEquals(aposToQuotes("{'foo':null,'bar':123,'dec':0.05}"), MAPPER.writeValueAsString(buf));
545         buf.close();
546     }
547 
548     /*
549     /**********************************************************
550     /* Tests to verify interaction of TokenBuffer and JsonParserSequence
551     /**********************************************************
552      */
553 
testWithJsonParserSequenceSimple()554     public void testWithJsonParserSequenceSimple() throws IOException
555     {
556         // Let's join a TokenBuffer with JsonParser first
557         TokenBuffer buf = new TokenBuffer(null, false);
558         buf.writeStartArray();
559         buf.writeString("test");
560         JsonParser p = createParserUsingReader("[ true, null ]");
561 
562         JsonParserSequence seq = JsonParserSequence.createFlattened(false, buf.asParser(), p);
563         assertEquals(2, seq.containedParsersCount());
564 
565         assertFalse(p.isClosed());
566 
567         assertFalse(seq.hasCurrentToken());
568         assertNull(seq.currentToken());
569         assertNull(seq.currentName());
570 
571         assertToken(JsonToken.START_ARRAY, seq.nextToken());
572         assertToken(JsonToken.VALUE_STRING, seq.nextToken());
573         assertEquals("test", seq.getText());
574         // end of first parser input, should switch over:
575 
576         assertToken(JsonToken.START_ARRAY, seq.nextToken());
577         assertToken(JsonToken.VALUE_TRUE, seq.nextToken());
578         assertToken(JsonToken.VALUE_NULL, seq.nextToken());
579         assertToken(JsonToken.END_ARRAY, seq.nextToken());
580 
581         /* 17-Jan-2009, tatus: At this point, we may or may not get an
582          *   exception, depending on how underlying parsers work.
583          *   Ideally this should be fixed, probably by asking underlying
584          *   parsers to disable checking for balanced start/end markers.
585          */
586 
587         // for this particular case, we won't get an exception tho...
588         assertNull(seq.nextToken());
589         // not an error to call again...
590         assertNull(seq.nextToken());
591 
592         // also: original parsers should be closed
593         assertTrue(p.isClosed());
594         p.close();
595         buf.close();
596         seq.close();
597     }
598 
599     /**
600      * Test to verify that TokenBuffer and JsonParserSequence work together
601      * as expected.
602      */
603     @SuppressWarnings("resource")
testWithMultipleJsonParserSequences()604     public void testWithMultipleJsonParserSequences() throws IOException
605     {
606         TokenBuffer buf1 = new TokenBuffer(null, false);
607         buf1.writeStartArray();
608         TokenBuffer buf2 = new TokenBuffer(null, false);
609         buf2.writeString("a");
610         TokenBuffer buf3 = new TokenBuffer(null, false);
611         buf3.writeNumber(13);
612         TokenBuffer buf4 = new TokenBuffer(null, false);
613         buf4.writeEndArray();
614 
615         JsonParserSequence seq1 = JsonParserSequence.createFlattened(false, buf1.asParser(), buf2.asParser());
616         assertEquals(2, seq1.containedParsersCount());
617         JsonParserSequence seq2 = JsonParserSequence.createFlattened(false, buf3.asParser(), buf4.asParser());
618         assertEquals(2, seq2.containedParsersCount());
619         JsonParserSequence combo = JsonParserSequence.createFlattened(false, seq1, seq2);
620         // should flatten it to have 4 underlying parsers
621         assertEquals(4, combo.containedParsersCount());
622 
623         assertToken(JsonToken.START_ARRAY, combo.nextToken());
624         assertToken(JsonToken.VALUE_STRING, combo.nextToken());
625         assertEquals("a", combo.getText());
626         assertToken(JsonToken.VALUE_NUMBER_INT, combo.nextToken());
627         assertEquals(13, combo.getIntValue());
628         assertToken(JsonToken.END_ARRAY, combo.nextToken());
629         assertNull(combo.nextToken());
630         buf1.close();
631         buf2.close();
632         buf3.close();
633         buf4.close();
634     }
635 
636     // [databind#743]
testRawValues()637     public void testRawValues() throws Exception
638     {
639         final String RAW = "{\"a\":1}";
640         TokenBuffer buf = new TokenBuffer(null, false);
641         buf.writeRawValue(RAW);
642         // first: raw value won't be transformed in any way:
643         JsonParser p = buf.asParser();
644         assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
645         assertEquals(RawValue.class, p.getEmbeddedObject().getClass());
646         assertNull(p.nextToken());
647         p.close();
648         buf.close();
649 
650         // then verify it would be serialized just fine
651         assertEquals(RAW, MAPPER.writeValueAsString(buf));
652     }
653 
654     // [databind#1730]
testEmbeddedObjectCoerceCheck()655     public void testEmbeddedObjectCoerceCheck() throws Exception
656     {
657         TokenBuffer buf = new TokenBuffer(null, false);
658         Object inputPojo = new Sub1730();
659         buf.writeEmbeddedObject(inputPojo);
660 
661         // first: raw value won't be transformed in any way:
662         JsonParser p = buf.asParser();
663         Base1730 out = MAPPER.readValue(p, Base1730.class);
664 
665         assertSame(inputPojo, out);
666         p.close();
667         buf.close();
668     }
669 }
670