xref: /aosp_15_r20/external/jackson-core/src/test/java/com/fasterxml/jackson/core/read/SimpleParserTest.java (revision 944f89f84d71c7cfddf0d16e984cab583aa14be3)
1 package com.fasterxml.jackson.core.read;
2 
3 import com.fasterxml.jackson.core.*;
4 import com.fasterxml.jackson.core.testsupport.MockDataInput;
5 import com.fasterxml.jackson.core.util.JsonParserDelegate;
6 
7 import java.io.*;
8 import java.net.URL;
9 import java.util.*;
10 
11 /**
12  * Set of basic unit tests for verifying that the basic parser
13  * functionality works as expected.
14  */
15 @SuppressWarnings("resource")
16 public class SimpleParserTest extends BaseTest
17 {
testConfig()18     public void testConfig() throws Exception
19     {
20         JsonParser p = createParser(MODE_READER, "[ ]");
21         Object src = p.getInputSource();
22         assertNotNull(src);
23         assertTrue(src instanceof Reader);
24         p.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
25         assertTrue(p.isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE));
26         p.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
27         assertFalse(p.isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE));
28 
29         p.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true);
30         assertTrue(p.isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE));
31         p.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
32         assertFalse(p.isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE));
33         p.close();
34 
35         p = createParser(MODE_INPUT_STREAM, "[ ]");
36         src = p.getInputSource();
37         assertNotNull(src);
38         assertTrue(src instanceof InputStream);
39         p.close();
40 
41         p = createParser(MODE_DATA_INPUT, "[ ]");
42         src = p.getInputSource();
43         assertNotNull(src);
44         assertTrue(src instanceof DataInput);
45         p.close();
46     }
47 
testInterningWithStreams()48     public void testInterningWithStreams() throws Exception
49     {
50         _testIntern(true, true, "a");
51         _testIntern(true, false, "b");
52     }
53 
testInterningWithReaders()54     public void testInterningWithReaders() throws Exception
55     {
56         _testIntern(false, true, "c");
57         _testIntern(false, false, "d");
58     }
59 
_testIntern(boolean useStream, boolean enableIntern, String expName)60     private void _testIntern(boolean useStream, boolean enableIntern, String expName) throws IOException
61     {
62         JsonFactory f = JsonFactory.builder()
63                 .configure(JsonFactory.Feature.INTERN_FIELD_NAMES, enableIntern)
64                 .build();
65         assertEquals(enableIntern, f.isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES));
66         final String JSON = "{ \""+expName+"\" : 1}";
67         JsonParser p = useStream ?
68             createParserUsingStream(f, JSON, "UTF-8") : createParserUsingReader(f, JSON);
69 
70         assertToken(JsonToken.START_OBJECT, p.nextToken());
71         assertToken(JsonToken.FIELD_NAME, p.nextToken());
72         // needs to be same of cours
73         String actName = p.getCurrentName();
74         assertEquals(expName, actName);
75         if (enableIntern) {
76             assertSame(expName, actName);
77         } else {
78             assertNotSame(expName, actName);
79         }
80         p.close();
81     }
82 
83     /**
84      * This basic unit test verifies that example given in the JSON
85      * specification (RFC-4627 or later) is properly parsed at
86      * high-level, without verifying values.
87      */
testSpecExampleSkipping()88     public void testSpecExampleSkipping() throws Exception
89     {
90         _doTestSpec(false);
91     }
92 
93     /**
94      * Unit test that verifies that the spec example JSON is completely
95      * parsed, and proper values are given for contents of all
96      * events/tokens.
97      */
testSpecExampleFully()98     public void testSpecExampleFully() throws Exception
99     {
100         _doTestSpec(true);
101     }
102 
103     /**
104      * Unit test that verifies that 3 basic keywords (null, true, false)
105      * are properly parsed in various contexts.
106      */
testKeywords()107     public void testKeywords() throws Exception
108     {
109         final String DOC = "{\n"
110             +"\"key1\" : null,\n"
111             +"\"key2\" : true,\n"
112             +"\"key3\" : false,\n"
113             +"\"key4\" : [ false, null, true ]\n"
114             +"}"
115             ;
116 
117         JsonParser p = createParserUsingStream(JSON_FACTORY, DOC, "UTF-8");
118         _testKeywords(p, true);
119         p.close();
120 
121         p = createParserUsingReader(JSON_FACTORY, DOC);
122         _testKeywords(p, true);
123         p.close();
124 
125         p = createParserForDataInput(JSON_FACTORY, new MockDataInput(DOC));
126         _testKeywords(p, false);
127         p.close();
128     }
129 
_testKeywords(JsonParser p, boolean checkColumn)130     private void _testKeywords(JsonParser p, boolean checkColumn) throws Exception
131     {
132         JsonStreamContext ctxt = p.getParsingContext();
133         assertEquals("/", ctxt.toString());
134         assertTrue(ctxt.inRoot());
135         assertFalse(ctxt.inArray());
136         assertFalse(ctxt.inObject());
137         assertEquals(0, ctxt.getEntryCount());
138         assertEquals(0, ctxt.getCurrentIndex());
139 
140         // Before advancing to content, we should have following default state...
141         assertFalse(p.hasCurrentToken());
142         assertNull(p.getText());
143         assertNull(p.getTextCharacters());
144         assertEquals(0, p.getTextLength());
145         // not sure if this is defined but:
146         assertEquals(0, p.getTextOffset());
147 
148         assertToken(JsonToken.START_OBJECT, p.nextToken());
149         assertEquals("/", ctxt.toString());
150 
151         assertTrue(p.hasCurrentToken());
152         JsonLocation loc = p.getTokenLocation();
153         assertNotNull(loc);
154         assertEquals(1, loc.getLineNr());
155         if (checkColumn) {
156             assertEquals(1, loc.getColumnNr());
157         }
158 
159         ctxt = p.getParsingContext();
160         assertFalse(ctxt.inRoot());
161         assertFalse(ctxt.inArray());
162         assertTrue(ctxt.inObject());
163         assertEquals(0, ctxt.getEntryCount());
164         assertEquals(0, ctxt.getCurrentIndex());
165 
166         assertToken(JsonToken.FIELD_NAME, p.nextToken());
167         verifyFieldName(p, "key1");
168         assertEquals("{\"key1\"}", ctxt.toString());
169         assertEquals(2, p.getTokenLocation().getLineNr());
170 
171         ctxt = p.getParsingContext();
172         assertFalse(ctxt.inRoot());
173         assertFalse(ctxt.inArray());
174         assertTrue(ctxt.inObject());
175         assertEquals(1, ctxt.getEntryCount());
176         assertEquals(0, ctxt.getCurrentIndex());
177         assertEquals("key1", ctxt.getCurrentName());
178 
179         assertToken(JsonToken.VALUE_NULL, p.nextToken());
180         assertEquals("key1", ctxt.getCurrentName());
181 
182         ctxt = p.getParsingContext();
183         assertEquals(1, ctxt.getEntryCount());
184         assertEquals(0, ctxt.getCurrentIndex());
185 
186         assertToken(JsonToken.FIELD_NAME, p.nextToken());
187         verifyFieldName(p, "key2");
188         ctxt = p.getParsingContext();
189         assertEquals(2, ctxt.getEntryCount());
190         assertEquals(1, ctxt.getCurrentIndex());
191         assertEquals("key2", ctxt.getCurrentName());
192 
193         assertToken(JsonToken.VALUE_TRUE, p.nextToken());
194         assertEquals("key2", ctxt.getCurrentName());
195 
196         assertToken(JsonToken.FIELD_NAME, p.nextToken());
197         verifyFieldName(p, "key3");
198         assertToken(JsonToken.VALUE_FALSE, p.nextToken());
199 
200         assertToken(JsonToken.FIELD_NAME, p.nextToken());
201         verifyFieldName(p, "key4");
202 
203         assertToken(JsonToken.START_ARRAY, p.nextToken());
204         ctxt = p.getParsingContext();
205         assertTrue(ctxt.inArray());
206         assertNull(ctxt.getCurrentName());
207         assertEquals("key4", ctxt.getParent().getCurrentName());
208 
209         assertToken(JsonToken.VALUE_FALSE, p.nextToken());
210         assertEquals("[0]", ctxt.toString());
211 
212         assertToken(JsonToken.VALUE_NULL, p.nextToken());
213         assertToken(JsonToken.VALUE_TRUE, p.nextToken());
214         assertToken(JsonToken.END_ARRAY, p.nextToken());
215 
216         ctxt = p.getParsingContext();
217         assertTrue(ctxt.inObject());
218 
219         assertToken(JsonToken.END_OBJECT, p.nextToken());
220         ctxt = p.getParsingContext();
221         assertTrue(ctxt.inRoot());
222         assertNull(ctxt.getCurrentName());
223     }
224 
testSkipping()225     public void testSkipping() throws Exception {
226         _testSkipping(MODE_INPUT_STREAM);
227         _testSkipping(MODE_INPUT_STREAM_THROTTLED);
228         _testSkipping(MODE_READER);
229         _testSkipping(MODE_DATA_INPUT);
230     }
231 
_testSkipping(int mode)232     private void _testSkipping(int mode) throws Exception
233     {
234         // InputData has some limitations to take into consideration
235         boolean isInputData = (mode == MODE_DATA_INPUT);
236         String DOC = aposToQuotes(
237             "[ 1, 3, [ true, null ], 3, { 'a\\\\b':'quoted: \\'stuff\\'' }, [ [ ] ], { } ]"
238         );
239         JsonParser p = createParser(mode, DOC);
240 
241         // First, skipping of the whole thing
242         assertToken(JsonToken.START_ARRAY, p.nextToken());
243         p.skipChildren();
244         assertEquals(JsonToken.END_ARRAY, p.currentToken());
245         if (!isInputData) {
246             JsonToken t = p.nextToken();
247             if (t != null) {
248                 fail("Expected null at end of doc, got "+t);
249             }
250         }
251         p.close();
252 
253         // Then individual ones
254         p = createParser(mode, DOC);
255         assertToken(JsonToken.START_ARRAY, p.nextToken());
256 
257         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
258         p.skipChildren();
259         // shouldn't move
260         assertToken(JsonToken.VALUE_NUMBER_INT, p.currentToken());
261         assertEquals(1, p.getIntValue());
262 
263         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
264         // then skip array
265         assertToken(JsonToken.START_ARRAY, p.nextToken());
266         p.skipChildren();
267         assertToken(JsonToken.END_ARRAY, p.currentToken());
268 
269         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
270         assertToken(JsonToken.START_OBJECT, p.nextToken());
271         p.skipChildren();
272         assertToken(JsonToken.END_OBJECT, p.currentToken());
273 
274         assertToken(JsonToken.START_ARRAY, p.nextToken());
275         p.skipChildren();
276         assertToken(JsonToken.END_ARRAY, p.currentToken());
277 
278         assertToken(JsonToken.START_OBJECT, p.nextToken());
279         p.skipChildren();
280         assertToken(JsonToken.END_OBJECT, p.currentToken());
281 
282         assertToken(JsonToken.END_ARRAY, p.nextToken());
283 
284         p.close();
285     }
286 
testNameEscaping()287     public void testNameEscaping() throws IOException
288     {
289         _testNameEscaping(MODE_INPUT_STREAM);
290         _testNameEscaping(MODE_READER);
291         _testNameEscaping(MODE_DATA_INPUT);
292     }
293 
_testNameEscaping(int mode)294     private void _testNameEscaping(int mode) throws IOException
295     {
296         final Map<String,String> NAME_MAP = new LinkedHashMap<String,String>();
297         NAME_MAP.put("", "");
298         NAME_MAP.put("\\\"funny\\\"", "\"funny\"");
299         NAME_MAP.put("\\\\", "\\");
300         NAME_MAP.put("\\r", "\r");
301         NAME_MAP.put("\\n", "\n");
302         NAME_MAP.put("\\t", "\t");
303         NAME_MAP.put("\\r\\n", "\r\n");
304         NAME_MAP.put("\\\"\\\"", "\"\"");
305         NAME_MAP.put("Line\\nfeed", "Line\nfeed");
306         NAME_MAP.put("Yet even longer \\\"name\\\"!", "Yet even longer \"name\"!");
307 
308         int entry = 0;
309         for (Map.Entry<String,String> en : NAME_MAP.entrySet()) {
310             ++entry;
311             String input = en.getKey();
312             String expResult = en.getValue();
313             final String DOC = "{ \""+input+"\":null}";
314             JsonParser p = createParser(mode, DOC);
315 
316             assertToken(JsonToken.START_OBJECT, p.nextToken());
317             assertToken(JsonToken.FIELD_NAME, p.nextToken());
318             // first, sanity check (field name == getText()
319             String act = p.getCurrentName();
320             assertEquals(act, getAndVerifyText(p));
321             if (!expResult.equals(act)) {
322                 String msg = "Failed for name #"+entry+"/"+NAME_MAP.size();
323                 if (expResult.length() != act.length()) {
324                     fail(msg+": exp length "+expResult.length()+", actual "+act.length());
325                 }
326                 assertEquals(msg, expResult, act);
327             }
328             assertToken(JsonToken.VALUE_NULL, p.nextToken());
329             assertToken(JsonToken.END_OBJECT, p.nextToken());
330             p.close();
331         }
332     }
333 
334     /**
335      * Unit test that verifies that long text segments are handled
336      * correctly; mostly to stress-test underlying segment-based
337      * text buffer(s).
338      */
testLongText()339     public void testLongText() throws Exception {
340         // lengths chosen to tease out problems with buffer allocation...
341         _testLongText(310);
342         _testLongText(7700);
343         _testLongText(49000);
344         _testLongText(96000);
345     }
346 
_testLongText(int LEN)347     private void _testLongText(int LEN) throws Exception
348     {
349         StringBuilder sb = new StringBuilder(LEN + 100);
350         Random r = new Random(LEN);
351         while (sb.length() < LEN) {
352             sb.append(r.nextInt());
353             sb.append(" xyz foo");
354             if (r.nextBoolean()) {
355                 sb.append(" and \"bar\"");
356             } else if (r.nextBoolean()) {
357                 sb.append(" [whatever].... ");
358             } else {
359                 // Let's try some more 'exotic' chars
360                 sb.append(" UTF-8-fu: try this {\u00E2/\u0BF8/\uA123!} (look funny?)");
361             }
362             if (r.nextBoolean()) {
363                 if (r.nextBoolean()) {
364                     sb.append('\n');
365                 } else if (r.nextBoolean()) {
366                     sb.append('\r');
367                 } else {
368                     sb.append("\r\n");
369                 }
370             }
371         }
372         final String VALUE = sb.toString();
373 
374         // Let's use real generator to get JSON done right
375         StringWriter sw = new StringWriter(LEN + (LEN >> 2));
376         JsonGenerator g = JSON_FACTORY.createGenerator(sw);
377         g.writeStartObject();
378         g.writeFieldName("doc");
379         g.writeString(VALUE);
380         g.writeEndObject();
381         g.close();
382 
383         final String DOC = sw.toString();
384 
385         for (int type = 0; type < 4; ++type) {
386             JsonParser p;
387             switch (type) {
388             case MODE_INPUT_STREAM:
389             case MODE_READER:
390             case MODE_DATA_INPUT:
391                 p = createParser(type, DOC);
392                 break;
393             default:
394                 p = JSON_FACTORY.createParser(encodeInUTF32BE(DOC));
395             }
396             assertToken(JsonToken.START_OBJECT, p.nextToken());
397             assertToken(JsonToken.FIELD_NAME, p.nextToken());
398             assertEquals("doc", p.getCurrentName());
399             assertToken(JsonToken.VALUE_STRING, p.nextToken());
400 
401             String act = getAndVerifyText(p);
402             if (act.length() != VALUE.length()) {
403                 fail("Expected length "+VALUE.length()+", got "+act.length()+" (mode = "+type+")");
404             }
405             if (!act.equals(VALUE)) {
406                 fail("Long text differs");
407             }
408 
409             // should still know the field name
410             assertEquals("doc", p.getCurrentName());
411             assertToken(JsonToken.END_OBJECT, p.nextToken());
412 
413             // InputDate somewhat special, so:
414             if (type != MODE_DATA_INPUT) {
415                 assertNull(p.nextToken());
416             }
417             p.close();
418         }
419     }
420 
421     /**
422      * Simple unit test that verifies that passing in a byte array
423      * as source works as expected.
424      */
testBytesAsSource()425     public void testBytesAsSource() throws Exception
426     {
427         String JSON = "[ 1, 2, 3, 4 ]";
428         byte[] b = JSON.getBytes("UTF-8");
429         int offset = 50;
430         int len = b.length;
431         byte[] src = new byte[offset + len + offset];
432 
433         System.arraycopy(b, 0, src, offset, len);
434 
435         JsonParser p = JSON_FACTORY.createParser(src, offset, len);
436 
437         assertToken(JsonToken.START_ARRAY, p.nextToken());
438         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
439         assertEquals(1, p.getIntValue());
440         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
441         assertEquals(2, p.getIntValue());
442         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
443         assertEquals(3, p.getIntValue());
444         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
445         assertEquals(4, p.getIntValue());
446         assertToken(JsonToken.END_ARRAY, p.nextToken());
447         assertNull(p.nextToken());
448 
449         p.close();
450     }
451 
testUtf8BOMHandling()452     public void testUtf8BOMHandling() throws Exception
453     {
454         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
455         // first, write BOM:
456         bytes.write(0xEF);
457         bytes.write(0xBB);
458         bytes.write(0xBF);
459         bytes.write("[ 1 ]".getBytes("UTF-8"));
460         byte[] input = bytes.toByteArray();
461 
462         JsonParser p = JSON_FACTORY.createParser(input);
463         assertEquals(JsonToken.START_ARRAY, p.nextToken());
464 
465         JsonLocation loc = p.getTokenLocation();
466         assertEquals(3, loc.getByteOffset());
467         assertEquals(-1, loc.getCharOffset());
468         assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
469         assertEquals(JsonToken.END_ARRAY, p.nextToken());
470         p.close();
471 
472         p = JSON_FACTORY.createParser(new MockDataInput(input));
473         assertEquals(JsonToken.START_ARRAY, p.nextToken());
474         // same BOM, but DataInput is more restrictive so can skip but offsets
475         // are not reliable...
476         loc = p.getTokenLocation();
477         assertNotNull(loc);
478         assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
479         assertEquals(JsonToken.END_ARRAY, p.nextToken());
480         p.close();
481     }
482 
483     // [core#48]
testSpacesInURL()484     public void testSpacesInURL() throws Exception
485     {
486         File f = File.createTempFile("pre fix&stuff", ".txt");
487         BufferedWriter w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
488         w.write("{ }");
489         w.close();
490         URL url = f.toURI().toURL();
491 
492         JsonParser p = JSON_FACTORY.createParser(url);
493         assertToken(JsonToken.START_OBJECT, p.nextToken());
494         assertToken(JsonToken.END_OBJECT, p.nextToken());
495         p.close();
496     }
497 
testGetValueAsTextBytes()498     public void testGetValueAsTextBytes() throws Exception
499     {
500         _testGetValueAsText(MODE_INPUT_STREAM, false);
501         _testGetValueAsText(MODE_INPUT_STREAM, true);
502     }
503 
testGetValueAsTextDataInput()504     public void testGetValueAsTextDataInput() throws Exception
505     {
506         _testGetValueAsText(MODE_DATA_INPUT, false);
507         _testGetValueAsText(MODE_DATA_INPUT, true);
508     }
509 
testGetValueAsTextChars()510     public void testGetValueAsTextChars() throws Exception
511     {
512         _testGetValueAsText(MODE_READER, false);
513         _testGetValueAsText(MODE_READER, true);
514     }
515 
_testGetValueAsText(int mode, boolean delegate)516     private void _testGetValueAsText(int mode, boolean delegate) throws Exception
517     {
518         String JSON = "{\"a\":1,\"b\":true,\"c\":null,\"d\":\"foo\"}";
519         JsonParser p = createParser(mode, JSON);
520         if (delegate) {
521             p = new JsonParserDelegate(p);
522         }
523 
524         assertToken(JsonToken.START_OBJECT, p.nextToken());
525         assertNull(p.getValueAsString());
526         assertEquals("foobar", p.getValueAsString("foobar"));
527 
528         assertToken(JsonToken.FIELD_NAME, p.nextToken());
529         assertEquals("a", p.getText());
530         assertEquals("a", p.getValueAsString());
531         assertEquals("a", p.getValueAsString("default"));
532         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
533         assertEquals("1", p.getValueAsString());
534 
535         assertToken(JsonToken.FIELD_NAME, p.nextToken());
536         assertEquals("b", p.getValueAsString());
537         assertToken(JsonToken.VALUE_TRUE, p.nextToken());
538         assertEquals("true", p.getValueAsString());
539         assertEquals("true", p.getValueAsString("foobar"));
540 
541         assertToken(JsonToken.FIELD_NAME, p.nextToken());
542         assertEquals("c", p.getValueAsString());
543         assertToken(JsonToken.VALUE_NULL, p.nextToken());
544         // null token returned as Java null, as per javadoc
545         assertNull(p.getValueAsString());
546 
547         assertToken(JsonToken.FIELD_NAME, p.nextToken());
548         assertEquals("d", p.getValueAsString());
549         assertToken(JsonToken.VALUE_STRING, p.nextToken());
550         assertEquals("foo", p.getValueAsString("default"));
551         assertEquals("foo", p.getValueAsString());
552 
553         assertToken(JsonToken.END_OBJECT, p.nextToken());
554         assertNull(p.getValueAsString());
555 
556         // InputData can't peek into end-of-input so:
557         if (mode != MODE_DATA_INPUT) {
558             assertNull(p.nextToken());
559         }
560         p.close();
561     }
562 
testGetTextViaWriter()563     public void testGetTextViaWriter() throws Exception
564     {
565         for (int mode : ALL_MODES) {
566             _testGetTextViaWriter(mode);
567         }
568     }
569 
_testGetTextViaWriter(int mode)570     private void _testGetTextViaWriter(int mode) throws Exception
571     {
572         final String INPUT_TEXT = "this is a sample text for json parsing using readText() method";
573         final String JSON = "{\"a\":\""+INPUT_TEXT+"\",\"b\":true,\"c\":null,\"d\":\"foobar!\"}";
574         JsonParser parser = createParser(mode, JSON);
575         assertToken(JsonToken.START_OBJECT, parser.nextToken());
576         assertToken(JsonToken.FIELD_NAME, parser.nextToken());
577         assertEquals("a", parser.getCurrentName());
578         _getAndVerifyText(parser, "a");
579         assertToken(JsonToken.VALUE_STRING, parser.nextToken());
580         _getAndVerifyText(parser, INPUT_TEXT);
581         assertToken(JsonToken.FIELD_NAME, parser.nextToken());
582         assertEquals("b", parser.getCurrentName());
583         assertToken(JsonToken.VALUE_TRUE, parser.nextToken());
584         _getAndVerifyText(parser, "true");
585         assertToken(JsonToken.FIELD_NAME, parser.nextToken());
586         assertEquals("c", parser.getCurrentName());
587         assertToken(JsonToken.VALUE_NULL, parser.nextToken());
588         _getAndVerifyText(parser, "null");
589         assertToken(JsonToken.FIELD_NAME, parser.nextToken());
590         assertEquals("d", parser.getCurrentName());
591         assertToken(JsonToken.VALUE_STRING, parser.nextToken());
592         _getAndVerifyText(parser, "foobar!");
593 
594         parser.close();
595     }
596 
_getAndVerifyText(JsonParser p, String exp)597     private void _getAndVerifyText(JsonParser p, String exp) throws Exception
598     {
599         Writer writer = new StringWriter();
600         int len = p.getText(writer);
601         String resultString = writer.toString();
602         assertEquals(len, resultString.length());
603         assertEquals(exp, resultString);
604     }
605 
testLongerReadText()606     public void testLongerReadText() throws Exception
607     {
608         for (int mode : ALL_MODES) {
609             _testLongerReadText(mode);
610         }
611     }
612 
_testLongerReadText(int mode)613     private void _testLongerReadText(int mode) throws Exception
614     {
615         StringBuilder builder = new StringBuilder();
616         for(int i= 0; i < 1000; i++) {
617             builder.append("Sample Text"+i);
618         }
619         String longText = builder.toString();
620         final String JSON = "{\"a\":\""+ longText +"\",\"b\":true,\"c\":null,\"d\":\"foo\"}";
621         JsonParser parser = createParser(MODE_READER, JSON);
622         assertToken(JsonToken.START_OBJECT, parser.nextToken());
623         assertToken(JsonToken.FIELD_NAME, parser.nextToken());
624         assertEquals("a", parser.getCurrentName());
625         assertToken(JsonToken.VALUE_STRING, parser.nextToken());
626 
627         Writer writer = new StringWriter();
628         int len = parser.getText(writer);
629         String resultString = writer.toString();
630         assertEquals(len, resultString.length());
631         assertEquals(longText, resultString);
632         parser.close();
633     }
634 
635     /*
636     /**********************************************************
637     /* Tests for Invalid input
638     /**********************************************************
639      */
640 
641     // [core#142]
testHandlingOfInvalidSpaceByteStream()642     public void testHandlingOfInvalidSpaceByteStream() throws Exception {
643         _testHandlingOfInvalidSpace(MODE_INPUT_STREAM);
644         _testHandlingOfInvalidSpaceFromResource(true);
645     }
646 
647     // [core#142]
testHandlingOfInvalidSpaceChars()648     public void testHandlingOfInvalidSpaceChars() throws Exception {
649         _testHandlingOfInvalidSpace(MODE_READER);
650         _testHandlingOfInvalidSpaceFromResource(false);
651     }
652 
653     // [core#142]
testHandlingOfInvalidSpaceDataInput()654     public void testHandlingOfInvalidSpaceDataInput() throws Exception {
655         _testHandlingOfInvalidSpace(MODE_DATA_INPUT);
656     }
657 
_testHandlingOfInvalidSpace(int mode)658     private void _testHandlingOfInvalidSpace(int mode) throws Exception
659     {
660         final String JSON = "{ \u00A0 \"a\":1}";
661 
662         JsonParser p = createParser(mode, JSON);
663         assertToken(JsonToken.START_OBJECT, p.nextToken());
664         try {
665             p.nextToken();
666             fail("Should have failed");
667         } catch (JsonParseException e) {
668             verifyException(e, "unexpected character");
669             // and correct error code
670             verifyException(e, "code 160");
671         }
672         p.close();
673     }
674 
_testHandlingOfInvalidSpaceFromResource(boolean useStream)675     private void _testHandlingOfInvalidSpaceFromResource(boolean useStream) throws Exception
676     {
677         InputStream in = getClass().getResourceAsStream("/test_0xA0.json");
678         JsonParser p = useStream
679                 ? JSON_FACTORY.createParser(in)
680                 : JSON_FACTORY.createParser(new InputStreamReader(in, "UTF-8"));
681         assertToken(JsonToken.START_OBJECT, p.nextToken());
682         try {
683             assertToken(JsonToken.FIELD_NAME, p.nextToken());
684             assertEquals("request", p.getCurrentName());
685             assertToken(JsonToken.START_OBJECT, p.nextToken());
686             assertToken(JsonToken.FIELD_NAME, p.nextToken());
687             assertEquals("mac", p.getCurrentName());
688             assertToken(JsonToken.VALUE_STRING, p.nextToken());
689             assertNotNull(p.getText());
690             assertToken(JsonToken.FIELD_NAME, p.nextToken());
691             assertEquals("data", p.getCurrentName());
692             assertToken(JsonToken.START_OBJECT, p.nextToken());
693 
694             // ... and from there on, just loop
695 
696             while (p.nextToken()  != null) { }
697             fail("Should have failed");
698         } catch (JsonParseException e) {
699             verifyException(e, "unexpected character");
700             // and correct error code
701             verifyException(e, "code 160");
702         }
703         p.close();
704     }
705 
706     /*
707     /**********************************************************
708     /* Helper methods
709     /**********************************************************
710      */
711 
_doTestSpec(boolean verify)712     private void _doTestSpec(boolean verify) throws IOException
713     {
714         JsonParser p;
715 
716         // First, using a StringReader:
717         p = createParserUsingReader(JSON_FACTORY, SAMPLE_DOC_JSON_SPEC);
718         verifyJsonSpecSampleDoc(p, verify);
719         p.close();
720 
721         // Then with streams using supported encodings:
722         p = createParserUsingStream(JSON_FACTORY, SAMPLE_DOC_JSON_SPEC, "UTF-8");
723         verifyJsonSpecSampleDoc(p, verify);
724         p.close();
725         p = createParserUsingStream(JSON_FACTORY, SAMPLE_DOC_JSON_SPEC, "UTF-16BE");
726         verifyJsonSpecSampleDoc(p, verify);
727         p.close();
728         p = createParserUsingStream(JSON_FACTORY, SAMPLE_DOC_JSON_SPEC, "UTF-16LE");
729         verifyJsonSpecSampleDoc(p, verify);
730         p.close();
731 
732         // Hmmh. UTF-32 is harder only because JDK doesn't come with
733         // a codec for it. Can't test it yet using this method
734         p = createParserUsingStream(JSON_FACTORY, SAMPLE_DOC_JSON_SPEC, "UTF-32");
735         verifyJsonSpecSampleDoc(p, verify);
736         p.close();
737 
738         // and finally, new (as of May 2016) source, DataInput:
739         p = createParserForDataInput(JSON_FACTORY, new MockDataInput(SAMPLE_DOC_JSON_SPEC));
740         verifyJsonSpecSampleDoc(p, verify);
741         p.close();
742     }
743 }
744