| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.json; |
| |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import junit.framework.TestCase; |
| |
| /** |
| * This black box test was written without inspecting the non-free org.json sourcecode. |
| */ |
| public class JSONArrayTest extends TestCase { |
| |
| public void testEmptyArray() throws JSONException { |
| JSONArray array = new JSONArray(); |
| assertEquals(0, array.length()); |
| assertEquals("", array.join(" AND ")); |
| try { |
| array.get(0); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.getBoolean(0); |
| fail(); |
| } catch (JSONException e) { |
| } |
| |
| assertEquals("[]", array.toString()); |
| assertEquals("[]", array.toString(4)); |
| |
| // out of bounds is co-opted with defaulting |
| assertTrue(array.isNull(0)); |
| assertNull(array.opt(0)); |
| assertFalse(array.optBoolean(0)); |
| assertTrue(array.optBoolean(0, true)); |
| |
| // bogus (but documented) behaviour: returns null rather than an empty object! |
| assertNull(array.toJSONObject(new JSONArray())); |
| } |
| |
| public void testEqualsAndHashCode() throws JSONException { |
| JSONArray a = new JSONArray(); |
| JSONArray b = new JSONArray(); |
| assertTrue(a.equals(b)); |
| assertEquals("equals() not consistent with hashCode()", a.hashCode(), b.hashCode()); |
| |
| a.put(true); |
| a.put(false); |
| b.put(true); |
| b.put(false); |
| assertTrue(a.equals(b)); |
| assertEquals(a.hashCode(), b.hashCode()); |
| |
| b.put(true); |
| assertFalse(a.equals(b)); |
| assertTrue(a.hashCode() != b.hashCode()); |
| } |
| |
| public void testBooleans() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put(true); |
| array.put(false); |
| array.put(2, false); |
| array.put(3, false); |
| array.put(2, true); |
| assertEquals("[true,false,true,false]", array.toString()); |
| assertEquals(4, array.length()); |
| assertEquals(Boolean.TRUE, array.get(0)); |
| assertEquals(Boolean.FALSE, array.get(1)); |
| assertEquals(Boolean.TRUE, array.get(2)); |
| assertEquals(Boolean.FALSE, array.get(3)); |
| assertFalse(array.isNull(0)); |
| assertFalse(array.isNull(1)); |
| assertFalse(array.isNull(2)); |
| assertFalse(array.isNull(3)); |
| assertEquals(true, array.optBoolean(0)); |
| assertEquals(false, array.optBoolean(1, true)); |
| assertEquals(true, array.optBoolean(2, false)); |
| assertEquals(false, array.optBoolean(3)); |
| assertEquals("true", array.getString(0)); |
| assertEquals("false", array.getString(1)); |
| assertEquals("true", array.optString(2)); |
| assertEquals("false", array.optString(3, "x")); |
| assertEquals("[\n true,\n false,\n true,\n false\n]", array.toString(5)); |
| |
| JSONArray other = new JSONArray(); |
| other.put(true); |
| other.put(false); |
| other.put(true); |
| other.put(false); |
| assertTrue(array.equals(other)); |
| other.put(true); |
| assertFalse(array.equals(other)); |
| |
| other = new JSONArray(); |
| other.put("true"); |
| other.put("false"); |
| other.put("truE"); |
| other.put("FALSE"); |
| assertFalse(array.equals(other)); |
| assertFalse(other.equals(array)); |
| assertEquals(true, other.getBoolean(0)); |
| assertEquals(false, other.optBoolean(1, true)); |
| assertEquals(true, other.optBoolean(2)); |
| assertEquals(false, other.getBoolean(3)); |
| } |
| |
| // http://code.google.com/p/android/issues/detail?id=16411 |
| public void testCoerceStringToBoolean() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put("maybe"); |
| try { |
| array.getBoolean(0); |
| fail(); |
| } catch (JSONException expected) { |
| } |
| assertEquals(false, array.optBoolean(0)); |
| assertEquals(true, array.optBoolean(0, true)); |
| } |
| |
| public void testNulls() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put(3, null); |
| array.put(0, JSONObject.NULL); |
| assertEquals(4, array.length()); |
| assertEquals("[null,null,null,null]", array.toString()); |
| |
| // there's 2 ways to represent null; each behaves differently! |
| assertEquals(JSONObject.NULL, array.get(0)); |
| try { |
| array.get(1); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.get(2); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.get(3); |
| fail(); |
| } catch (JSONException e) { |
| } |
| assertEquals(JSONObject.NULL, array.opt(0)); |
| assertEquals(null, array.opt(1)); |
| assertEquals(null, array.opt(2)); |
| assertEquals(null, array.opt(3)); |
| assertTrue(array.isNull(0)); |
| assertTrue(array.isNull(1)); |
| assertTrue(array.isNull(2)); |
| assertTrue(array.isNull(3)); |
| assertEquals("null", array.optString(0)); |
| assertEquals("", array.optString(1)); |
| assertEquals("", array.optString(2)); |
| assertEquals("", array.optString(3)); |
| } |
| |
| /** |
| * Our behaviour is questioned by this bug: |
| * http://code.google.com/p/android/issues/detail?id=7257 |
| */ |
| public void testParseNullYieldsJSONObjectNull() throws JSONException { |
| JSONArray array = new JSONArray("[\"null\",null]"); |
| array.put(null); |
| assertEquals("null", array.get(0)); |
| assertEquals(JSONObject.NULL, array.get(1)); |
| try { |
| array.get(2); |
| fail(); |
| } catch (JSONException e) { |
| } |
| assertEquals("null", array.getString(0)); |
| assertEquals("null", array.getString(1)); |
| try { |
| array.getString(2); |
| fail(); |
| } catch (JSONException e) { |
| } |
| } |
| |
| public void testNumbers() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put(Double.MIN_VALUE); |
| array.put(9223372036854775806L); |
| array.put(Double.MAX_VALUE); |
| array.put(-0d); |
| assertEquals(4, array.length()); |
| |
| // toString() and getString(int) return different values for -0d |
| assertEquals("[4.9E-324,9223372036854775806,1.7976931348623157E308,-0]", array.toString()); |
| |
| assertEquals(Double.MIN_VALUE, array.get(0)); |
| assertEquals(9223372036854775806L, array.get(1)); |
| assertEquals(Double.MAX_VALUE, array.get(2)); |
| assertEquals(-0d, array.get(3)); |
| assertEquals(Double.MIN_VALUE, array.getDouble(0)); |
| assertEquals(9.223372036854776E18, array.getDouble(1)); |
| assertEquals(Double.MAX_VALUE, array.getDouble(2)); |
| assertEquals(-0d, array.getDouble(3)); |
| assertEquals(0, array.getLong(0)); |
| assertEquals(9223372036854775806L, array.getLong(1)); |
| assertEquals(Long.MAX_VALUE, array.getLong(2)); |
| assertEquals(0, array.getLong(3)); |
| assertEquals(0, array.getInt(0)); |
| assertEquals(-2, array.getInt(1)); |
| assertEquals(Integer.MAX_VALUE, array.getInt(2)); |
| assertEquals(0, array.getInt(3)); |
| assertEquals(Double.MIN_VALUE, array.opt(0)); |
| assertEquals(Double.MIN_VALUE, array.optDouble(0)); |
| assertEquals(0, array.optLong(0, 1L)); |
| assertEquals(0, array.optInt(0, 1)); |
| assertEquals("4.9E-324", array.getString(0)); |
| assertEquals("9223372036854775806", array.getString(1)); |
| assertEquals("1.7976931348623157E308", array.getString(2)); |
| assertEquals("-0.0", array.getString(3)); |
| |
| JSONArray other = new JSONArray(); |
| other.put(Double.MIN_VALUE); |
| other.put(9223372036854775806L); |
| other.put(Double.MAX_VALUE); |
| other.put(-0d); |
| assertTrue(array.equals(other)); |
| other.put(0, 0L); |
| assertFalse(array.equals(other)); |
| } |
| |
| public void testStrings() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put("true"); |
| array.put("5.5"); |
| array.put("9223372036854775806"); |
| array.put("null"); |
| array.put("5\"8' tall"); |
| assertEquals(5, array.length()); |
| assertEquals("[\"true\",\"5.5\",\"9223372036854775806\",\"null\",\"5\\\"8' tall\"]", |
| array.toString()); |
| |
| // although the documentation doesn't mention it, join() escapes text and wraps |
| // strings in quotes |
| assertEquals("\"true\" \"5.5\" \"9223372036854775806\" \"null\" \"5\\\"8' tall\"", |
| array.join(" ")); |
| |
| assertEquals("true", array.get(0)); |
| assertEquals("null", array.getString(3)); |
| assertEquals("5\"8' tall", array.getString(4)); |
| assertEquals("true", array.opt(0)); |
| assertEquals("5.5", array.optString(1)); |
| assertEquals("9223372036854775806", array.optString(2, null)); |
| assertEquals("null", array.optString(3, "-1")); |
| assertFalse(array.isNull(0)); |
| assertFalse(array.isNull(3)); |
| |
| assertEquals(true, array.getBoolean(0)); |
| assertEquals(true, array.optBoolean(0)); |
| assertEquals(true, array.optBoolean(0, false)); |
| assertEquals(0, array.optInt(0)); |
| assertEquals(-2, array.optInt(0, -2)); |
| |
| assertEquals(5.5d, array.getDouble(1)); |
| assertEquals(5L, array.getLong(1)); |
| assertEquals(5, array.getInt(1)); |
| assertEquals(5, array.optInt(1, 3)); |
| |
| // The last digit of the string is a 6 but getLong returns a 7. It's probably parsing as a |
| // double and then converting that to a long. This is consistent with JavaScript. |
| assertEquals(9223372036854775807L, array.getLong(2)); |
| assertEquals(9.223372036854776E18, array.getDouble(2)); |
| assertEquals(Integer.MAX_VALUE, array.getInt(2)); |
| |
| assertFalse(array.isNull(3)); |
| try { |
| array.getDouble(3); |
| fail(); |
| } catch (JSONException e) { |
| } |
| assertEquals(Double.NaN, array.optDouble(3)); |
| assertEquals(-1.0d, array.optDouble(3, -1.0d)); |
| } |
| |
| public void testJoin() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put(null); |
| assertEquals("null", array.join(" & ")); |
| array.put("\""); |
| assertEquals("null & \"\\\"\"", array.join(" & ")); |
| array.put(5); |
| assertEquals("null & \"\\\"\" & 5", array.join(" & ")); |
| array.put(true); |
| assertEquals("null & \"\\\"\" & 5 & true", array.join(" & ")); |
| array.put(new JSONArray(Arrays.asList(true, false))); |
| assertEquals("null & \"\\\"\" & 5 & true & [true,false]", array.join(" & ")); |
| array.put(new JSONObject(Collections.singletonMap("x", 6))); |
| assertEquals("null & \"\\\"\" & 5 & true & [true,false] & {\"x\":6}", array.join(" & ")); |
| } |
| |
| public void testJoinWithNull() throws JSONException { |
| JSONArray array = new JSONArray(Arrays.asList(5, 6)); |
| assertEquals("5null6", array.join(null)); |
| } |
| |
| public void testJoinWithSpecialCharacters() throws JSONException { |
| JSONArray array = new JSONArray(Arrays.asList(5, 6)); |
| assertEquals("5\"6", array.join("\"")); |
| } |
| |
| public void testToJSONObject() throws JSONException { |
| JSONArray keys = new JSONArray(); |
| keys.put("a"); |
| keys.put("b"); |
| |
| JSONArray values = new JSONArray(); |
| values.put(5.5d); |
| values.put(false); |
| |
| JSONObject object = values.toJSONObject(keys); |
| assertEquals(5.5d, object.get("a")); |
| assertEquals(false, object.get("b")); |
| |
| keys.put(0, "a"); |
| values.put(0, 11.0d); |
| assertEquals(5.5d, object.get("a")); |
| } |
| |
| public void testToJSONObjectWithNulls() throws JSONException { |
| JSONArray keys = new JSONArray(); |
| keys.put("a"); |
| keys.put("b"); |
| |
| JSONArray values = new JSONArray(); |
| values.put(5.5d); |
| values.put(null); |
| |
| // null values are stripped! |
| JSONObject object = values.toJSONObject(keys); |
| assertEquals(1, object.length()); |
| assertFalse(object.has("b")); |
| assertEquals("{\"a\":5.5}", object.toString()); |
| } |
| |
| public void testToJSONObjectMoreNamesThanValues() throws JSONException { |
| JSONArray keys = new JSONArray(); |
| keys.put("a"); |
| keys.put("b"); |
| JSONArray values = new JSONArray(); |
| values.put(5.5d); |
| JSONObject object = values.toJSONObject(keys); |
| assertEquals(1, object.length()); |
| assertEquals(5.5d, object.get("a")); |
| } |
| |
| public void testToJSONObjectMoreValuesThanNames() throws JSONException { |
| JSONArray keys = new JSONArray(); |
| keys.put("a"); |
| JSONArray values = new JSONArray(); |
| values.put(5.5d); |
| values.put(11.0d); |
| JSONObject object = values.toJSONObject(keys); |
| assertEquals(1, object.length()); |
| assertEquals(5.5d, object.get("a")); |
| } |
| |
| public void testToJSONObjectNullKey() throws JSONException { |
| JSONArray keys = new JSONArray(); |
| keys.put(JSONObject.NULL); |
| JSONArray values = new JSONArray(); |
| values.put(5.5d); |
| JSONObject object = values.toJSONObject(keys); |
| assertEquals(1, object.length()); |
| assertEquals(5.5d, object.get("null")); |
| } |
| |
| public void testPutUnsupportedNumbers() throws JSONException { |
| JSONArray array = new JSONArray(); |
| |
| try { |
| array.put(Double.NaN); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.put(0, Double.NEGATIVE_INFINITY); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.put(0, Double.POSITIVE_INFINITY); |
| fail(); |
| } catch (JSONException e) { |
| } |
| } |
| |
| public void testPutUnsupportedNumbersAsObject() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put(Double.valueOf(Double.NaN)); |
| array.put(Double.valueOf(Double.NEGATIVE_INFINITY)); |
| array.put(Double.valueOf(Double.POSITIVE_INFINITY)); |
| assertEquals(null, array.toString()); |
| } |
| |
| /** |
| * Although JSONArray is usually defensive about which numbers it accepts, |
| * it doesn't check inputs in its constructor. |
| */ |
| public void testCreateWithUnsupportedNumbers() throws JSONException { |
| JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN)); |
| assertEquals(2, array.length()); |
| assertEquals(5.5, array.getDouble(0)); |
| assertEquals(Double.NaN, array.getDouble(1)); |
| } |
| |
| public void testToStringWithUnsupportedNumbers() throws JSONException { |
| // when the array contains an unsupported number, toString returns null! |
| JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN)); |
| assertNull(array.toString()); |
| } |
| |
| public void testListConstructorCopiesContents() throws JSONException { |
| List<Object> contents = Arrays.<Object>asList(5); |
| JSONArray array = new JSONArray(contents); |
| contents.set(0, 10); |
| assertEquals(5, array.get(0)); |
| } |
| |
| public void testTokenerConstructor() throws JSONException { |
| JSONArray object = new JSONArray(new JSONTokener("[false]")); |
| assertEquals(1, object.length()); |
| assertEquals(false, object.get(0)); |
| } |
| |
| public void testTokenerConstructorWrongType() throws JSONException { |
| try { |
| new JSONArray(new JSONTokener("{\"foo\": false}")); |
| fail(); |
| } catch (JSONException e) { |
| } |
| } |
| |
| public void testTokenerConstructorNull() throws JSONException { |
| try { |
| new JSONArray((JSONTokener) null); |
| fail(); |
| } catch (NullPointerException e) { |
| } |
| } |
| |
| public void testTokenerConstructorParseFail() { |
| try { |
| new JSONArray(new JSONTokener("[")); |
| fail(); |
| } catch (JSONException e) { |
| } catch (StackOverflowError e) { |
| fail("Stack overflowed on input: \"[\""); |
| } |
| } |
| |
| public void testStringConstructor() throws JSONException { |
| JSONArray object = new JSONArray("[false]"); |
| assertEquals(1, object.length()); |
| assertEquals(false, object.get(0)); |
| } |
| |
| public void testStringConstructorWrongType() throws JSONException { |
| try { |
| new JSONArray("{\"foo\": false}"); |
| fail(); |
| } catch (JSONException e) { |
| } |
| } |
| |
| public void testStringConstructorNull() throws JSONException { |
| try { |
| new JSONArray((String) null); |
| fail(); |
| } catch (NullPointerException e) { |
| } |
| } |
| |
| public void testStringConstructorParseFail() { |
| try { |
| new JSONArray("["); |
| fail(); |
| } catch (JSONException e) { |
| } catch (StackOverflowError e) { |
| fail("Stack overflowed on input: \"[\""); |
| } |
| } |
| |
| public void testCreate() throws JSONException { |
| JSONArray array = new JSONArray(Arrays.asList(5.5, true)); |
| assertEquals(2, array.length()); |
| assertEquals(5.5, array.getDouble(0)); |
| assertEquals(true, array.get(1)); |
| assertEquals("[5.5,true]", array.toString()); |
| } |
| |
| public void testAccessOutOfBounds() throws JSONException { |
| JSONArray array = new JSONArray(); |
| array.put("foo"); |
| assertEquals(null, array.opt(3)); |
| assertEquals(null, array.opt(-3)); |
| assertEquals("", array.optString(3)); |
| assertEquals("", array.optString(-3)); |
| try { |
| array.get(3); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.get(-3); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.getString(3); |
| fail(); |
| } catch (JSONException e) { |
| } |
| try { |
| array.getString(-3); |
| fail(); |
| } catch (JSONException e) { |
| } |
| } |
| } |