diff options
author | Jesse Wilson <jessewilson@google.com> | 2010-03-09 17:54:35 -0800 |
---|---|---|
committer | Jesse Wilson <jessewilson@google.com> | 2010-03-10 10:00:53 -0800 |
commit | 53c13031e4b68645b0ca7c7a335aae41d0b84276 (patch) | |
tree | 473852c8e9654b0bdaede0d25d5a2f710be6d9e2 /json | |
parent | ec02394f92b3ff460543dad5c57bc2ee6474683f (diff) | |
download | libcore-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.java | 6 | ||||
-rw-r--r-- | json/src/test/java/org/json/JSONArrayTest.java | 83 | ||||
-rw-r--r-- | json/src/test/java/org/json/JSONObjectTest.java | 803 | ||||
-rw-r--r-- | json/src/test/java/org/json/JSONStringerTest.java | 1 | ||||
-rw-r--r-- | json/src/test/java/org/json/SelfUseTest.java | 204 |
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); + } + +} |