summaryrefslogtreecommitdiffstats
path: root/json
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2010-03-09 17:54:35 -0800
committerJesse Wilson <jessewilson@google.com>2010-03-10 10:00:53 -0800
commit53c13031e4b68645b0ca7c7a335aae41d0b84276 (patch)
tree473852c8e9654b0bdaede0d25d5a2f710be6d9e2 /json
parentec02394f92b3ff460543dad5c57bc2ee6474683f (diff)
downloadlibcore-53c13031e4b68645b0ca7c7a335aae41d0b84276.zip
libcore-53c13031e4b68645b0ca7c7a335aae41d0b84276.tar.gz
libcore-53c13031e4b68645b0ca7c7a335aae41d0b84276.tar.bz2
New tests for JSONObject and for JSON's self-use.
Alongside development of these tests, I'm working on a new cleanroom implementation. The self use test was written to prevent me from self-using in a way that the original implementation does not. Change-Id: Ie617aca1978bd39d85b05e5c2c7bd657ed159dd6
Diffstat (limited to 'json')
-rw-r--r--json/src/test/java/org/json/AllTests.java6
-rw-r--r--json/src/test/java/org/json/JSONArrayTest.java83
-rw-r--r--json/src/test/java/org/json/JSONObjectTest.java803
-rw-r--r--json/src/test/java/org/json/JSONStringerTest.java1
-rw-r--r--json/src/test/java/org/json/SelfUseTest.java204
5 files changed, 1090 insertions, 7 deletions
diff --git a/json/src/test/java/org/json/AllTests.java b/json/src/test/java/org/json/AllTests.java
index 8261a4d..ee6c90e 100644
--- a/json/src/test/java/org/json/AllTests.java
+++ b/json/src/test/java/org/json/AllTests.java
@@ -21,10 +21,12 @@ import junit.framework.TestSuite;
public class AllTests {
public static Test suite() {
- TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ TestSuite suite = new TestSuite();
suite.addTestSuite(JSONArrayTest.class);
+ suite.addTestSuite(JSONObjectTest.class);
suite.addTestSuite(JSONStringerTest.class);
- suite.addTestSuite(JSONStringerTest.class);
+ suite.addTestSuite(JSONTokenerTest.class);
+ suite.addTestSuite(SelfUseTest.class);
return suite;
}
}
diff --git a/json/src/test/java/org/json/JSONArrayTest.java b/json/src/test/java/org/json/JSONArrayTest.java
index 34e5ff6..d6013a8 100644
--- a/json/src/test/java/org/json/JSONArrayTest.java
+++ b/json/src/test/java/org/json/JSONArrayTest.java
@@ -19,6 +19,7 @@ package org.json;
import junit.framework.TestCase;
import java.util.Arrays;
+import java.util.List;
/**
* This black box test was written without inspecting the non-free org.json sourcecode.
@@ -131,17 +132,17 @@ public class JSONArrayTest extends TestCase {
// bogus behaviour: there's 2 ways to represent null; each behaves differently!
assertEquals(JSONObject.NULL, array.get(0));
try {
- assertEquals(null, array.get(1));
+ array.get(1);
fail();
} catch (JSONException e) {
}
try {
- assertEquals(null, array.get(2));
+ array.get(2);
fail();
} catch (JSONException e) {
}
try {
- assertEquals(null, array.get(3));
+ array.get(3);
fail();
} catch (JSONException e) {
}
@@ -238,7 +239,7 @@ public class JSONArrayTest extends TestCase {
assertEquals(-2, array.optInt(0, -2));
assertEquals(5.5d, array.getDouble(1));
- assertEquals(5, array.getLong(1));
+ assertEquals(5L, array.getLong(1));
assertEquals(5, array.getInt(1));
assertEquals(5, array.optInt(1, 3));
@@ -285,13 +286,45 @@ public class JSONArrayTest extends TestCase {
values.put(5.5d);
values.put(null);
- // bogus behaviour: null values are stripped
+ // bogus behaviour: 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();
@@ -312,6 +345,10 @@ public class JSONArrayTest extends TestCase {
}
}
+ /**
+ * 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());
@@ -324,6 +361,13 @@ public class JSONArrayTest extends TestCase {
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 testCreate() throws JSONException {
JSONArray array = new JSONArray(Arrays.asList(5.5, true));
@@ -333,6 +377,35 @@ public class JSONArrayTest extends TestCase {
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) {
+ }
+ }
+
public void testParsingConstructor() {
fail("TODO");
}
diff --git a/json/src/test/java/org/json/JSONObjectTest.java b/json/src/test/java/org/json/JSONObjectTest.java
new file mode 100644
index 0000000..83beea8
--- /dev/null
+++ b/json/src/test/java/org/json/JSONObjectTest.java
@@ -0,0 +1,803 @@
+/**
+ * Copyright (C) 2010 Google Inc.
+ *
+ * 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 junit.framework.TestCase;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+/**
+ * This black box test was written without inspecting the non-free org.json sourcecode.
+ */
+public class JSONObjectTest extends TestCase {
+
+ public void testEmptyObject() throws JSONException {
+ JSONObject object = new JSONObject();
+ assertEquals(0, object.length());
+
+ // bogus (but documented) behaviour: returns null rather than the empty object
+ assertNull(object.names());
+
+ // bogus behaviour: returns null rather than an empty array
+ assertNull(object.toJSONArray(new JSONArray()));
+ assertEquals("{}", object.toString());
+ assertEquals("{}", object.toString(5));
+ try {
+ object.get("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getBoolean("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getDouble("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getInt("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getJSONArray("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getJSONObject("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getLong("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getString("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ assertFalse(object.has("foo"));
+ assertTrue(object.isNull("foo")); // isNull also means "is not present"
+ assertNull(object.opt("foo"));
+ assertEquals(false, object.optBoolean("foo"));
+ assertEquals(true, object.optBoolean("foo", true));
+ assertEquals(Double.NaN, object.optDouble("foo"));
+ assertEquals(5.0, object.optDouble("foo", 5.0));
+ assertEquals(0, object.optInt("foo"));
+ assertEquals(5, object.optInt("foo", 5));
+ assertEquals(null, object.optJSONArray("foo"));
+ assertEquals(null, object.optJSONObject("foo"));
+ assertEquals(0, object.optLong("foo"));
+ assertEquals(Long.MAX_VALUE-1, object.optLong("foo", Long.MAX_VALUE-1));
+ assertEquals("", object.optString("foo")); // empty string is default!
+ assertEquals("bar", object.optString("foo", "bar"));
+ assertNull(object.remove("foo"));
+ }
+
+ public void testEqualsAndHashCode() throws JSONException {
+ JSONObject a = new JSONObject();
+ JSONObject b = new JSONObject();
+
+ // JSON object doesn't override either equals or hashCode (!)
+ assertFalse(a.equals(b));
+ assertEquals(a.hashCode(), System.identityHashCode(a));
+ }
+
+ public void testGet() throws JSONException {
+ JSONObject object = new JSONObject();
+ Object value = new Object();
+ object.put("foo", value);
+ object.put("bar", new Object());
+ object.put("baz", new Object());
+ assertSame(value, object.get("foo"));
+ try {
+ object.get("FOO");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.put(null, value);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.get(null);
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testPut() throws JSONException {
+ JSONObject object = new JSONObject();
+ assertSame(object, object.put("foo", true));
+ object.put("foo", false);
+ assertEquals(false, object.get("foo"));
+
+ object.put("foo", 5.0d);
+ assertEquals(5.0d, object.get("foo"));
+ object.put("foo", 0);
+ assertEquals(0, object.get("foo"));
+ object.put("bar", Long.MAX_VALUE - 1);
+ assertEquals(Long.MAX_VALUE - 1, object.get("bar"));
+ object.put("baz", "x");
+ assertEquals("x", object.get("baz"));
+ object.put("bar", JSONObject.NULL);
+ assertSame(JSONObject.NULL, object.get("bar"));
+ }
+
+ public void testPutNullRemoves() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", "bar");
+ object.put("foo", null);
+ assertEquals(0, object.length());
+ assertFalse(object.has("foo"));
+ try {
+ object.get("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testPutOpt() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", "bar");
+ object.putOpt("foo", null);
+ assertEquals("bar", object.get("foo"));
+ object.putOpt(null, null);
+ assertEquals(1, object.length());
+ object.putOpt(null, "bar");
+ assertEquals(1, object.length());
+ }
+
+ public void testPutOptUnsupportedNumbers() throws JSONException {
+ JSONObject object = new JSONObject();
+ try {
+ object.putOpt("foo", Double.NaN);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.putOpt("foo", Double.NEGATIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.putOpt("foo", Double.POSITIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testRemove() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", "bar");
+ assertEquals(null, object.remove(null));
+ assertEquals(null, object.remove(""));
+ assertEquals(null, object.remove("bar"));
+ assertEquals("bar", object.remove("foo"));
+ assertEquals(null, object.remove("foo"));
+ }
+
+ public void testBooleans() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", true);
+ object.put("bar", false);
+ object.put("baz", "true");
+ object.put("quux", "false");
+ assertEquals(4, object.length());
+ assertEquals(true, object.getBoolean("foo"));
+ assertEquals(false, object.getBoolean("bar"));
+ assertEquals(true, object.getBoolean("baz"));
+ assertEquals(false, object.getBoolean("quux"));
+ assertFalse(object.isNull("foo"));
+ assertFalse(object.isNull("quux"));
+ assertTrue(object.has("foo"));
+ assertTrue(object.has("quux"));
+ assertFalse(object.has("missing"));
+ assertEquals(true, object.optBoolean("foo"));
+ assertEquals(false, object.optBoolean("bar"));
+ assertEquals(true, object.optBoolean("baz"));
+ assertEquals(false, object.optBoolean("quux"));
+ assertEquals(false, object.optBoolean("missing"));
+ assertEquals(true, object.optBoolean("foo", true));
+ assertEquals(false, object.optBoolean("bar", true));
+ assertEquals(true, object.optBoolean("baz", true));
+ assertEquals(false, object.optBoolean("quux", true));
+ assertEquals(true, object.optBoolean("missing", true));
+
+ object.put("foo", "truE");
+ object.put("bar", "FALSE");
+ assertEquals(true, object.getBoolean("foo"));
+ assertEquals(false, object.getBoolean("bar"));
+ assertEquals(true, object.optBoolean("foo"));
+ assertEquals(false, object.optBoolean("bar"));
+ assertEquals(true, object.optBoolean("foo", false));
+ assertEquals(false, object.optBoolean("bar", false));
+ }
+
+ public void testNumbers() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", Double.MIN_VALUE);
+ object.put("bar", 9223372036854775806L);
+ object.put("baz", Double.MAX_VALUE);
+ object.put("quux", -0d);
+ assertEquals(4, object.length());
+
+ assertTrue(object.toString().contains("\"foo\":4.9E-324"));
+ assertTrue(object.toString().contains("\"bar\":9223372036854775806"));
+ assertTrue(object.toString().contains("\"baz\":1.7976931348623157E308"));
+
+ // bogus behaviour: toString() and getString() return different values for -0d
+ assertTrue(object.toString().contains("\"quux\":-0}") // no trailing decimal point
+ || object.toString().contains("\"quux\":-0,"));
+
+ assertEquals(Double.MIN_VALUE, object.get("foo"));
+ assertEquals(9223372036854775806L, object.get("bar"));
+ assertEquals(Double.MAX_VALUE, object.get("baz"));
+ assertEquals(-0d, object.get("quux"));
+ assertEquals(Double.MIN_VALUE, object.getDouble("foo"));
+ assertEquals(9.223372036854776E18, object.getDouble("bar"));
+ assertEquals(Double.MAX_VALUE, object.getDouble("baz"));
+ assertEquals(-0d, object.getDouble("quux"));
+ assertEquals(0, object.getLong("foo"));
+ assertEquals(9223372036854775806L, object.getLong("bar"));
+ assertEquals(Long.MAX_VALUE, object.getLong("baz"));
+ assertEquals(0, object.getLong("quux"));
+ assertEquals(0, object.getInt("foo"));
+ assertEquals(-2, object.getInt("bar"));
+ assertEquals(Integer.MAX_VALUE, object.getInt("baz"));
+ assertEquals(0, object.getInt("quux"));
+ assertEquals(Double.MIN_VALUE, object.opt("foo"));
+ assertEquals(9223372036854775806L, object.optLong("bar"));
+ assertEquals(Double.MAX_VALUE, object.optDouble("baz"));
+ assertEquals(0, object.optInt("quux"));
+ assertEquals(Double.MIN_VALUE, object.opt("foo"));
+ assertEquals(9223372036854775806L, object.optLong("bar"));
+ assertEquals(Double.MAX_VALUE, object.optDouble("baz"));
+ assertEquals(0, object.optInt("quux"));
+ assertEquals(Double.MIN_VALUE, object.optDouble("foo", 5.0d));
+ assertEquals(9223372036854775806L, object.optLong("bar", 1L));
+ assertEquals(Long.MAX_VALUE, object.optLong("baz", 1L));
+ assertEquals(0, object.optInt("quux", -1));
+ assertEquals("4.9E-324", object.getString("foo"));
+ assertEquals("9223372036854775806", object.getString("bar"));
+ assertEquals("1.7976931348623157E308", object.getString("baz"));
+ assertEquals("-0.0", object.getString("quux"));
+ }
+
+ public void testFloats() throws JSONException {
+ JSONObject object = new JSONObject();
+ try {
+ object.put("foo", (Float) Float.NaN);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.put("foo", (Float) Float.NEGATIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.put("foo", (Float) Float.POSITIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testOtherNumbers() throws JSONException {
+ Number nan = new Number() {
+ public int intValue() {
+ return 0;
+ }
+ public long longValue() {
+ return 1L;
+ }
+ public float floatValue() {
+ return 2;
+ }
+ public double doubleValue() {
+ return Double.NaN;
+ }
+ @Override public String toString() {
+ return "x";
+ }
+ };
+
+ // bogus behaviour: foreign object types should be rejected!
+ JSONObject object = new JSONObject();
+ object.put("foo", nan);
+ assertEquals("{\"foo\":x}", object.toString());
+ }
+
+ public void testForeignObjects() throws JSONException {
+ Object foreign = new Object() {
+ @Override public String toString() {
+ return "x";
+ }
+ };
+
+ // bogus behaviour: foreign object types should be rejected and not treated as Strings
+ JSONObject object = new JSONObject();
+ object.put("foo", foreign);
+ assertEquals("{\"foo\":\"x\"}", object.toString());
+ }
+
+ public void testNullKeys() {
+ try {
+ new JSONObject().put(null, false);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ new JSONObject().put(null, 0.0d);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ new JSONObject().put(null, 5);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ new JSONObject().put(null, 5L);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ new JSONObject().put(null, "foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testStrings() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", "true");
+ object.put("bar", "5.5");
+ object.put("baz", "9223372036854775806");
+ object.put("quux", "null");
+ object.put("height", "5\"8' tall");
+
+ assertTrue(object.toString().contains("\"foo\":\"true\""));
+ assertTrue(object.toString().contains("\"bar\":\"5.5\""));
+ assertTrue(object.toString().contains("\"baz\":\"9223372036854775806\""));
+ assertTrue(object.toString().contains("\"quux\":\"null\""));
+ assertTrue(object.toString().contains("\"height\":\"5\\\"8' tall\""));
+
+ assertEquals("true", object.get("foo"));
+ assertEquals("null", object.getString("quux"));
+ assertEquals("5\"8' tall", object.getString("height"));
+ assertEquals("true", object.opt("foo"));
+ assertEquals("5.5", object.optString("bar"));
+ assertEquals("true", object.optString("foo", "x"));
+ assertFalse(object.isNull("foo"));
+
+ assertEquals(true, object.getBoolean("foo"));
+ assertEquals(true, object.optBoolean("foo"));
+ assertEquals(true, object.optBoolean("foo", false));
+ assertEquals(0, object.optInt("foo"));
+ assertEquals(-2, object.optInt("foo", -2));
+
+ assertEquals(5.5d, object.getDouble("bar"));
+ assertEquals(5L, object.getLong("bar"));
+ assertEquals(5, object.getInt("bar"));
+ assertEquals(5, object.optInt("bar", 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, object.getLong("baz"));
+ assertEquals(9.223372036854776E18, object.getDouble("baz"));
+ assertEquals(Integer.MAX_VALUE, object.getInt("baz"));
+
+ assertFalse(object.isNull("quux"));
+ try {
+ object.getDouble("quux");
+ fail();
+ } catch (JSONException e) {
+ }
+ assertEquals(Double.NaN, object.optDouble("quux"));
+ assertEquals(-1.0d, object.optDouble("quux", -1.0d));
+
+ object.put("foo", "TRUE");
+ assertEquals(true, object.getBoolean("foo"));
+ }
+
+ public void testJSONObjects() throws JSONException {
+ JSONObject object = new JSONObject();
+
+ JSONArray a = new JSONArray();
+ JSONObject b = new JSONObject();
+ object.put("foo", a);
+ object.put("bar", b);
+
+ assertSame(a, object.getJSONArray("foo"));
+ assertSame(b, object.getJSONObject("bar"));
+ try {
+ object.getJSONObject("foo");
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.getJSONArray("bar");
+ fail();
+ } catch (JSONException e) {
+ }
+ assertEquals(a, object.optJSONArray("foo"));
+ assertEquals(b, object.optJSONObject("bar"));
+ assertEquals(null, object.optJSONArray("bar"));
+ assertEquals(null, object.optJSONObject("foo"));
+ }
+
+ public void testToJSONArray() throws JSONException {
+ JSONObject object = new JSONObject();
+ Object value = new Object();
+ object.put("foo", true);
+ object.put("bar", 5.0d);
+ object.put("baz", -0.0d);
+ object.put("quux", value);
+
+ JSONArray names = new JSONArray();
+ names.put("baz");
+ names.put("quux");
+ names.put("foo");
+
+ JSONArray array = object.toJSONArray(names);
+ assertEquals(-0.0d, array.get(0));
+ assertEquals(value, array.get(1));
+ assertEquals(true, array.get(2));
+
+ object.put("foo", false);
+ assertEquals(true, array.get(2));
+ }
+
+ public void testToJSONArrayMissingNames() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", true);
+ object.put("bar", 5.0d);
+ object.put("baz", JSONObject.NULL);
+
+ JSONArray names = new JSONArray();
+ names.put("bar");
+ names.put("foo");
+ names.put("quux");
+ names.put("baz");
+
+ JSONArray array = object.toJSONArray(names);
+ assertEquals(4, array.length());
+
+ assertEquals(5.0d, array.get(0));
+ assertEquals(true, array.get(1));
+ try {
+ array.get(2);
+ fail();
+ } catch (JSONException e) {
+ }
+ assertEquals(JSONObject.NULL, array.get(3));
+ }
+
+ public void testToJSONArrayNull() throws JSONException {
+ JSONObject object = new JSONObject();
+ assertEquals(null, object.toJSONArray(null));
+ object.put("foo", 5);
+ try {
+ object.toJSONArray(null);
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testToJSONArrayEndsUpEmpty() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ JSONArray array = new JSONArray();
+ array.put("bar");
+ assertEquals(1, object.toJSONArray(array).length());
+ }
+
+ public void testToJSONArrayNonString() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ object.put("null", 10);
+ object.put("false", 15);
+
+ JSONArray names = new JSONArray();
+ names.put(JSONObject.NULL);
+ names.put(false);
+ names.put("foo");
+
+ // bogus behaviour: array elements are converted to Strings
+ JSONArray array = object.toJSONArray(names);
+ assertEquals(3, array.length());
+ assertEquals(10, array.get(0));
+ assertEquals(15, array.get(1));
+ assertEquals(5, array.get(2));
+ }
+
+ public void testPutUnsupportedNumbers() throws JSONException {
+ JSONObject object = new JSONObject();
+ try {
+ object.put("foo", Double.NaN);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.put("foo", Double.NEGATIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.put("foo", Double.POSITIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testPutUnsupportedNumbersAsObjects() throws JSONException {
+ JSONObject object = new JSONObject();
+ try {
+ object.put("foo", (Double) Double.NaN);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.put("foo", (Double) Double.NEGATIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ object.put("foo", (Double) Double.POSITIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ /**
+ * Although JSONObject is usually defensive about which numbers it accepts,
+ * it doesn't check inputs in its constructor.
+ */
+ public void testCreateWithUnsupportedNumbers() throws JSONException {
+ Map<String, Object> contents = new HashMap<String, Object>();
+ contents.put("foo", Double.NaN);
+ contents.put("bar", Double.NEGATIVE_INFINITY);
+ contents.put("baz", Double.POSITIVE_INFINITY);
+
+ JSONObject object = new JSONObject(contents);
+ assertEquals(Double.NaN, object.get("foo"));
+ assertEquals(Double.NEGATIVE_INFINITY, object.get("bar"));
+ assertEquals(Double.POSITIVE_INFINITY, object.get("baz"));
+ }
+
+ public void testToStringWithUnsupportedNumbers() {
+ // bogus behaviour: when the object contains an unsupported number, toString returns null
+ JSONObject object = new JSONObject(Collections.singletonMap("foo", Double.NaN));
+ assertEquals(null, object.toString());
+ }
+
+ public void testMapConstructorCopiesContents() throws JSONException {
+ Map<String, Object> contents = new HashMap<String, Object>();
+ contents.put("foo", 5);
+ JSONObject object = new JSONObject(contents);
+ contents.put("foo", 10);
+ assertEquals(5, object.get("foo"));
+ }
+
+ public void testMapConstructorWithBogusEntries() {
+ Map<Object, Object> contents = new HashMap<Object, Object>();
+ contents.put(5, 5);
+
+ // bogus behaviour: the constructor doesn't validate its input
+ new JSONObject(contents);
+ }
+
+ public void testAccumulateMutatesInPlace() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ object.accumulate("foo", 6);
+ JSONArray array = object.getJSONArray("foo");
+ assertEquals("[5,6]", array.toString());
+ object.accumulate("foo", 7);
+ assertEquals("[5,6,7]", array.toString());
+ }
+
+ public void testAccumulateExistingArray() throws JSONException {
+ JSONArray array = new JSONArray();
+ JSONObject object = new JSONObject();
+ object.put("foo", array);
+ object.accumulate("foo", 5);
+ assertEquals("[5]", array.toString());
+ }
+
+ public void testAccumulatePutArray() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.accumulate("foo", 5);
+ assertEquals("{\"foo\":5}", object.toString());
+ object.accumulate("foo", new JSONArray());
+ assertEquals("{\"foo\":[5,[]]}", object.toString());
+ }
+
+ public void testAccumulateNull() {
+ JSONObject object = new JSONObject();
+ try {
+ object.accumulate(null, 5);
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+
+ public void testEmptyStringKey() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("", 5);
+ assertEquals(5, object.get(""));
+ assertEquals("{\"\":5}", object.toString());
+ }
+
+ public void testNullValue() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", JSONObject.NULL);
+ object.put("bar", null);
+
+ // bogus behaviour: there's 2 ways to represent null; each behaves differently!
+ assertTrue(object.has("foo"));
+ assertFalse(object.has("bar"));
+ assertTrue(object.isNull("foo"));
+ assertTrue(object.isNull("bar"));
+ }
+
+ public void testHas() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ assertTrue(object.has("foo"));
+ assertFalse(object.has("bar"));
+ assertFalse(object.has(null));
+ }
+
+ public void testOptNull() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", "bar");
+ assertEquals(null, object.opt(null));
+ assertEquals(false, object.optBoolean(null));
+ assertEquals(Double.NaN, object.optDouble(null));
+ assertEquals(0, object.optInt(null));
+ assertEquals(0L, object.optLong(null));
+ assertEquals(null, object.optJSONArray(null));
+ assertEquals(null, object.optJSONObject(null));
+ assertEquals("", object.optString(null));
+ assertEquals(true, object.optBoolean(null, true));
+ assertEquals(0.0d, object.optDouble(null, 0.0d));
+ assertEquals(1, object.optInt(null, 1));
+ assertEquals(1L, object.optLong(null, 1L));
+ assertEquals("baz", object.optString(null, "baz"));
+ }
+
+ public void testToStringWithIndentFactor() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", new JSONArray(Arrays.asList(5, 6)));
+ object.put("bar", new JSONObject());
+ String foobar = "{\n" +
+ " \"foo\": [\n" +
+ " 5,\n" +
+ " 6\n" +
+ " ],\n" +
+ " \"bar\": {}\n" +
+ "}";
+ String barfoo = "{\n" +
+ " \"bar\": {},\n" +
+ " \"foo\": [\n" +
+ " 5,\n" +
+ " 6\n" +
+ " ]\n" +
+ "}";
+ String string = object.toString(5);
+ assertTrue(string, foobar.equals(string) || barfoo.equals(string));
+ }
+
+ public void testNames() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ object.put("bar", 6);
+ object.put("baz", 7);
+ JSONArray array = object.names();
+ assertTrue(array.toString().contains("foo"));
+ assertTrue(array.toString().contains("bar"));
+ assertTrue(array.toString().contains("baz"));
+ }
+
+ public void testKeysEmptyObject() {
+ JSONObject object = new JSONObject();
+ assertFalse(object.keys().hasNext());
+ try {
+ object.keys().next();
+ fail();
+ } catch (NoSuchElementException e) {
+ }
+ }
+
+ public void testKeys() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ object.put("bar", 6);
+ object.put("foo", 7);
+
+ @SuppressWarnings("unchecked")
+ Iterator<String> keys = (Iterator<String>) object.keys();
+ Set<String> result = new HashSet<String>();
+ assertTrue(keys.hasNext());
+ result.add(keys.next());
+ assertTrue(keys.hasNext());
+ result.add(keys.next());
+ assertFalse(keys.hasNext());
+ assertEquals(new HashSet<String>(Arrays.asList("foo", "bar")), result);
+
+ try {
+ keys.next();
+ fail();
+ } catch (NoSuchElementException e) {
+ }
+ }
+
+ public void testMutatingKeysMutatesObject() throws JSONException {
+ JSONObject object = new JSONObject();
+ object.put("foo", 5);
+ Iterator keys = object.keys();
+ keys.next();
+ keys.remove();
+ assertEquals(0, object.length());
+ }
+
+ public void testQuote() {
+ // covered by JSONStringerTest.testEscaping()
+ }
+
+ public void testNumberToString() throws JSONException {
+ assertEquals("5", JSONObject.numberToString(5));
+ assertEquals("-0", JSONObject.numberToString(-0.0d));
+ assertEquals("9223372036854775806", JSONObject.numberToString(9223372036854775806L));
+ assertEquals("4.9E-324", JSONObject.numberToString(Double.MIN_VALUE));
+ assertEquals("1.7976931348623157E308", JSONObject.numberToString(Double.MAX_VALUE));
+ try {
+ JSONObject.numberToString(Double.NaN);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ JSONObject.numberToString(Double.NEGATIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ try {
+ JSONObject.numberToString(Double.POSITIVE_INFINITY);
+ fail();
+ } catch (JSONException e) {
+ }
+ assertEquals("0.001", JSONObject.numberToString(new BigDecimal("0.001")));
+ assertEquals("9223372036854775806",
+ JSONObject.numberToString(new BigInteger("9223372036854775806")));
+ try {
+ JSONObject.numberToString(null);
+ fail();
+ } catch (JSONException e) {
+ }
+ }
+}
diff --git a/json/src/test/java/org/json/JSONStringerTest.java b/json/src/test/java/org/json/JSONStringerTest.java
index a30df9e..03a2903 100644
--- a/json/src/test/java/org/json/JSONStringerTest.java
+++ b/json/src/test/java/org/json/JSONStringerTest.java
@@ -213,6 +213,7 @@ public class JSONStringerTest extends TestCase {
new JSONStringer().object().key("a").value(original).endObject().toString());
assertEquals("[\"" + escaped + "\"]",
new JSONStringer().array().value(original).endArray().toString());
+ assertEquals("\"" + escaped + "\"", JSONObject.quote(original));
}
public void testJSONArrayAsValue() throws JSONException {
diff --git a/json/src/test/java/org/json/SelfUseTest.java b/json/src/test/java/org/json/SelfUseTest.java
new file mode 100644
index 0000000..e3d428b
--- /dev/null
+++ b/json/src/test/java/org/json/SelfUseTest.java
@@ -0,0 +1,204 @@
+/**
+ * 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 junit.framework.TestCase;
+
+/**
+ * These tests checks self use; ie. when methods delegate to non-final methods.
+ * For the most part we doesn't attempt to cover self-use, except in those cases
+ * where our clean room implementation does it.
+ *
+ * <p>This black box test was written without inspecting the non-free org.json
+ * sourcecode.
+ */
+public class SelfUseTest extends TestCase {
+
+ private int objectPutCalls = 0;
+ private int objectGetCalls = 0;
+ private int objectOptCalls = 0;
+ private int objectOptTypeCalls = 0;
+ private int arrayPutCalls = 0;
+ private int arrayGetCalls = 0;
+ private int arrayOptCalls = 0;
+ private int arrayOptTypeCalls = 0;
+
+ private final JSONObject object = new JSONObject() {
+ @Override public JSONObject put(String name, Object value) throws JSONException {
+ objectPutCalls++;
+ return super.put(name, value);
+ }
+ @Override public Object get(String name) throws JSONException {
+ objectGetCalls++;
+ return super.get(name);
+ }
+ @Override public Object opt(String name) {
+ objectOptCalls++;
+ return super.opt(name);
+ }
+ @Override public boolean optBoolean(String key, boolean defaultValue) {
+ objectOptTypeCalls++;
+ return super.optBoolean(key, defaultValue);
+ }
+ @Override public double optDouble(String key, double defaultValue) {
+ objectOptTypeCalls++;
+ return super.optDouble(key, defaultValue);
+ }
+ @Override public int optInt(String key, int defaultValue) {
+ objectOptTypeCalls++;
+ return super.optInt(key, defaultValue);
+ }
+ @Override public long optLong(String key, long defaultValue) {
+ objectOptTypeCalls++;
+ return super.optLong(key, defaultValue);
+ }
+ @Override public String optString(String key, String defaultValue) {
+ objectOptTypeCalls++;
+ return super.optString(key, defaultValue);
+ }
+ };
+
+ private final JSONArray array = new JSONArray() {
+ @Override public JSONArray put(int index, Object value) throws JSONException {
+ arrayPutCalls++;
+ return super.put(index, value);
+ }
+ @Override public Object get(int index) throws JSONException {
+ arrayGetCalls++;
+ return super.get(index);
+ }
+ @Override public Object opt(int index) {
+ arrayOptCalls++;
+ return super.opt(index);
+ }
+ @Override public boolean optBoolean(int index, boolean fallback) {
+ arrayOptTypeCalls++;
+ return super.optBoolean(index, fallback);
+ }
+ @Override public double optDouble(int index, double fallback) {
+ arrayOptTypeCalls++;
+ return super.optDouble(index, fallback);
+ }
+ @Override public long optLong(int index, long fallback) {
+ arrayOptTypeCalls++;
+ return super.optLong(index, fallback);
+ }
+ @Override public String optString(int index, String fallback) {
+ arrayOptTypeCalls++;
+ return super.optString(index, fallback);
+ }
+ @Override public int optInt(int index, int fallback) {
+ arrayOptTypeCalls++;
+ return super.optInt(index, fallback);
+ }
+ };
+
+ public void testObjectPut() throws JSONException {
+ object.putOpt("foo", "bar");
+ assertEquals(1, objectPutCalls);
+ }
+
+ public void testObjectAccumulate() throws JSONException {
+ object.accumulate("foo", "bar");
+ assertEquals(1, objectPutCalls);
+ }
+
+ public void testObjectGetBoolean() throws JSONException {
+ object.put("foo", "true");
+ object.getBoolean("foo");
+ assertEquals(1, objectGetCalls);
+ }
+
+ public void testObjectOptType() throws JSONException {
+ object.optBoolean("foo");
+ assertEquals(1, objectOptCalls);
+ assertEquals(1, objectOptTypeCalls);
+ object.optDouble("foo");
+ assertEquals(2, objectOptCalls);
+ assertEquals(2, objectOptTypeCalls);
+ object.optInt("foo");
+ assertEquals(3, objectOptCalls);
+ assertEquals(3, objectOptTypeCalls);
+ object.optLong("foo");
+ assertEquals(4, objectOptCalls);
+ assertEquals(4, objectOptTypeCalls);
+ object.optString("foo");
+ assertEquals(5, objectOptCalls);
+ assertEquals(5, objectOptTypeCalls);
+ }
+
+ public void testToJSONArray() throws JSONException {
+ object.put("foo", 5);
+ object.put("bar", 10);
+ array.put("foo");
+ array.put("baz");
+ array.put("bar");
+ object.toJSONArray(array);
+ assertEquals(3, arrayOptCalls);
+ assertEquals(0, arrayOptTypeCalls);
+ assertEquals(3, objectOptCalls);
+ assertEquals(0, objectOptTypeCalls);
+ }
+
+ public void testPutAtIndex() throws JSONException {
+ array.put(10, false);
+ assertEquals(1, arrayPutCalls);
+ }
+
+ public void testIsNull() {
+ array.isNull(5);
+ assertEquals(1, arrayOptCalls);
+ }
+
+ public void testArrayGetType() throws JSONException {
+ array.put(true);
+ array.getBoolean(0);
+ assertEquals(1, arrayGetCalls);
+ }
+
+ public void testArrayOptType() throws JSONException {
+ array.optBoolean(3);
+ assertEquals(1, arrayOptCalls);
+ assertEquals(1, arrayOptTypeCalls);
+ array.optDouble(3);
+ assertEquals(2, arrayOptCalls);
+ assertEquals(2, arrayOptTypeCalls);
+ array.optInt(3);
+ assertEquals(3, arrayOptCalls);
+ assertEquals(3, arrayOptTypeCalls);
+ array.optLong(3);
+ assertEquals(4, arrayOptCalls);
+ assertEquals(4, arrayOptTypeCalls);
+ array.optString(3);
+ assertEquals(5, arrayOptCalls);
+ assertEquals(5, arrayOptTypeCalls);
+ }
+
+ public void testToJSONObject() throws JSONException {
+ array.put("foo");
+ array.put("baz");
+ array.put("bar");
+ JSONArray values = new JSONArray();
+ values.put(5.5d);
+ values.put(11d);
+ values.put(30);
+ values.toJSONObject(array);
+ assertEquals(3, arrayOptCalls);
+ assertEquals(0, arrayOptTypeCalls);
+ }
+
+}