• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 java.util.Arrays;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.List;
23 import junit.framework.TestCase;
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 
testEmptyArray()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 
testEqualsAndHashCode()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 
testBooleans()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     // http://code.google.com/p/android/issues/detail?id=16411
testCoerceStringToBoolean()126     public void testCoerceStringToBoolean() throws JSONException {
127         JSONArray array = new JSONArray();
128         array.put("maybe");
129         try {
130             array.getBoolean(0);
131             fail();
132         } catch (JSONException expected) {
133         }
134         assertEquals(false, array.optBoolean(0));
135         assertEquals(true, array.optBoolean(0, true));
136     }
137 
testNulls()138     public void testNulls() throws JSONException {
139         JSONArray array = new JSONArray();
140         array.put(3, (Collection) null);
141         array.put(0, JSONObject.NULL);
142         assertEquals(4, array.length());
143         assertEquals("[null,null,null,null]", array.toString());
144 
145         // there's 2 ways to represent null; each behaves differently!
146         assertEquals(JSONObject.NULL, array.get(0));
147         try {
148             array.get(1);
149             fail();
150         } catch (JSONException e) {
151         }
152         try {
153             array.get(2);
154             fail();
155         } catch (JSONException e) {
156         }
157         try {
158             array.get(3);
159             fail();
160         } catch (JSONException e) {
161         }
162         assertEquals(JSONObject.NULL, array.opt(0));
163         assertEquals(null, array.opt(1));
164         assertEquals(null, array.opt(2));
165         assertEquals(null, array.opt(3));
166         assertTrue(array.isNull(0));
167         assertTrue(array.isNull(1));
168         assertTrue(array.isNull(2));
169         assertTrue(array.isNull(3));
170         assertEquals("null", array.optString(0));
171         assertEquals("", array.optString(1));
172         assertEquals("", array.optString(2));
173         assertEquals("", array.optString(3));
174     }
175 
176     /**
177      * Our behaviour is questioned by this bug:
178      * http://code.google.com/p/android/issues/detail?id=7257
179      */
testParseNullYieldsJSONObjectNull()180     public void testParseNullYieldsJSONObjectNull() throws JSONException {
181         JSONArray array = new JSONArray("[\"null\",null]");
182         array.put((Collection) null);
183         assertEquals("null", array.get(0));
184         assertEquals(JSONObject.NULL, array.get(1));
185         try {
186             array.get(2);
187             fail();
188         } catch (JSONException e) {
189         }
190         assertEquals("null", array.getString(0));
191         assertEquals("null", array.getString(1));
192         try {
193             array.getString(2);
194             fail();
195         } catch (JSONException e) {
196         }
197     }
198 
testNumbers()199     public void testNumbers() throws JSONException {
200         JSONArray array = new JSONArray();
201         array.put(Double.MIN_VALUE);
202         array.put(9223372036854775806L);
203         array.put(Double.MAX_VALUE);
204         array.put(-0d);
205         assertEquals(4, array.length());
206 
207         // toString() and getString(int) return different values for -0d
208         assertEquals("[4.9E-324,9223372036854775806,1.7976931348623157E308,-0]", array.toString());
209 
210         assertEquals(Double.MIN_VALUE, array.get(0));
211         assertEquals(9223372036854775806L, array.get(1));
212         assertEquals(Double.MAX_VALUE, array.get(2));
213         assertEquals(-0d, array.get(3));
214         assertEquals(Double.MIN_VALUE, array.getDouble(0));
215         assertEquals(9.223372036854776E18, array.getDouble(1));
216         assertEquals(Double.MAX_VALUE, array.getDouble(2));
217         assertEquals(-0d, array.getDouble(3));
218         assertEquals(0, array.getLong(0));
219         assertEquals(9223372036854775806L, array.getLong(1));
220         assertEquals(Long.MAX_VALUE, array.getLong(2));
221         assertEquals(0, array.getLong(3));
222         assertEquals(0, array.getInt(0));
223         assertEquals(-2, array.getInt(1));
224         assertEquals(Integer.MAX_VALUE, array.getInt(2));
225         assertEquals(0, array.getInt(3));
226         assertEquals(Double.MIN_VALUE, array.opt(0));
227         assertEquals(Double.MIN_VALUE, array.optDouble(0));
228         assertEquals(0, array.optLong(0, 1L));
229         assertEquals(0, array.optInt(0, 1));
230         assertEquals("4.9E-324", array.getString(0));
231         assertEquals("9223372036854775806", array.getString(1));
232         assertEquals("1.7976931348623157E308", array.getString(2));
233         assertEquals("-0.0", array.getString(3));
234 
235         JSONArray other = new JSONArray();
236         other.put(Double.MIN_VALUE);
237         other.put(9223372036854775806L);
238         other.put(Double.MAX_VALUE);
239         other.put(-0d);
240         assertTrue(array.equals(other));
241         other.put(0, 0L);
242         assertFalse(array.equals(other));
243     }
244 
testStrings()245     public void testStrings() throws JSONException {
246         JSONArray array = new JSONArray();
247         array.put("true");
248         array.put("5.5");
249         array.put("9223372036854775806");
250         array.put("null");
251         array.put("5\"8' tall");
252         assertEquals(5, array.length());
253         assertEquals("[\"true\",\"5.5\",\"9223372036854775806\",\"null\",\"5\\\"8' tall\"]",
254                 array.toString());
255 
256         // although the documentation doesn't mention it, join() escapes text and wraps
257         // strings in quotes
258         assertEquals("\"true\" \"5.5\" \"9223372036854775806\" \"null\" \"5\\\"8' tall\"",
259                 array.join(" "));
260 
261         assertEquals("true", array.get(0));
262         assertEquals("null", array.getString(3));
263         assertEquals("5\"8' tall", array.getString(4));
264         assertEquals("true", array.opt(0));
265         assertEquals("5.5", array.optString(1));
266         assertEquals("9223372036854775806", array.optString(2, null));
267         assertEquals("null", array.optString(3, "-1"));
268         assertFalse(array.isNull(0));
269         assertFalse(array.isNull(3));
270 
271         assertEquals(true, array.getBoolean(0));
272         assertEquals(true, array.optBoolean(0));
273         assertEquals(true, array.optBoolean(0, false));
274         assertEquals(0, array.optInt(0));
275         assertEquals(-2, array.optInt(0, -2));
276 
277         assertEquals(5.5d, array.getDouble(1));
278         assertEquals(5L, array.getLong(1));
279         assertEquals(5, array.getInt(1));
280         assertEquals(5, array.optInt(1, 3));
281 
282         // The last digit of the string is a 6 but getLong returns a 7. It's probably parsing as a
283         // double and then converting that to a long. This is consistent with JavaScript.
284         assertEquals(9223372036854775807L, array.getLong(2));
285         assertEquals(9.223372036854776E18, array.getDouble(2));
286         assertEquals(Integer.MAX_VALUE, array.getInt(2));
287 
288         assertFalse(array.isNull(3));
289         try {
290             array.getDouble(3);
291             fail();
292         } catch (JSONException e) {
293         }
294         assertEquals(Double.NaN, array.optDouble(3));
295         assertEquals(-1.0d, array.optDouble(3, -1.0d));
296     }
297 
testJoin()298     public void testJoin() throws JSONException {
299         JSONArray array = new JSONArray();
300         array.put((Collection) null);
301         assertEquals("null", array.join(" & "));
302         array.put("\"");
303         assertEquals("null & \"\\\"\"", array.join(" & "));
304         array.put(5);
305         assertEquals("null & \"\\\"\" & 5", array.join(" & "));
306         array.put(true);
307         assertEquals("null & \"\\\"\" & 5 & true", array.join(" & "));
308         array.put(new JSONArray(Arrays.asList(true, false)));
309         assertEquals("null & \"\\\"\" & 5 & true & [true,false]", array.join(" & "));
310         array.put(new JSONObject(Collections.singletonMap("x", 6)));
311         assertEquals("null & \"\\\"\" & 5 & true & [true,false] & {\"x\":6}", array.join(" & "));
312     }
313 
testJoinWithNull()314     public void testJoinWithNull() throws JSONException {
315         JSONArray array = new JSONArray(Arrays.asList(5, 6));
316         assertEquals("5null6", array.join(null));
317     }
318 
testJoinWithSpecialCharacters()319     public void testJoinWithSpecialCharacters() throws JSONException {
320         JSONArray array = new JSONArray(Arrays.asList(5, 6));
321         assertEquals("5\"6", array.join("\""));
322     }
323 
testToJSONObject()324     public void testToJSONObject() throws JSONException {
325         JSONArray keys = new JSONArray();
326         keys.put("a");
327         keys.put("b");
328 
329         JSONArray values = new JSONArray();
330         values.put(5.5d);
331         values.put(false);
332 
333         JSONObject object = values.toJSONObject(keys);
334         assertEquals(5.5d, object.get("a"));
335         assertEquals(false, object.get("b"));
336 
337         keys.put(0, "a");
338         values.put(0, 11.0d);
339         assertEquals(5.5d, object.get("a"));
340     }
341 
testToJSONObjectWithNulls()342     public void testToJSONObjectWithNulls() throws JSONException {
343         JSONArray keys = new JSONArray();
344         keys.put("a");
345         keys.put("b");
346 
347         JSONArray values = new JSONArray();
348         values.put(5.5d);
349         values.put((Collection) null);
350 
351         // null values are stripped!
352         JSONObject object = values.toJSONObject(keys);
353         assertEquals(1, object.length());
354         assertFalse(object.has("b"));
355         assertEquals("{\"a\":5.5}", object.toString());
356     }
357 
testToJSONObjectMoreNamesThanValues()358     public void testToJSONObjectMoreNamesThanValues() throws JSONException {
359         JSONArray keys = new JSONArray();
360         keys.put("a");
361         keys.put("b");
362         JSONArray values = new JSONArray();
363         values.put(5.5d);
364         JSONObject object = values.toJSONObject(keys);
365         assertEquals(1, object.length());
366         assertEquals(5.5d, object.get("a"));
367     }
368 
testToJSONObjectMoreValuesThanNames()369     public void testToJSONObjectMoreValuesThanNames() throws JSONException {
370         JSONArray keys = new JSONArray();
371         keys.put("a");
372         JSONArray values = new JSONArray();
373         values.put(5.5d);
374         values.put(11.0d);
375         JSONObject object = values.toJSONObject(keys);
376         assertEquals(1, object.length());
377         assertEquals(5.5d, object.get("a"));
378     }
379 
testToJSONObjectNullKey()380     public void testToJSONObjectNullKey() throws JSONException {
381         JSONArray keys = new JSONArray();
382         keys.put(JSONObject.NULL);
383         JSONArray values = new JSONArray();
384         values.put(5.5d);
385         JSONObject object = values.toJSONObject(keys);
386         assertEquals(1, object.length());
387         assertEquals(5.5d, object.get("null"));
388     }
389 
testPutUnsupportedNumbers()390     public void testPutUnsupportedNumbers() throws JSONException {
391         JSONArray array = new JSONArray();
392 
393         try {
394             array.put(Double.NaN);
395             fail();
396         } catch (JSONException e) {
397         }
398         try {
399             array.put(0, Double.NEGATIVE_INFINITY);
400             fail();
401         } catch (JSONException e) {
402         }
403         try {
404             array.put(0, Double.POSITIVE_INFINITY);
405             fail();
406         } catch (JSONException e) {
407         }
408     }
409 
testPutUnsupportedNumbersAsObject()410     public void testPutUnsupportedNumbersAsObject() throws JSONException {
411         JSONArray array = new JSONArray();
412         array.put(Double.valueOf(Double.NaN));
413         array.put(Double.valueOf(Double.NEGATIVE_INFINITY));
414         array.put(Double.valueOf(Double.POSITIVE_INFINITY));
415         assertEquals(null, array.toString());
416     }
417 
418     /**
419      * Although JSONArray is usually defensive about which numbers it accepts,
420      * it doesn't check inputs in its constructor.
421      */
testCreateWithUnsupportedNumbers()422     public void testCreateWithUnsupportedNumbers() throws JSONException {
423         JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN));
424         assertEquals(2, array.length());
425         assertEquals(5.5, array.getDouble(0));
426         assertEquals(Double.NaN, array.getDouble(1));
427     }
428 
testToStringWithUnsupportedNumbers()429     public void testToStringWithUnsupportedNumbers() throws JSONException {
430         // when the array contains an unsupported number, toString returns null!
431         JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN));
432         assertNull(array.toString());
433     }
434 
testListConstructorCopiesContents()435     public void testListConstructorCopiesContents() throws JSONException {
436         List<Object> contents = Arrays.<Object>asList(5);
437         JSONArray array = new JSONArray(contents);
438         contents.set(0, 10);
439         assertEquals(5, array.get(0));
440     }
441 
testTokenerConstructor()442     public void testTokenerConstructor() throws JSONException {
443         JSONArray object = new JSONArray(new JSONTokener("[false]"));
444         assertEquals(1, object.length());
445         assertEquals(false, object.get(0));
446     }
447 
testTokenerConstructorWrongType()448     public void testTokenerConstructorWrongType() throws JSONException {
449         try {
450             new JSONArray(new JSONTokener("{\"foo\": false}"));
451             fail();
452         } catch (JSONException e) {
453         }
454     }
455 
testTokenerConstructorNull()456     public void testTokenerConstructorNull() throws JSONException {
457         try {
458             new JSONArray((JSONTokener) null);
459             fail();
460         } catch (NullPointerException e) {
461         }
462     }
463 
testTokenerConstructorParseFail()464     public void testTokenerConstructorParseFail() {
465         try {
466             new JSONArray(new JSONTokener("["));
467             fail();
468         } catch (JSONException e) {
469         } catch (StackOverflowError e) {
470             fail("Stack overflowed on input: \"[\"");
471         }
472     }
473 
testStringConstructor()474     public void testStringConstructor() throws JSONException {
475         JSONArray object = new JSONArray("[false]");
476         assertEquals(1, object.length());
477         assertEquals(false, object.get(0));
478     }
479 
testStringConstructorWrongType()480     public void testStringConstructorWrongType() throws JSONException {
481         try {
482             new JSONArray("{\"foo\": false}");
483             fail();
484         } catch (JSONException e) {
485         }
486     }
487 
testStringConstructorNull()488     public void testStringConstructorNull() throws JSONException {
489         try {
490             new JSONArray((String) null);
491             fail();
492         } catch (NullPointerException e) {
493         }
494     }
495 
testStringConstructorParseFail()496     public void testStringConstructorParseFail() {
497         try {
498             new JSONArray("[");
499             fail();
500         } catch (JSONException e) {
501         } catch (StackOverflowError e) {
502             fail("Stack overflowed on input: \"[\"");
503         }
504     }
505 
testCreate()506     public void testCreate() throws JSONException {
507         JSONArray array = new JSONArray(Arrays.asList(5.5, true));
508         assertEquals(2, array.length());
509         assertEquals(5.5, array.getDouble(0));
510         assertEquals(true, array.get(1));
511         assertEquals("[5.5,true]", array.toString());
512     }
513 
testAccessOutOfBounds()514     public void testAccessOutOfBounds() throws JSONException {
515         JSONArray array = new JSONArray();
516         array.put("foo");
517         assertEquals(null, array.opt(3));
518         assertEquals(null, array.opt(-3));
519         assertEquals("", array.optString(3));
520         assertEquals("", array.optString(-3));
521         try {
522             array.get(3);
523             fail();
524         } catch (JSONException e) {
525         }
526         try {
527             array.get(-3);
528             fail();
529         } catch (JSONException e) {
530         }
531         try {
532             array.getString(3);
533             fail();
534         } catch (JSONException e) {
535         }
536         try {
537             array.getString(-3);
538             fail();
539         } catch (JSONException e) {
540         }
541     }
542 
test_remove()543     public void test_remove() throws Exception {
544         JSONArray a = new JSONArray();
545         assertEquals(null, a.remove(-1));
546         assertEquals(null, a.remove(0));
547 
548         a.put("hello");
549         assertEquals(null, a.remove(-1));
550         assertEquals(null, a.remove(1));
551         assertEquals("hello", a.remove(0));
552         assertEquals(null, a.remove(0));
553     }
554 
555     enum MyEnum { A, B, C; }
556 
557     // https://code.google.com/p/android/issues/detail?id=62539
testEnums()558     public void testEnums() throws Exception {
559         // This works because it's in java.* and any class in there falls back to toString.
560         JSONArray a1 = new JSONArray(java.lang.annotation.RetentionPolicy.values());
561         assertEquals("[\"SOURCE\",\"CLASS\",\"RUNTIME\"]", a1.toString());
562 
563         // This doesn't because it's not.
564         JSONArray a2 = new JSONArray(MyEnum.values());
565         assertEquals("[null,null,null]", a2.toString());
566     }
567 }
568