1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
19import java.io.IOException;
20import java.io.StringReader;
21import java.util.Arrays;
22import junit.framework.TestCase;
23
24public final class JsonReaderTest extends TestCase {
25
26    private static final int READER_BUFFER_SIZE = 1024;
27
28    public void testReadArray() throws IOException {
29        JsonReader reader = new JsonReader(new StringReader("[true, true]"));
30        reader.beginArray();
31        assertEquals(true, reader.nextBoolean());
32        assertEquals(true, reader.nextBoolean());
33        reader.endArray();
34        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
35    }
36
37    public void testReadEmptyArray() throws IOException {
38        JsonReader reader = new JsonReader(new StringReader("[]"));
39        reader.beginArray();
40        assertFalse(reader.hasNext());
41        reader.endArray();
42        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
43    }
44
45    public void testReadObject() throws IOException {
46        JsonReader reader = new JsonReader(new StringReader(
47                "{\"a\": \"android\", \"b\": \"banana\"}"));
48        reader.beginObject();
49        assertEquals("a", reader.nextName());
50        assertEquals("android", reader.nextString());
51        assertEquals("b", reader.nextName());
52        assertEquals("banana", reader.nextString());
53        reader.endObject();
54        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
55    }
56
57    public void testReadEmptyObject() throws IOException {
58        JsonReader reader = new JsonReader(new StringReader("{}"));
59        reader.beginObject();
60        assertFalse(reader.hasNext());
61        reader.endObject();
62        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
63    }
64
65    public void testSkipObject() throws IOException {
66        JsonReader reader = new JsonReader(new StringReader(
67                "{\"a\": { \"c\": [], \"d\": [true, true, {}] }, \"b\": \"banana\"}"));
68        reader.beginObject();
69        assertEquals("a", reader.nextName());
70        reader.skipValue();
71        assertEquals("b", reader.nextName());
72        reader.skipValue();
73        reader.endObject();
74        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
75    }
76
77    public void testHelloWorld() throws IOException {
78        String json = "{\n" +
79                "   \"hello\": true,\n" +
80                "   \"foo\": [\"world\"]\n" +
81                "}";
82        JsonReader reader = new JsonReader(new StringReader(json));
83        reader.beginObject();
84        assertEquals("hello", reader.nextName());
85        assertEquals(true, reader.nextBoolean());
86        assertEquals("foo", reader.nextName());
87        reader.beginArray();
88        assertEquals("world", reader.nextString());
89        reader.endArray();
90        reader.endObject();
91        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
92    }
93
94    public void testNulls() {
95        try {
96            new JsonReader(null);
97            fail();
98        } catch (NullPointerException expected) {
99        }
100    }
101
102    public void testEmptyString() throws IOException {
103        try {
104            new JsonReader(new StringReader("")).beginArray();
105        } catch (IOException expected) {
106        }
107        try {
108            new JsonReader(new StringReader("")).beginObject();
109        } catch (IOException expected) {
110        }
111    }
112
113    public void testNoTopLevelObject() throws IOException {
114        try {
115            new JsonReader(new StringReader("true")).nextBoolean();
116        } catch (IOException expected) {
117        }
118    }
119
120    public void testCharacterUnescaping() throws IOException {
121        String json = "[\"a\","
122                + "\"a\\\"\","
123                + "\"\\\"\","
124                + "\":\","
125                + "\",\","
126                + "\"\\b\","
127                + "\"\\f\","
128                + "\"\\n\","
129                + "\"\\r\","
130                + "\"\\t\","
131                + "\" \","
132                + "\"\\\\\","
133                + "\"{\","
134                + "\"}\","
135                + "\"[\","
136                + "\"]\","
137                + "\"\\u0000\","
138                + "\"\\u0019\","
139                + "\"\\u20AC\""
140                + "]";
141        JsonReader reader = new JsonReader(new StringReader(json));
142        reader.beginArray();
143        assertEquals("a", reader.nextString());
144        assertEquals("a\"", reader.nextString());
145        assertEquals("\"", reader.nextString());
146        assertEquals(":", reader.nextString());
147        assertEquals(",", reader.nextString());
148        assertEquals("\b", reader.nextString());
149        assertEquals("\f", reader.nextString());
150        assertEquals("\n", reader.nextString());
151        assertEquals("\r", reader.nextString());
152        assertEquals("\t", reader.nextString());
153        assertEquals(" ", reader.nextString());
154        assertEquals("\\", reader.nextString());
155        assertEquals("{", reader.nextString());
156        assertEquals("}", reader.nextString());
157        assertEquals("[", reader.nextString());
158        assertEquals("]", reader.nextString());
159        assertEquals("\0", reader.nextString());
160        assertEquals("\u0019", reader.nextString());
161        assertEquals("\u20AC", reader.nextString());
162        reader.endArray();
163        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
164    }
165
166    public void testIntegersWithFractionalPartSpecified() throws IOException {
167        JsonReader reader = new JsonReader(new StringReader("[1.0,1.0,1.0]"));
168        reader.beginArray();
169        assertEquals(1.0, reader.nextDouble());
170        assertEquals(1, reader.nextInt());
171        assertEquals(1L, reader.nextLong());
172    }
173
174    public void testDoubles() throws IOException {
175        String json = "[-0.0,"
176                + "1.0,"
177                + "1.7976931348623157E308,"
178                + "4.9E-324,"
179                + "0.0,"
180                + "-0.5,"
181                + "2.2250738585072014E-308,"
182                + "3.141592653589793,"
183                + "2.718281828459045,"
184                + "\"1.0\","
185                + "\"011.0\","
186                + "\"NaN\","
187                + "\"Infinity\","
188                + "\"-Infinity\""
189                + "]";
190        JsonReader reader = new JsonReader(new StringReader(json));
191        reader.beginArray();
192        assertEquals(-0.0, reader.nextDouble());
193        assertEquals(1.0, reader.nextDouble());
194        assertEquals(1.7976931348623157E308, reader.nextDouble());
195        assertEquals(4.9E-324, reader.nextDouble());
196        assertEquals(0.0, reader.nextDouble());
197        assertEquals(-0.5, reader.nextDouble());
198        assertEquals(2.2250738585072014E-308, reader.nextDouble());
199        assertEquals(3.141592653589793, reader.nextDouble());
200        assertEquals(2.718281828459045, reader.nextDouble());
201        assertEquals(1,0, reader.nextDouble());
202        assertEquals(11.0, reader.nextDouble());
203        assertTrue(Double.isNaN(reader.nextDouble()));
204        assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
205        assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
206        reader.endArray();
207        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
208    }
209
210    public void testLenientDoubles() throws IOException {
211        String json = "["
212                + "011.0,"
213                + "NaN,"
214                + "NAN,"
215                + "Infinity,"
216                + "INFINITY,"
217                + "-Infinity"
218                + "]";
219        JsonReader reader = new JsonReader(new StringReader(json));
220        reader.setLenient(true);
221        reader.beginArray();
222        assertEquals(11.0, reader.nextDouble());
223        assertTrue(Double.isNaN(reader.nextDouble()));
224        try {
225            reader.nextDouble();
226            fail();
227        } catch (NumberFormatException expected) {
228        }
229        assertEquals("NAN", reader.nextString());
230        assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
231        try {
232            reader.nextDouble();
233            fail();
234        } catch (NumberFormatException expected) {
235        }
236        assertEquals("INFINITY", reader.nextString());
237        assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
238        reader.endArray();
239        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
240    }
241
242    public void testBufferBoundary() throws IOException {
243        char[] pad = new char[READER_BUFFER_SIZE - 8];
244        Arrays.fill(pad, '5');
245        String json = "[\"" + new String(pad) + "\",33333]";
246        JsonReader reader = new JsonReader(new StringReader(json));
247        reader.beginArray();
248        assertEquals(JsonToken.STRING, reader.peek());
249        assertEquals(new String(pad), reader.nextString());
250        assertEquals(JsonToken.NUMBER, reader.peek());
251        assertEquals(33333, reader.nextInt());
252    }
253
254    public void testTruncatedBufferBoundary() throws IOException {
255        char[] pad = new char[READER_BUFFER_SIZE - 8];
256        Arrays.fill(pad, '5');
257        String json = "[\"" + new String(pad) + "\",33333";
258        JsonReader reader = new JsonReader(new StringReader(json));
259        reader.setLenient(true);
260        reader.beginArray();
261        assertEquals(JsonToken.STRING, reader.peek());
262        assertEquals(new String(pad), reader.nextString());
263        assertEquals(JsonToken.NUMBER, reader.peek());
264        assertEquals(33333, reader.nextInt());
265        try {
266            reader.endArray();
267            fail();
268        } catch (IOException e) {
269        }
270    }
271
272    public void testLongestSupportedNumericLiterals() throws IOException {
273        testLongNumericLiterals(READER_BUFFER_SIZE - 1, JsonToken.NUMBER);
274    }
275
276    public void testLongerNumericLiterals() throws IOException {
277        testLongNumericLiterals(READER_BUFFER_SIZE, JsonToken.STRING);
278    }
279
280    private void testLongNumericLiterals(int length, JsonToken expectedToken) throws IOException {
281        char[] longNumber = new char[length];
282        Arrays.fill(longNumber, '9');
283        longNumber[0] = '1';
284        longNumber[1] = '.';
285
286        String json = "[" + new String(longNumber) + "]";
287        JsonReader reader = new JsonReader(new StringReader(json));
288        reader.setLenient(true);
289        reader.beginArray();
290        assertEquals(expectedToken, reader.peek());
291        assertEquals(2.0d, reader.nextDouble());
292        reader.endArray();
293    }
294
295    public void testLongs() throws IOException {
296        String json = "[0,0,0,"
297                + "1,1,1,"
298                + "-1,-1,-1,"
299                + "-9223372036854775808,"
300                + "9223372036854775807,"
301                + "5.0,"
302                + "1.0e2,"
303                + "\"011\","
304                + "\"5.0\","
305                + "\"1.0e2\""
306                + "]";
307        JsonReader reader = new JsonReader(new StringReader(json));
308        reader.beginArray();
309        assertEquals(0L, reader.nextLong());
310        assertEquals(0, reader.nextInt());
311        assertEquals(0.0, reader.nextDouble());
312        assertEquals(1L, reader.nextLong());
313        assertEquals(1, reader.nextInt());
314        assertEquals(1.0, reader.nextDouble());
315        assertEquals(-1L, reader.nextLong());
316        assertEquals(-1, reader.nextInt());
317        assertEquals(-1.0, reader.nextDouble());
318        try {
319            reader.nextInt();
320            fail();
321        } catch (NumberFormatException expected) {
322        }
323        assertEquals(Long.MIN_VALUE, reader.nextLong());
324        try {
325            reader.nextInt();
326            fail();
327        } catch (NumberFormatException expected) {
328        }
329        assertEquals(Long.MAX_VALUE, reader.nextLong());
330        assertEquals(5, reader.nextLong());
331        assertEquals(100, reader.nextLong());
332        assertEquals(11, reader.nextLong());
333        assertEquals(5, reader.nextLong());
334        assertEquals(100, reader.nextLong());
335        reader.endArray();
336        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
337    }
338
339    /**
340     * This test fails because there's no double for 9223372036854775806, and
341     * our long parsing uses Double.parseDouble() for fractional values.
342     */
343    public void testHighPrecisionLong() throws IOException {
344        String json = "[9223372036854775806.000]";
345        JsonReader reader = new JsonReader(new StringReader(json));
346        reader.beginArray();
347        assertEquals(9223372036854775806L, reader.nextLong());
348        reader.endArray();
349    }
350
351    public void testMatchingValidNumbers() throws IOException {
352        String json = "[-1,99,-0,0,0e1,0e+1,0e-1,0E1,0E+1,0E-1,0.0,1.0,-1.0,1.0e0,1.0e+1,1.0e-1]";
353        JsonReader reader = new JsonReader(new StringReader(json));
354        reader.beginArray();
355        for (int i = 0; i < 16; i++) {
356            assertEquals(JsonToken.NUMBER, reader.peek());
357            reader.nextDouble();
358        }
359        reader.endArray();
360    }
361
362    public void testRecognizingInvalidNumbers() throws IOException {
363        String json = "[-00,00,001,+1,1f,0x,0xf,0x0,0f1,0ee1,1..0,1e0.1,1.-01,1.+1,1.0x,1.0+]";
364        JsonReader reader = new JsonReader(new StringReader(json));
365        reader.setLenient(true);
366        reader.beginArray();
367        for (int i = 0; i < 16; i++) {
368            assertEquals(JsonToken.STRING, reader.peek());
369            reader.nextString();
370        }
371        reader.endArray();
372    }
373
374    public void testNonFiniteDouble() throws IOException {
375        String json = "[NaN]";
376        JsonReader reader = new JsonReader(new StringReader(json));
377        reader.beginArray();
378        try {
379            reader.nextDouble();
380            fail();
381        } catch (IOException expected) {
382        }
383    }
384
385    public void testNumberWithHexPrefix() throws IOException {
386        String json = "[0x11]";
387        JsonReader reader = new JsonReader(new StringReader(json));
388        reader.beginArray();
389        try {
390            reader.nextLong();
391            fail();
392        } catch (IOException expected) {
393        }
394    }
395
396    public void testNumberWithOctalPrefix() throws IOException {
397        String json = "[01]";
398        JsonReader reader = new JsonReader(new StringReader(json));
399        reader.beginArray();
400        try {
401            reader.nextInt();
402            fail();
403        } catch (IOException expected) {
404        }
405    }
406
407    public void testBooleans() throws IOException {
408        JsonReader reader = new JsonReader(new StringReader("[true,false]"));
409        reader.beginArray();
410        assertEquals(true, reader.nextBoolean());
411        assertEquals(false, reader.nextBoolean());
412        reader.endArray();
413        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
414    }
415
416    public void testMixedCaseLiterals() throws IOException {
417        JsonReader reader = new JsonReader(new StringReader("[True,TruE,False,FALSE,NULL,nulL]"));
418        reader.beginArray();
419        assertEquals(true, reader.nextBoolean());
420        assertEquals(true, reader.nextBoolean());
421        assertEquals(false, reader.nextBoolean());
422        assertEquals(false, reader.nextBoolean());
423        reader.nextNull();
424        reader.nextNull();
425        reader.endArray();
426        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
427    }
428
429    public void testMissingValue() throws IOException {
430        JsonReader reader = new JsonReader(new StringReader("{\"a\":}"));
431        reader.beginObject();
432        assertEquals("a", reader.nextName());
433        try {
434            reader.nextString();
435            fail();
436        } catch (IOException expected) {
437        }
438    }
439
440    public void testPrematureEndOfInput() throws IOException {
441        JsonReader reader = new JsonReader(new StringReader("{\"a\":true,"));
442        reader.beginObject();
443        assertEquals("a", reader.nextName());
444        assertEquals(true, reader.nextBoolean());
445        try {
446            reader.nextName();
447            fail();
448        } catch (IOException expected) {
449        }
450    }
451
452    public void testPrematurelyClosed() throws IOException {
453        try {
454            JsonReader reader = new JsonReader(new StringReader("{\"a\":[]}"));
455            reader.beginObject();
456            reader.close();
457            reader.nextName();
458            fail();
459        } catch (IllegalStateException expected) {
460        }
461
462        try {
463            JsonReader reader = new JsonReader(new StringReader("{\"a\":[]}"));
464            reader.close();
465            reader.beginObject();
466            fail();
467        } catch (IllegalStateException expected) {
468        }
469
470        try {
471            JsonReader reader = new JsonReader(new StringReader("{\"a\":true}"));
472            reader.beginObject();
473            reader.nextName();
474            reader.peek();
475            reader.close();
476            reader.nextBoolean();
477            fail();
478        } catch (IllegalStateException expected) {
479        }
480    }
481
482    public void testNextFailuresDoNotAdvance() throws IOException {
483        JsonReader reader = new JsonReader(new StringReader("{\"a\":true}"));
484        reader.beginObject();
485        try {
486            reader.nextString();
487            fail();
488        } catch (IllegalStateException expected) {
489        }
490        assertEquals("a", reader.nextName());
491        try {
492            reader.nextName();
493            fail();
494        } catch (IllegalStateException expected) {
495        }
496        try {
497            reader.beginArray();
498            fail();
499        } catch (IllegalStateException expected) {
500        }
501        try {
502            reader.endArray();
503            fail();
504        } catch (IllegalStateException expected) {
505        }
506        try {
507            reader.beginObject();
508            fail();
509        } catch (IllegalStateException expected) {
510        }
511        try {
512            reader.endObject();
513            fail();
514        } catch (IllegalStateException expected) {
515        }
516        assertEquals(true, reader.nextBoolean());
517        try {
518            reader.nextString();
519            fail();
520        } catch (IllegalStateException expected) {
521        }
522        try {
523            reader.nextName();
524            fail();
525        } catch (IllegalStateException expected) {
526        }
527        try {
528            reader.beginArray();
529            fail();
530        } catch (IllegalStateException expected) {
531        }
532        try {
533            reader.endArray();
534            fail();
535        } catch (IllegalStateException expected) {
536        }
537        reader.endObject();
538        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
539        reader.close();
540    }
541
542    public void testStringNullIsNotNull() throws IOException {
543        JsonReader reader = new JsonReader(new StringReader("[\"null\"]"));
544        reader.beginArray();
545        try {
546            reader.nextNull();
547            fail();
548        } catch (IllegalStateException expected) {
549        }
550    }
551
552    public void testNullLiteralIsNotAString() throws IOException {
553       JsonReader reader = new JsonReader(new StringReader("[null]"));
554        reader.beginArray();
555        try {
556            reader.nextString();
557            fail();
558        } catch (IllegalStateException expected) {
559        }
560    }
561
562    public void testStrictNameValueSeparator() throws IOException {
563        JsonReader reader = new JsonReader(new StringReader("{\"a\"=true}"));
564        reader.beginObject();
565        assertEquals("a", reader.nextName());
566        try {
567            reader.nextBoolean();
568            fail();
569        } catch (IOException expected) {
570        }
571
572        reader = new JsonReader(new StringReader("{\"a\"=>true}"));
573        reader.beginObject();
574        assertEquals("a", reader.nextName());
575        try {
576            reader.nextBoolean();
577            fail();
578        } catch (IOException expected) {
579        }
580    }
581
582    public void testLenientNameValueSeparator() throws IOException {
583        JsonReader reader = new JsonReader(new StringReader("{\"a\"=true}"));
584        reader.setLenient(true);
585        reader.beginObject();
586        assertEquals("a", reader.nextName());
587        assertEquals(true, reader.nextBoolean());
588
589        reader = new JsonReader(new StringReader("{\"a\"=>true}"));
590        reader.setLenient(true);
591        reader.beginObject();
592        assertEquals("a", reader.nextName());
593        assertEquals(true, reader.nextBoolean());
594    }
595
596    public void testStrictComments() throws IOException {
597        JsonReader reader = new JsonReader(new StringReader("[// comment \n true]"));
598        reader.beginArray();
599        try {
600            reader.nextBoolean();
601            fail();
602        } catch (IOException expected) {
603        }
604
605        reader = new JsonReader(new StringReader("[# comment \n true]"));
606        reader.beginArray();
607        try {
608            reader.nextBoolean();
609            fail();
610        } catch (IOException expected) {
611        }
612
613        reader = new JsonReader(new StringReader("[/* comment */ true]"));
614        reader.beginArray();
615        try {
616            reader.nextBoolean();
617            fail();
618        } catch (IOException expected) {
619        }
620    }
621
622    public void testLenientComments() throws IOException {
623        JsonReader reader = new JsonReader(new StringReader("[// comment \n true]"));
624        reader.setLenient(true);
625        reader.beginArray();
626        assertEquals(true, reader.nextBoolean());
627
628        reader = new JsonReader(new StringReader("[# comment \n true]"));
629        reader.setLenient(true);
630        reader.beginArray();
631        assertEquals(true, reader.nextBoolean());
632
633        reader = new JsonReader(new StringReader("[/* comment */ true]"));
634        reader.setLenient(true);
635        reader.beginArray();
636        assertEquals(true, reader.nextBoolean());
637    }
638
639    public void testStrictUnquotedNames() throws IOException {
640        JsonReader reader = new JsonReader(new StringReader("{a:true}"));
641        reader.beginObject();
642        try {
643            reader.nextName();
644            fail();
645        } catch (IOException expected) {
646        }
647    }
648
649    public void testLenientUnquotedNames() throws IOException {
650        JsonReader reader = new JsonReader(new StringReader("{a:true}"));
651        reader.setLenient(true);
652        reader.beginObject();
653        assertEquals("a", reader.nextName());
654    }
655
656    public void testStrictSingleQuotedNames() throws IOException {
657        JsonReader reader = new JsonReader(new StringReader("{'a':true}"));
658        reader.beginObject();
659        try {
660            reader.nextName();
661            fail();
662        } catch (IOException expected) {
663        }
664    }
665
666    public void testLenientSingleQuotedNames() throws IOException {
667        JsonReader reader = new JsonReader(new StringReader("{'a':true}"));
668        reader.setLenient(true);
669        reader.beginObject();
670        assertEquals("a", reader.nextName());
671    }
672
673    public void testStrictUnquotedStrings() throws IOException {
674        JsonReader reader = new JsonReader(new StringReader("[a]"));
675        reader.beginArray();
676        try {
677            reader.nextString();
678            fail();
679        } catch (MalformedJsonException expected) {
680        }
681    }
682
683    public void testLenientUnquotedStrings() throws IOException {
684        JsonReader reader = new JsonReader(new StringReader("[a]"));
685        reader.setLenient(true);
686        reader.beginArray();
687        assertEquals("a", reader.nextString());
688    }
689
690    public void testStrictSingleQuotedStrings() throws IOException {
691        JsonReader reader = new JsonReader(new StringReader("['a']"));
692        reader.beginArray();
693        try {
694            reader.nextString();
695            fail();
696        } catch (IOException expected) {
697        }
698    }
699
700    public void testLenientSingleQuotedStrings() throws IOException {
701        JsonReader reader = new JsonReader(new StringReader("['a']"));
702        reader.setLenient(true);
703        reader.beginArray();
704        assertEquals("a", reader.nextString());
705    }
706
707    public void testStrictSemicolonDelimitedArray() throws IOException {
708        JsonReader reader = new JsonReader(new StringReader("[true;true]"));
709        reader.beginArray();
710        try {
711            reader.nextBoolean();
712            reader.nextBoolean();
713            fail();
714        } catch (IOException expected) {
715        }
716    }
717
718    public void testLenientSemicolonDelimitedArray() throws IOException {
719        JsonReader reader = new JsonReader(new StringReader("[true;true]"));
720        reader.setLenient(true);
721        reader.beginArray();
722        assertEquals(true, reader.nextBoolean());
723        assertEquals(true, reader.nextBoolean());
724    }
725
726    public void testStrictSemicolonDelimitedNameValuePair() throws IOException {
727        JsonReader reader = new JsonReader(new StringReader("{\"a\":true;\"b\":true}"));
728        reader.beginObject();
729        assertEquals("a", reader.nextName());
730        try {
731            reader.nextBoolean();
732            reader.nextName();
733            fail();
734        } catch (IOException expected) {
735        }
736    }
737
738    public void testLenientSemicolonDelimitedNameValuePair() throws IOException {
739        JsonReader reader = new JsonReader(new StringReader("{\"a\":true;\"b\":true}"));
740        reader.setLenient(true);
741        reader.beginObject();
742        assertEquals("a", reader.nextName());
743        assertEquals(true, reader.nextBoolean());
744        assertEquals("b", reader.nextName());
745    }
746
747    public void testStrictUnnecessaryArraySeparators() throws IOException {
748        JsonReader reader = new JsonReader(new StringReader("[true,,true]"));
749        reader.beginArray();
750        assertEquals(true, reader.nextBoolean());
751        try {
752            reader.nextNull();
753            fail();
754        } catch (IOException expected) {
755        }
756
757        reader = new JsonReader(new StringReader("[,true]"));
758        reader.beginArray();
759        try {
760            reader.nextNull();
761            fail();
762        } catch (IOException expected) {
763        }
764
765        reader = new JsonReader(new StringReader("[true,]"));
766        reader.beginArray();
767        assertEquals(true, reader.nextBoolean());
768        try {
769            reader.nextNull();
770            fail();
771        } catch (IOException expected) {
772        }
773
774        reader = new JsonReader(new StringReader("[,]"));
775        reader.beginArray();
776        try {
777            reader.nextNull();
778            fail();
779        } catch (IOException expected) {
780        }
781    }
782
783    public void testLenientUnnecessaryArraySeparators() throws IOException {
784        JsonReader reader = new JsonReader(new StringReader("[true,,true]"));
785        reader.setLenient(true);
786        reader.beginArray();
787        assertEquals(true, reader.nextBoolean());
788        reader.nextNull();
789        assertEquals(true, reader.nextBoolean());
790        reader.endArray();
791
792        reader = new JsonReader(new StringReader("[,true]"));
793        reader.setLenient(true);
794        reader.beginArray();
795        reader.nextNull();
796        assertEquals(true, reader.nextBoolean());
797        reader.endArray();
798
799        reader = new JsonReader(new StringReader("[true,]"));
800        reader.setLenient(true);
801        reader.beginArray();
802        assertEquals(true, reader.nextBoolean());
803        reader.nextNull();
804        reader.endArray();
805
806        reader = new JsonReader(new StringReader("[,]"));
807        reader.setLenient(true);
808        reader.beginArray();
809        reader.nextNull();
810        reader.nextNull();
811        reader.endArray();
812    }
813
814    public void testStrictMultipleTopLevelValues() throws IOException {
815        JsonReader reader = new JsonReader(new StringReader("[] []"));
816        reader.beginArray();
817        reader.endArray();
818        try {
819            reader.peek();
820            fail();
821        } catch (IOException expected) {
822        }
823    }
824
825    public void testLenientMultipleTopLevelValues() throws IOException {
826        JsonReader reader = new JsonReader(new StringReader("[] true {}"));
827        reader.setLenient(true);
828        reader.beginArray();
829        reader.endArray();
830        assertEquals(true, reader.nextBoolean());
831        reader.beginObject();
832        reader.endObject();
833        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
834    }
835
836    public void testStrictTopLevelValueType() {
837        JsonReader reader = new JsonReader(new StringReader("true"));
838        try {
839            reader.nextBoolean();
840            fail();
841        } catch (IOException expected) {
842        }
843    }
844
845    public void testLenientTopLevelValueType() throws IOException {
846        JsonReader reader = new JsonReader(new StringReader("true"));
847        reader.setLenient(true);
848        assertEquals(true, reader.nextBoolean());
849    }
850
851    public void testStrictNonExecutePrefix() {
852        JsonReader reader = new JsonReader(new StringReader(")]}'\n []"));
853        try {
854            reader.beginArray();
855            fail();
856        } catch (IOException expected) {
857        }
858    }
859
860    public void testBomIgnoredAsFirstCharacterOfDocument() throws IOException {
861        JsonReader reader = new JsonReader(new StringReader("\ufeff[]"));
862        reader.beginArray();
863        reader.endArray();
864    }
865
866    public void testBomForbiddenAsOtherCharacterInDocument() throws IOException {
867        JsonReader reader = new JsonReader(new StringReader("[\ufeff]"));
868        reader.beginArray();
869        try {
870            reader.endArray();
871            fail();
872        } catch (IOException expected) {
873        }
874    }
875
876    public void testFailWithPosition() throws IOException {
877        testFailWithPosition("Expected literal value at line 6 column 3",
878                "[\n\n\n\n\n0,}]");
879    }
880
881    public void testFailWithPositionIsOffsetByBom() throws IOException {
882        testFailWithPosition("Expected literal value at line 1 column 4",
883                "\ufeff[0,}]");
884    }
885
886    public void testFailWithPositionGreaterThanBufferSize() throws IOException {
887        String spaces = repeat(' ', 8192);
888        testFailWithPosition("Expected literal value at line 6 column 3",
889                "[\n\n" + spaces + "\n\n\n0,}]");
890    }
891
892    private void testFailWithPosition(String message, String json) throws IOException {
893        JsonReader reader = new JsonReader(new StringReader(json));
894        reader.beginArray();
895        reader.nextInt();
896        try {
897            reader.peek();
898            fail();
899        } catch (IOException expected) {
900            assertEquals(message, expected.getMessage());
901        }
902    }
903
904    private String repeat(char c, int count) {
905        char[] array = new char[count];
906        Arrays.fill(array, c);
907        return new String(array);
908    }
909}
910