Home | History | Annotate | Download | only in util
      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 
     17 package android.util;
     18 
     19 import java.io.IOException;
     20 import java.io.StringReader;
     21 import java.util.Arrays;
     22 import junit.framework.TestCase;
     23 
     24 public 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