JSONArrayTest.java revision 4558195b4a7ee014517f1aa3c59bc6c561baa2ef
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 org.json;
18
19import junit.framework.TestCase;
20
21import java.util.Arrays;
22import java.util.List;
23import java.util.Collections;
24
25/**
26 * This black box test was written without inspecting the non-free org.json sourcecode.
27 */
28public 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    public void testNumbers() throws JSONException {
164        JSONArray array = new JSONArray();
165        array.put(Double.MIN_VALUE);
166        array.put(9223372036854775806L);
167        array.put(Double.MAX_VALUE);
168        array.put(-0d);
169        assertEquals(4, array.length());
170
171        // toString() and getString(int) return different values for -0d
172        assertEquals("[4.9E-324,9223372036854775806,1.7976931348623157E308,-0]", array.toString());
173
174        assertEquals(Double.MIN_VALUE, array.get(0));
175        assertEquals(9223372036854775806L, array.get(1));
176        assertEquals(Double.MAX_VALUE, array.get(2));
177        assertEquals(-0d, array.get(3));
178        assertEquals(Double.MIN_VALUE, array.getDouble(0));
179        assertEquals(9.223372036854776E18, array.getDouble(1));
180        assertEquals(Double.MAX_VALUE, array.getDouble(2));
181        assertEquals(-0d, array.getDouble(3));
182        assertEquals(0, array.getLong(0));
183        assertEquals(9223372036854775806L, array.getLong(1));
184        assertEquals(Long.MAX_VALUE, array.getLong(2));
185        assertEquals(0, array.getLong(3));
186        assertEquals(0, array.getInt(0));
187        assertEquals(-2, array.getInt(1));
188        assertEquals(Integer.MAX_VALUE, array.getInt(2));
189        assertEquals(0, array.getInt(3));
190        assertEquals(Double.MIN_VALUE, array.opt(0));
191        assertEquals(Double.MIN_VALUE, array.optDouble(0));
192        assertEquals(0, array.optLong(0, 1L));
193        assertEquals(0, array.optInt(0, 1));
194        assertEquals("4.9E-324", array.getString(0));
195        assertEquals("9223372036854775806", array.getString(1));
196        assertEquals("1.7976931348623157E308", array.getString(2));
197        assertEquals("-0.0", array.getString(3));
198
199        JSONArray other = new JSONArray();
200        other.put(Double.MIN_VALUE);
201        other.put(9223372036854775806L);
202        other.put(Double.MAX_VALUE);
203        other.put(-0d);
204        assertTrue(array.equals(other));
205        other.put(0, 0L);
206        assertFalse(array.equals(other));
207    }
208
209    public void testStrings() throws JSONException {
210        JSONArray array = new JSONArray();
211        array.put("true");
212        array.put("5.5");
213        array.put("9223372036854775806");
214        array.put("null");
215        array.put("5\"8' tall");
216        assertEquals(5, array.length());
217        assertEquals("[\"true\",\"5.5\",\"9223372036854775806\",\"null\",\"5\\\"8' tall\"]",
218                array.toString());
219
220        // although the documentation doesn't mention it, join() escapes text and wraps
221        // strings in quotes
222        assertEquals("\"true\" \"5.5\" \"9223372036854775806\" \"null\" \"5\\\"8' tall\"",
223                array.join(" "));
224
225        assertEquals("true", array.get(0));
226        assertEquals("null", array.getString(3));
227        assertEquals("5\"8' tall", array.getString(4));
228        assertEquals("true", array.opt(0));
229        assertEquals("5.5", array.optString(1));
230        assertEquals("9223372036854775806", array.optString(2, null));
231        assertEquals("null", array.optString(3, "-1"));
232        assertFalse(array.isNull(0));
233        assertFalse(array.isNull(3));
234
235        assertEquals(true, array.getBoolean(0));
236        assertEquals(true, array.optBoolean(0));
237        assertEquals(true, array.optBoolean(0, false));
238        assertEquals(0, array.optInt(0));
239        assertEquals(-2, array.optInt(0, -2));
240
241        assertEquals(5.5d, array.getDouble(1));
242        assertEquals(5L, array.getLong(1));
243        assertEquals(5, array.getInt(1));
244        assertEquals(5, array.optInt(1, 3));
245
246        // The last digit of the string is a 6 but getLong returns a 7. It's probably parsing as a
247        // double and then converting that to a long. This is consistent with JavaScript.
248        assertEquals(9223372036854775807L, array.getLong(2));
249        assertEquals(9.223372036854776E18, array.getDouble(2));
250        assertEquals(Integer.MAX_VALUE, array.getInt(2));
251
252        assertFalse(array.isNull(3));
253        try {
254            array.getDouble(3);
255            fail();
256        } catch (JSONException e) {
257        }
258        assertEquals(Double.NaN, array.optDouble(3));
259        assertEquals(-1.0d, array.optDouble(3, -1.0d));
260    }
261
262    public void testJoin() throws JSONException {
263        JSONArray array = new JSONArray();
264        array.put(null);
265        assertEquals("null", array.join(" & "));
266        array.put("\"");
267        assertEquals("null & \"\\\"\"", array.join(" & "));
268        array.put(5);
269        assertEquals("null & \"\\\"\" & 5", array.join(" & "));
270        array.put(true);
271        assertEquals("null & \"\\\"\" & 5 & true", array.join(" & "));
272        array.put(new JSONArray(Arrays.asList(true, false)));
273        assertEquals("null & \"\\\"\" & 5 & true & [true,false]", array.join(" & "));
274        array.put(new JSONObject(Collections.singletonMap("x", 6)));
275        assertEquals("null & \"\\\"\" & 5 & true & [true,false] & {\"x\":6}", array.join(" & "));
276    }
277
278    public void testJoinWithNull() throws JSONException {
279        JSONArray array = new JSONArray(Arrays.asList(5, 6));
280        assertEquals("5null6", array.join(null));
281    }
282
283    public void testJoinWithSpecialCharacters() throws JSONException {
284        JSONArray array = new JSONArray(Arrays.asList(5, 6));
285        assertEquals("5\"6", array.join("\""));
286    }
287
288    public void testToJSONObject() throws JSONException {
289        JSONArray keys = new JSONArray();
290        keys.put("a");
291        keys.put("b");
292
293        JSONArray values = new JSONArray();
294        values.put(5.5d);
295        values.put(false);
296
297        JSONObject object = values.toJSONObject(keys);
298        assertEquals(5.5d, object.get("a"));
299        assertEquals(false, object.get("b"));
300
301        keys.put(0, "a");
302        values.put(0, 11.0d);
303        assertEquals(5.5d, object.get("a"));
304    }
305
306    public void testToJSONObjectWithNulls() throws JSONException {
307        JSONArray keys = new JSONArray();
308        keys.put("a");
309        keys.put("b");
310
311        JSONArray values = new JSONArray();
312        values.put(5.5d);
313        values.put(null);
314
315        // null values are stripped!
316        JSONObject object = values.toJSONObject(keys);
317        assertEquals(1, object.length());
318        assertFalse(object.has("b"));
319        assertEquals("{\"a\":5.5}", object.toString());
320    }
321
322    public void testToJSONObjectMoreNamesThanValues() throws JSONException {
323        JSONArray keys = new JSONArray();
324        keys.put("a");
325        keys.put("b");
326        JSONArray values = new JSONArray();
327        values.put(5.5d);
328        JSONObject object = values.toJSONObject(keys);
329        assertEquals(1, object.length());
330        assertEquals(5.5d, object.get("a"));
331    }
332
333    public void testToJSONObjectMoreValuesThanNames() throws JSONException {
334        JSONArray keys = new JSONArray();
335        keys.put("a");
336        JSONArray values = new JSONArray();
337        values.put(5.5d);
338        values.put(11.0d);
339        JSONObject object = values.toJSONObject(keys);
340        assertEquals(1, object.length());
341        assertEquals(5.5d, object.get("a"));
342    }
343
344    public void testToJSONObjectNullKey() throws JSONException {
345        JSONArray keys = new JSONArray();
346        keys.put(JSONObject.NULL);
347        JSONArray values = new JSONArray();
348        values.put(5.5d);
349        JSONObject object = values.toJSONObject(keys);
350        assertEquals(1, object.length());
351        assertEquals(5.5d, object.get("null"));
352    }
353
354    public void testPutUnsupportedNumbers() throws JSONException {
355        JSONArray array = new JSONArray();
356
357        try {
358            array.put(Double.NaN);
359            fail();
360        } catch (JSONException e) {
361        }
362        try {
363            array.put(0, Double.NEGATIVE_INFINITY);
364            fail();
365        } catch (JSONException e) {
366        }
367        try {
368            array.put(0, Double.POSITIVE_INFINITY);
369            fail();
370        } catch (JSONException e) {
371        }
372    }
373
374    public void testPutUnsupportedNumbersAsObject() throws JSONException {
375        JSONArray array = new JSONArray();
376        array.put(Double.valueOf(Double.NaN));
377        array.put(Double.valueOf(Double.NEGATIVE_INFINITY));
378        array.put(Double.valueOf(Double.POSITIVE_INFINITY));
379        assertEquals(null, array.toString());
380    }
381
382    /**
383     * Although JSONArray is usually defensive about which numbers it accepts,
384     * it doesn't check inputs in its constructor.
385     */
386    public void testCreateWithUnsupportedNumbers() throws JSONException {
387        JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN));
388        assertEquals(2, array.length());
389        assertEquals(5.5, array.getDouble(0));
390        assertEquals(Double.NaN, array.getDouble(1));
391    }
392
393    public void testToStringWithUnsupportedNumbers() throws JSONException {
394        // when the array contains an unsupported number, toString returns null!
395        JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN));
396        assertNull(array.toString());
397    }
398
399    public void testListConstructorCopiesContents() throws JSONException {
400        List<Object> contents = Arrays.<Object>asList(5);
401        JSONArray array = new JSONArray(contents);
402        contents.set(0, 10);
403        assertEquals(5, array.get(0));
404    }
405
406    public void testTokenerConstructor() throws JSONException {
407        JSONArray object = new JSONArray(new JSONTokener("[false]"));
408        assertEquals(1, object.length());
409        assertEquals(false, object.get(0));
410    }
411
412    public void testTokenerConstructorWrongType() throws JSONException {
413        try {
414            new JSONArray(new JSONTokener("{\"foo\": false}"));
415            fail();
416        } catch (JSONException e) {
417        }
418    }
419
420    public void testTokenerConstructorNull() throws JSONException {
421        try {
422            new JSONArray((JSONTokener) null);
423            fail();
424        } catch (NullPointerException e) {
425        }
426    }
427
428    public void testTokenerConstructorParseFail() {
429        try {
430            new JSONArray(new JSONTokener("["));
431            fail();
432        } catch (JSONException e) {
433        } catch (StackOverflowError e) {
434            fail("Stack overflowed on input: \"[\"");
435        }
436    }
437
438    public void testStringConstructor() throws JSONException {
439        JSONArray object = new JSONArray("[false]");
440        assertEquals(1, object.length());
441        assertEquals(false, object.get(0));
442    }
443
444    public void testStringConstructorWrongType() throws JSONException {
445        try {
446            new JSONArray("{\"foo\": false}");
447            fail();
448        } catch (JSONException e) {
449        }
450    }
451
452    public void testStringConstructorNull() throws JSONException {
453        try {
454            new JSONArray((String) null);
455            fail();
456        } catch (NullPointerException e) {
457        }
458    }
459
460    public void testStringConstructorParseFail() {
461        try {
462            new JSONArray("[");
463            fail();
464        } catch (JSONException e) {
465        } catch (StackOverflowError e) {
466            fail("Stack overflowed on input: \"[\"");
467        }
468    }
469
470    public void testCreate() throws JSONException {
471        JSONArray array = new JSONArray(Arrays.asList(5.5, true));
472        assertEquals(2, array.length());
473        assertEquals(5.5, array.getDouble(0));
474        assertEquals(true, array.get(1));
475        assertEquals("[5.5,true]", array.toString());
476    }
477
478    public void testAccessOutOfBounds() throws JSONException {
479        JSONArray array = new JSONArray();
480        array.put("foo");
481        assertEquals(null, array.opt(3));
482        assertEquals(null, array.opt(-3));
483        assertEquals("", array.optString(3));
484        assertEquals("", array.optString(-3));
485        try {
486            array.get(3);
487            fail();
488        } catch (JSONException e) {
489        }
490        try {
491            array.get(-3);
492            fail();
493        } catch (JSONException e) {
494        }
495        try {
496            array.getString(3);
497            fail();
498        } catch (JSONException e) {
499        }
500        try {
501            array.getString(-3);
502            fail();
503        } catch (JSONException e) {
504        }
505    }
506}
507