Home | History | Annotate | Download | only in json
      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 org.json;
     18 
     19 import junit.framework.TestCase;
     20 
     21 import java.util.Arrays;
     22 import java.util.List;
     23 import java.util.Collections;
     24 
     25 /**
     26  * This black box test was written without inspecting the non-free org.json sourcecode.
     27  */
     28 public class JSONArrayTest extends TestCase {
     29 
     30     public void testEmptyArray() throws JSONException {
     31         JSONArray array = new JSONArray();
     32         assertEquals(0, array.length());
     33         assertEquals("", array.join(" AND "));
     34         try {
     35             array.get(0);
     36             fail();
     37         } catch (JSONException e) {
     38         }
     39         try {
     40             array.getBoolean(0);
     41             fail();
     42         } catch (JSONException e) {
     43         }
     44 
     45         assertEquals("[]", array.toString());
     46         assertEquals("[]", array.toString(4));
     47 
     48         // out of bounds is co-opted with defaulting
     49         assertTrue(array.isNull(0));
     50         assertNull(array.opt(0));
     51         assertFalse(array.optBoolean(0));
     52         assertTrue(array.optBoolean(0, true));
     53 
     54         // bogus (but documented) behaviour: returns null rather than an empty object!
     55         assertNull(array.toJSONObject(new JSONArray()));
     56     }
     57 
     58     public void testEqualsAndHashCode() throws JSONException {
     59         JSONArray a = new JSONArray();
     60         JSONArray b = new JSONArray();
     61         assertTrue(a.equals(b));
     62         assertEquals("equals() not consistent with hashCode()", a.hashCode(), b.hashCode());
     63 
     64         a.put(true);
     65         a.put(false);
     66         b.put(true);
     67         b.put(false);
     68         assertTrue(a.equals(b));
     69         assertEquals(a.hashCode(), b.hashCode());
     70 
     71         b.put(true);
     72         assertFalse(a.equals(b));
     73         assertTrue(a.hashCode() != b.hashCode());
     74     }
     75 
     76     public void testBooleans() throws JSONException {
     77         JSONArray array = new JSONArray();
     78         array.put(true);
     79         array.put(false);
     80         array.put(2, false);
     81         array.put(3, false);
     82         array.put(2, true);
     83         assertEquals("[true,false,true,false]", array.toString());
     84         assertEquals(4, array.length());
     85         assertEquals(Boolean.TRUE, array.get(0));
     86         assertEquals(Boolean.FALSE, array.get(1));
     87         assertEquals(Boolean.TRUE, array.get(2));
     88         assertEquals(Boolean.FALSE, array.get(3));
     89         assertFalse(array.isNull(0));
     90         assertFalse(array.isNull(1));
     91         assertFalse(array.isNull(2));
     92         assertFalse(array.isNull(3));
     93         assertEquals(true, array.optBoolean(0));
     94         assertEquals(false, array.optBoolean(1, true));
     95         assertEquals(true, array.optBoolean(2, false));
     96         assertEquals(false, array.optBoolean(3));
     97         assertEquals("true", array.getString(0));
     98         assertEquals("false", array.getString(1));
     99         assertEquals("true", array.optString(2));
    100         assertEquals("false", array.optString(3, "x"));
    101         assertEquals("[\n     true,\n     false,\n     true,\n     false\n]", array.toString(5));
    102 
    103         JSONArray other = new JSONArray();
    104         other.put(true);
    105         other.put(false);
    106         other.put(true);
    107         other.put(false);
    108         assertTrue(array.equals(other));
    109         other.put(true);
    110         assertFalse(array.equals(other));
    111 
    112         other = new JSONArray();
    113         other.put("true");
    114         other.put("false");
    115         other.put("truE");
    116         other.put("FALSE");
    117         assertFalse(array.equals(other));
    118         assertFalse(other.equals(array));
    119         assertEquals(true, other.getBoolean(0));
    120         assertEquals(false, other.optBoolean(1, true));
    121         assertEquals(true, other.optBoolean(2));
    122         assertEquals(false, other.getBoolean(3));
    123     }
    124 
    125     public void testNulls() throws JSONException {
    126         JSONArray array = new JSONArray();
    127         array.put(3, null);
    128         array.put(0, JSONObject.NULL);
    129         assertEquals(4, array.length());
    130         assertEquals("[null,null,null,null]", array.toString());
    131 
    132         // there's 2 ways to represent null; each behaves differently!
    133         assertEquals(JSONObject.NULL, array.get(0));
    134         try {
    135             array.get(1);
    136             fail();
    137         } catch (JSONException e) {
    138         }
    139         try {
    140             array.get(2);
    141             fail();
    142         } catch (JSONException e) {
    143         }
    144         try {
    145             array.get(3);
    146             fail();
    147         } catch (JSONException e) {
    148         }
    149         assertEquals(JSONObject.NULL, array.opt(0));
    150         assertEquals(null, array.opt(1));
    151         assertEquals(null, array.opt(2));
    152         assertEquals(null, array.opt(3));
    153         assertTrue(array.isNull(0));
    154         assertTrue(array.isNull(1));
    155         assertTrue(array.isNull(2));
    156         assertTrue(array.isNull(3));
    157         assertEquals("null", array.optString(0));
    158         assertEquals("", array.optString(1));
    159         assertEquals("", array.optString(2));
    160         assertEquals("", array.optString(3));
    161     }
    162 
    163     /**
    164      * Our behaviour is questioned by this bug:
    165      * http://code.google.com/p/android/issues/detail?id=7257
    166      */
    167     public void testParseNullYieldsJSONObjectNull() throws JSONException {
    168         JSONArray array = new JSONArray("[\"null\",null]");
    169         array.put(null);
    170         assertEquals("null", array.get(0));
    171         assertEquals(JSONObject.NULL, array.get(1));
    172         try {
    173             array.get(2);
    174             fail();
    175         } catch (JSONException e) {
    176         }
    177         assertEquals("null", array.getString(0));
    178         assertEquals("null", array.getString(1));
    179         try {
    180             array.getString(2);
    181             fail();
    182         } catch (JSONException e) {
    183         }
    184     }
    185 
    186     public void testNumbers() throws JSONException {
    187         JSONArray array = new JSONArray();
    188         array.put(Double.MIN_VALUE);
    189         array.put(9223372036854775806L);
    190         array.put(Double.MAX_VALUE);
    191         array.put(-0d);
    192         assertEquals(4, array.length());
    193 
    194         // toString() and getString(int) return different values for -0d
    195         assertEquals("[4.9E-324,9223372036854775806,1.7976931348623157E308,-0]", array.toString());
    196 
    197         assertEquals(Double.MIN_VALUE, array.get(0));
    198         assertEquals(9223372036854775806L, array.get(1));
    199         assertEquals(Double.MAX_VALUE, array.get(2));
    200         assertEquals(-0d, array.get(3));
    201         assertEquals(Double.MIN_VALUE, array.getDouble(0));
    202         assertEquals(9.223372036854776E18, array.getDouble(1));
    203         assertEquals(Double.MAX_VALUE, array.getDouble(2));
    204         assertEquals(-0d, array.getDouble(3));
    205         assertEquals(0, array.getLong(0));
    206         assertEquals(9223372036854775806L, array.getLong(1));
    207         assertEquals(Long.MAX_VALUE, array.getLong(2));
    208         assertEquals(0, array.getLong(3));
    209         assertEquals(0, array.getInt(0));
    210         assertEquals(-2, array.getInt(1));
    211         assertEquals(Integer.MAX_VALUE, array.getInt(2));
    212         assertEquals(0, array.getInt(3));
    213         assertEquals(Double.MIN_VALUE, array.opt(0));
    214         assertEquals(Double.MIN_VALUE, array.optDouble(0));
    215         assertEquals(0, array.optLong(0, 1L));
    216         assertEquals(0, array.optInt(0, 1));
    217         assertEquals("4.9E-324", array.getString(0));
    218         assertEquals("9223372036854775806", array.getString(1));
    219         assertEquals("1.7976931348623157E308", array.getString(2));
    220         assertEquals("-0.0", array.getString(3));
    221 
    222         JSONArray other = new JSONArray();
    223         other.put(Double.MIN_VALUE);
    224         other.put(9223372036854775806L);
    225         other.put(Double.MAX_VALUE);
    226         other.put(-0d);
    227         assertTrue(array.equals(other));
    228         other.put(0, 0L);
    229         assertFalse(array.equals(other));
    230     }
    231 
    232     public void testStrings() throws JSONException {
    233         JSONArray array = new JSONArray();
    234         array.put("true");
    235         array.put("5.5");
    236         array.put("9223372036854775806");
    237         array.put("null");
    238         array.put("5\"8' tall");
    239         assertEquals(5, array.length());
    240         assertEquals("[\"true\",\"5.5\",\"9223372036854775806\",\"null\",\"5\\\"8' tall\"]",
    241                 array.toString());
    242 
    243         // although the documentation doesn't mention it, join() escapes text and wraps
    244         // strings in quotes
    245         assertEquals("\"true\" \"5.5\" \"9223372036854775806\" \"null\" \"5\\\"8' tall\"",
    246                 array.join(" "));
    247 
    248         assertEquals("true", array.get(0));
    249         assertEquals("null", array.getString(3));
    250         assertEquals("5\"8' tall", array.getString(4));
    251         assertEquals("true", array.opt(0));
    252         assertEquals("5.5", array.optString(1));
    253         assertEquals("9223372036854775806", array.optString(2, null));
    254         assertEquals("null", array.optString(3, "-1"));
    255         assertFalse(array.isNull(0));
    256         assertFalse(array.isNull(3));
    257 
    258         assertEquals(true, array.getBoolean(0));
    259         assertEquals(true, array.optBoolean(0));
    260         assertEquals(true, array.optBoolean(0, false));
    261         assertEquals(0, array.optInt(0));
    262         assertEquals(-2, array.optInt(0, -2));
    263 
    264         assertEquals(5.5d, array.getDouble(1));
    265         assertEquals(5L, array.getLong(1));
    266         assertEquals(5, array.getInt(1));
    267         assertEquals(5, array.optInt(1, 3));
    268 
    269         // The last digit of the string is a 6 but getLong returns a 7. It's probably parsing as a
    270         // double and then converting that to a long. This is consistent with JavaScript.
    271         assertEquals(9223372036854775807L, array.getLong(2));
    272         assertEquals(9.223372036854776E18, array.getDouble(2));
    273         assertEquals(Integer.MAX_VALUE, array.getInt(2));
    274 
    275         assertFalse(array.isNull(3));
    276         try {
    277             array.getDouble(3);
    278             fail();
    279         } catch (JSONException e) {
    280         }
    281         assertEquals(Double.NaN, array.optDouble(3));
    282         assertEquals(-1.0d, array.optDouble(3, -1.0d));
    283     }
    284 
    285     public void testJoin() throws JSONException {
    286         JSONArray array = new JSONArray();
    287         array.put(null);
    288         assertEquals("null", array.join(" & "));
    289         array.put("\"");
    290         assertEquals("null & \"\\\"\"", array.join(" & "));
    291         array.put(5);
    292         assertEquals("null & \"\\\"\" & 5", array.join(" & "));
    293         array.put(true);
    294         assertEquals("null & \"\\\"\" & 5 & true", array.join(" & "));
    295         array.put(new JSONArray(Arrays.asList(true, false)));
    296         assertEquals("null & \"\\\"\" & 5 & true & [true,false]", array.join(" & "));
    297         array.put(new JSONObject(Collections.singletonMap("x", 6)));
    298         assertEquals("null & \"\\\"\" & 5 & true & [true,false] & {\"x\":6}", array.join(" & "));
    299     }
    300 
    301     public void testJoinWithNull() throws JSONException {
    302         JSONArray array = new JSONArray(Arrays.asList(5, 6));
    303         assertEquals("5null6", array.join(null));
    304     }
    305 
    306     public void testJoinWithSpecialCharacters() throws JSONException {
    307         JSONArray array = new JSONArray(Arrays.asList(5, 6));
    308         assertEquals("5\"6", array.join("\""));
    309     }
    310 
    311     public void testToJSONObject() throws JSONException {
    312         JSONArray keys = new JSONArray();
    313         keys.put("a");
    314         keys.put("b");
    315 
    316         JSONArray values = new JSONArray();
    317         values.put(5.5d);
    318         values.put(false);
    319 
    320         JSONObject object = values.toJSONObject(keys);
    321         assertEquals(5.5d, object.get("a"));
    322         assertEquals(false, object.get("b"));
    323 
    324         keys.put(0, "a");
    325         values.put(0, 11.0d);
    326         assertEquals(5.5d, object.get("a"));
    327     }
    328 
    329     public void testToJSONObjectWithNulls() throws JSONException {
    330         JSONArray keys = new JSONArray();
    331         keys.put("a");
    332         keys.put("b");
    333 
    334         JSONArray values = new JSONArray();
    335         values.put(5.5d);
    336         values.put(null);
    337 
    338         // null values are stripped!
    339         JSONObject object = values.toJSONObject(keys);
    340         assertEquals(1, object.length());
    341         assertFalse(object.has("b"));
    342         assertEquals("{\"a\":5.5}", object.toString());
    343     }
    344 
    345     public void testToJSONObjectMoreNamesThanValues() throws JSONException {
    346         JSONArray keys = new JSONArray();
    347         keys.put("a");
    348         keys.put("b");
    349         JSONArray values = new JSONArray();
    350         values.put(5.5d);
    351         JSONObject object = values.toJSONObject(keys);
    352         assertEquals(1, object.length());
    353         assertEquals(5.5d, object.get("a"));
    354     }
    355 
    356     public void testToJSONObjectMoreValuesThanNames() throws JSONException {
    357         JSONArray keys = new JSONArray();
    358         keys.put("a");
    359         JSONArray values = new JSONArray();
    360         values.put(5.5d);
    361         values.put(11.0d);
    362         JSONObject object = values.toJSONObject(keys);
    363         assertEquals(1, object.length());
    364         assertEquals(5.5d, object.get("a"));
    365     }
    366 
    367     public void testToJSONObjectNullKey() throws JSONException {
    368         JSONArray keys = new JSONArray();
    369         keys.put(JSONObject.NULL);
    370         JSONArray values = new JSONArray();
    371         values.put(5.5d);
    372         JSONObject object = values.toJSONObject(keys);
    373         assertEquals(1, object.length());
    374         assertEquals(5.5d, object.get("null"));
    375     }
    376 
    377     public void testPutUnsupportedNumbers() throws JSONException {
    378         JSONArray array = new JSONArray();
    379 
    380         try {
    381             array.put(Double.NaN);
    382             fail();
    383         } catch (JSONException e) {
    384         }
    385         try {
    386             array.put(0, Double.NEGATIVE_INFINITY);
    387             fail();
    388         } catch (JSONException e) {
    389         }
    390         try {
    391             array.put(0, Double.POSITIVE_INFINITY);
    392             fail();
    393         } catch (JSONException e) {
    394         }
    395     }
    396 
    397     public void testPutUnsupportedNumbersAsObject() throws JSONException {
    398         JSONArray array = new JSONArray();
    399         array.put(Double.valueOf(Double.NaN));
    400         array.put(Double.valueOf(Double.NEGATIVE_INFINITY));
    401         array.put(Double.valueOf(Double.POSITIVE_INFINITY));
    402         assertEquals(null, array.toString());
    403     }
    404 
    405     /**
    406      * Although JSONArray is usually defensive about which numbers it accepts,
    407      * it doesn't check inputs in its constructor.
    408      */
    409     public void testCreateWithUnsupportedNumbers() throws JSONException {
    410         JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN));
    411         assertEquals(2, array.length());
    412         assertEquals(5.5, array.getDouble(0));
    413         assertEquals(Double.NaN, array.getDouble(1));
    414     }
    415 
    416     public void testToStringWithUnsupportedNumbers() throws JSONException {
    417         // when the array contains an unsupported number, toString returns null!
    418         JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN));
    419         assertNull(array.toString());
    420     }
    421 
    422     public void testListConstructorCopiesContents() throws JSONException {
    423         List<Object> contents = Arrays.<Object>asList(5);
    424         JSONArray array = new JSONArray(contents);
    425         contents.set(0, 10);
    426         assertEquals(5, array.get(0));
    427     }
    428 
    429     public void testTokenerConstructor() throws JSONException {
    430         JSONArray object = new JSONArray(new JSONTokener("[false]"));
    431         assertEquals(1, object.length());
    432         assertEquals(false, object.get(0));
    433     }
    434 
    435     public void testTokenerConstructorWrongType() throws JSONException {
    436         try {
    437             new JSONArray(new JSONTokener("{\"foo\": false}"));
    438             fail();
    439         } catch (JSONException e) {
    440         }
    441     }
    442 
    443     public void testTokenerConstructorNull() throws JSONException {
    444         try {
    445             new JSONArray((JSONTokener) null);
    446             fail();
    447         } catch (NullPointerException e) {
    448         }
    449     }
    450 
    451     public void testTokenerConstructorParseFail() {
    452         try {
    453             new JSONArray(new JSONTokener("["));
    454             fail();
    455         } catch (JSONException e) {
    456         } catch (StackOverflowError e) {
    457             fail("Stack overflowed on input: \"[\"");
    458         }
    459     }
    460 
    461     public void testStringConstructor() throws JSONException {
    462         JSONArray object = new JSONArray("[false]");
    463         assertEquals(1, object.length());
    464         assertEquals(false, object.get(0));
    465     }
    466 
    467     public void testStringConstructorWrongType() throws JSONException {
    468         try {
    469             new JSONArray("{\"foo\": false}");
    470             fail();
    471         } catch (JSONException e) {
    472         }
    473     }
    474 
    475     public void testStringConstructorNull() throws JSONException {
    476         try {
    477             new JSONArray((String) null);
    478             fail();
    479         } catch (NullPointerException e) {
    480         }
    481     }
    482 
    483     public void testStringConstructorParseFail() {
    484         try {
    485             new JSONArray("[");
    486             fail();
    487         } catch (JSONException e) {
    488         } catch (StackOverflowError e) {
    489             fail("Stack overflowed on input: \"[\"");
    490         }
    491     }
    492 
    493     public void testCreate() throws JSONException {
    494         JSONArray array = new JSONArray(Arrays.asList(5.5, true));
    495         assertEquals(2, array.length());
    496         assertEquals(5.5, array.getDouble(0));
    497         assertEquals(true, array.get(1));
    498         assertEquals("[5.5,true]", array.toString());
    499     }
    500 
    501     public void testAccessOutOfBounds() throws JSONException {
    502         JSONArray array = new JSONArray();
    503         array.put("foo");
    504         assertEquals(null, array.opt(3));
    505         assertEquals(null, array.opt(-3));
    506         assertEquals("", array.optString(3));
    507         assertEquals("", array.optString(-3));
    508         try {
    509             array.get(3);
    510             fail();
    511         } catch (JSONException e) {
    512         }
    513         try {
    514             array.get(-3);
    515             fail();
    516         } catch (JSONException e) {
    517         }
    518         try {
    519             array.getString(3);
    520             fail();
    521         } catch (JSONException e) {
    522         }
    523         try {
    524             array.getString(-3);
    525             fail();
    526         } catch (JSONException e) {
    527         }
    528     }
    529 }
    530