From c3ba4bdbe5321c0cf2eeae9829e8a6508cd4665b Mon Sep 17 00:00:00 2001 From: Nicholas Cull Date: Sat, 23 Jul 2016 19:12:51 +1000 Subject: [PATCH 1/7] Nesting depth test works as expected. --- .../java/org/json/junit/JSONStringerTest.java | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/src/test/java/org/json/junit/JSONStringerTest.java b/src/test/java/org/json/junit/JSONStringerTest.java index 19b46de..d4376df 100644 --- a/src/test/java/org/json/junit/JSONStringerTest.java +++ b/src/test/java/org/json/junit/JSONStringerTest.java @@ -27,7 +27,7 @@ public class JSONStringerTest { jsonStringer.key(null); assertTrue("Expected an exception", false); } catch (JSONException e) { - assertTrue("Expected an exception message", + assertTrue("Expected an exception message", "Null key.". equals(e.getMessage())); } @@ -44,7 +44,7 @@ public class JSONStringerTest { jsonStringer.key("hi"); assertTrue("Expected an exception", false); } catch (JSONException e) { - assertTrue("Expected an exception message", + assertTrue("Expected an exception message", "Misplaced key.". equals(e.getMessage())); } @@ -61,7 +61,7 @@ public class JSONStringerTest { try { jsonStringer.array(); } catch (JSONException e) { - assertTrue("Expected an exception message", + assertTrue("Expected an exception message", "Misplaced array.". equals(e.getMessage())); } @@ -78,7 +78,7 @@ public class JSONStringerTest { try { jsonStringer.endArray(); } catch (JSONException e) { - assertTrue("Expected an exception message", + assertTrue("Expected an exception message", "Misplaced endArray.". equals(e.getMessage())); } @@ -95,7 +95,7 @@ public class JSONStringerTest { try { jsonStringer.endObject(); } catch (JSONException e) { - assertTrue("Expected an exception message", + assertTrue("Expected an exception message", "Misplaced endObject.". equals(e.getMessage())); } @@ -112,7 +112,7 @@ public class JSONStringerTest { try { jsonStringer.object(); } catch (JSONException e) { - assertTrue("Expected an exception message", + assertTrue("Expected an exception message", "Misplaced object.". equals(e.getMessage())); } @@ -125,7 +125,47 @@ public class JSONStringerTest { @Test public void exceedNestDepthException() { try { - new JSONStringer().object(). + JSONStringer s = new JSONStringer(); + s.object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). + key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(); + s.key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). @@ -165,9 +205,10 @@ public class JSONStringerTest { key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(). key("k").object().key("k").object().key("k").object().key("k").object().key("k").object(); + fail("Expected an exception message"); } catch (JSONException e) { - assertTrue("Expected an exception message", - "". + assertTrue("Expected an exception message", + "Nesting too deep.". equals(e.getMessage())); } } From 72c2b911bfba67472c6d03bdb4ffa12c47b56b70 Mon Sep 17 00:00:00 2001 From: Nicholas Cull Date: Sat, 23 Jul 2016 22:33:19 +1000 Subject: [PATCH 2/7] Tests for toString(), write(), toList(), and toMap(). Explicitly test variations of toString() and write() for different indent levels, and different method overloads. Also create some tests for the new toList() and toMap() methods for coverage improvements to JSONArray and JSONObject. --- .../java/org/json/junit/JSONArrayTest.java | 195 ++++++++++++++++++ .../java/org/json/junit/JSONObjectTest.java | 180 +++++++++++++++- 2 files changed, 373 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index ef3a608..c818e8b 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -2,7 +2,10 @@ package org.json.junit; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import java.io.StringWriter; +import java.io.Writer; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; @@ -639,6 +642,71 @@ public class JSONArrayTest { !jsonArray.similar(otherJsonArray)); } + /** + * Exercise JSONArray toString() method with various indent levels. + */ + @Test + public void jsonArrayToStringIndent() { + String jsonArray0Str = + "[" + + "[1,2," + + "{\"key3\":true}" + + "]," + + "{\"key1\":\"val1\",\"key2\":" + + "{\"key2\":\"val2\"}" + + "}," + + "[" + + "[1,2.1]" + + "," + + "[null]" + + "]" + + "]"; + + String jsonArray1Str = + "[\n" + + " [\n" + + " 1,\n" + + " 2,\n" + + " {\"key3\": true}\n" + + " ],\n" + + " {\n" + + " \"key1\": \"val1\",\n" + + " \"key2\": {\"key2\": \"val2\"}\n" + + " },\n" + + " [\n" + + " [\n" + + " 1,\n" + + " 2.1\n" + + " ],\n" + + " [null]\n" + + " ]\n" + + "]"; + String jsonArray4Str = + "[\n" + + " [\n" + + " 1,\n" + + " 2,\n" + + " {\"key3\": true}\n" + + " ],\n" + + " {\n" + + " \"key1\": \"val1\",\n" + + " \"key2\": {\"key2\": \"val2\"}\n" + + " },\n" + + " [\n" + + " [\n" + + " 1,\n" + + " 2.1\n" + + " ],\n" + + " [null]\n" + + " ]\n" + + "]"; + JSONArray jsonArray = new JSONArray(jsonArray0Str); + assertEquals(jsonArray0Str, jsonArray.toString()); + assertEquals(jsonArray0Str, jsonArray.toString(0)); + assertEquals(jsonArray1Str, jsonArray.toString(1)); + assertEquals(jsonArray4Str, jsonArray.toString(4)); + } + /** * Convert an empty JSONArray to JSONObject */ @@ -726,4 +794,131 @@ public class JSONArrayTest { public void optQueryWithSyntaxError() { new JSONArray().optQuery("invalid"); } + + + /** + * Exercise the JSONArray write() method + */ + @Test + public void write() { + String str = "[\"value1\",\"value2\",{\"key1\":1,\"key2\":2,\"key3\":3}]"; + String expectedStr = str; + JSONArray jsonArray = new JSONArray(str); + StringWriter stringWriter = new StringWriter(); + Writer writer = jsonArray.write(stringWriter); + String actualStr = writer.toString(); + assertTrue("write() expected " + expectedStr + + "but found " + actualStr, + expectedStr.equals(actualStr)); + StringBuilder stringBuilder = new StringBuilder(); + Appendable appendable = jsonArray.write(stringBuilder); + actualStr = appendable.toString(); + assertTrue("write() expected " + expectedStr + + "but found " + actualStr, + expectedStr.equals(actualStr)); + } + + /** + * Exercise the JSONArray write(Appendable, int, int) method + */ + @Test + public void write3Param() { + String str0 = "[\"value1\",\"value2\",{\"key1\":1,\"key2\":false,\"key3\":3.14}]"; + String str2 = + "[\n" + + " \"value1\",\n" + + " \"value2\",\n" + + " {\n" + + " \"key1\": 1,\n" + + " \"key2\": false,\n" + + " \"key3\": 3.14\n" + + " }\n" + + " ]"; + String expectedStr = str0; + JSONArray jsonArray = new JSONArray(str0); + StringWriter stringWriter = new StringWriter(); + Writer writer = jsonArray.write(stringWriter, 0, 0); + String actualStr = writer.toString(); + assertEquals(expectedStr, actualStr); + expectedStr = str0; + StringBuilder stringBuilder = new StringBuilder(); + Appendable appendable = jsonArray.write(stringBuilder, 0, 0); + actualStr = appendable.toString(); + assertEquals(expectedStr, actualStr); + expectedStr = str2; + stringBuilder = new StringBuilder(); + appendable = jsonArray.write(stringBuilder, 2, 1); + actualStr = appendable.toString(); + assertEquals(expectedStr, actualStr); + } + + /** + * Exercise JSONArray toString() method with various indent levels. + */ + @Test + public void toList() { + String jsonArrayStr = + "[" + + "[1,2," + + "{\"key3\":true}" + + "]," + + "{\"key1\":\"val1\",\"key2\":" + + "{\"key2\":null}," + + "\"key3\":42,\"key4\":[]" + + "}," + + "[" + + "[\"value1\",2.1]" + + "," + + "[null]" + + "]" + + "]"; + + JSONArray jsonArray = new JSONArray(jsonArrayStr); + List list = jsonArray.toList(); + + assertTrue("List should not be null", list != null); + assertTrue("List should have 3 elements", list.size() == 3); + + List val1List = (List) list.get(0); + assertTrue("val1 should not be null", val1List != null); + assertTrue("val1 should have 3 elements", val1List.size() == 3); + + assertTrue("val1 value 1 should be 1", val1List.get(0).equals(Integer.valueOf(1))); + assertTrue("val1 value 2 should be 2", val1List.get(1).equals(Integer.valueOf(2))); + + Map key1Value3Map = (Map)val1List.get(2); + assertTrue("Map should not be null", key1Value3Map != null); + assertTrue("Map should have 1 element", key1Value3Map.size() == 1); + assertTrue("Map key3 should be true", key1Value3Map.get("key3").equals(Boolean.TRUE)); + + Map val2Map = (Map) list.get(1); + assertTrue("val2 should not be null", val2Map != null); + assertTrue("val2 should have 4 elements", val2Map.size() == 4); + assertTrue("val2 map key 1 should be val1", val2Map.get("key1").equals("val1")); + assertTrue("val2 map key 3 should be 42", val2Map.get("key3").equals(Integer.valueOf(42))); + + Map val2Key2Map = (Map)val2Map.get("key2"); + assertTrue("val2 map key 2 should not be null", val2Key2Map != null); + assertTrue("val2 map key 2 should have an entry", val2Key2Map.containsKey("key2")); + assertTrue("val2 map key 2 value should be null", val2Key2Map.get("key2") == null); + + List val2Key4List = (List)val2Map.get("key4"); + assertTrue("val2 map key 4 should not be null", val2Key4List != null); + assertTrue("val2 map key 4 should be empty", val2Key4List.isEmpty()); + + List val3List = (List) list.get(2); + assertTrue("val3 should not be null", val3List != null); + assertTrue("val3 should have 2 elements", val3List.size() == 2); + + List val3Val1List = (List)val3List.get(0); + assertTrue("val3 list val 1 should not be null", val3Val1List != null); + assertTrue("val3 list val 1 should have 2 elements", val3Val1List.size() == 2); + assertTrue("val3 list val 1 list element 1 should be value1", val3Val1List.get(0).equals("value1")); + assertTrue("val3 list val 1 list element 2 should be 2.1", val3Val1List.get(1).equals(Double.valueOf("2.1"))); + + List val3Val2List = (List)val3List.get(1); + assertTrue("val3 list val 2 should not be null", val3Val2List != null); + assertTrue("val3 list val 2 should have 1 element", val3Val2List.size() == 1); + assertTrue("val3 list val 2 list element 1 should be null", val3Val2List.get(0) == null); + } } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 08ec964..73029e7 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -3,6 +3,7 @@ package org.json.junit; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -1371,6 +1372,74 @@ public class JSONObjectTest { assertTrue("expected myVal4", "myVal4".equals(jsonObject.query("/objectKey/myKey4"))); } + /** + * Exercise JSONObject toString() method with various indent levels. + */ + @Test + public void jsonObjectToStringIndent() { + String jsonObject0Str = + "{"+ + "\"key1\":" + + "[1,2," + + "{\"key3\":true}" + + "],"+ + "\"key2\":" + + "{\"key1\":\"val1\",\"key2\":" + + "{\"key2\":\"val2\"}" + + "},"+ + "\"key3\":" + + "[" + + "[1,2.1]" + + "," + + "[null]" + + "]"+ + "}"; + + String jsonObject1Str = + "{\n" + + " \"key1\": [\n" + + " 1,\n" + + " 2,\n" + + " {\"key3\": true}\n" + + " ],\n" + + " \"key2\": {\n" + + " \"key1\": \"val1\",\n" + + " \"key2\": {\"key2\": \"val2\"}\n" + + " },\n" + + " \"key3\": [\n" + + " [\n" + + " 1,\n" + + " 2.1\n" + + " ],\n" + + " [null]\n" + + " ]\n" + + "}"; + String jsonObject4Str = + "{\n" + + " \"key1\": [\n" + + " 1,\n" + + " 2,\n" + + " {\"key3\": true}\n" + + " ],\n" + + " \"key2\": {\n" + + " \"key1\": \"val1\",\n" + + " \"key2\": {\"key2\": \"val2\"}\n" + + " },\n" + + " \"key3\": [\n" + + " [\n" + + " 1,\n" + + " 2.1\n" + + " ],\n" + + " [null]\n" + + " ]\n" + + "}"; + JSONObject jsonObject = new JSONObject(jsonObject0Str); + assertEquals(jsonObject0Str, jsonObject.toString()); + assertEquals(jsonObject0Str, jsonObject.toString(0)); + assertEquals(jsonObject1Str, jsonObject.toString(1)); + assertEquals(jsonObject4Str, jsonObject.toString(4)); + } + /** * Explores how JSONObject handles maps. Insert a string/string map * as a value in a JSONObject. It will remain a map. Convert the @@ -1441,7 +1510,7 @@ public class JSONObjectTest { String jsonArrayStr = "[1,2,3]"; JSONArray jsonArray = new JSONArray(jsonArrayStr); - assertTrue("jsonArra valueToString() incorrect", + assertTrue("jsonArray valueToString() incorrect", JSONObject.valueToString(jsonArray).equals(jsonArray.toString())); Map map = new HashMap(); map.put("key1", "val1"); @@ -1840,7 +1909,7 @@ public class JSONObjectTest { */ @Test public void write() { - String str = "{\"key\":\"value\"}"; + String str = "{\"key1\":\"value1\",\"key2\":[1,2,3]}"; String expectedStr = str; JSONObject jsonObject = new JSONObject(str); StringWriter stringWriter = new StringWriter(); @@ -1849,6 +1918,45 @@ public class JSONObjectTest { assertTrue("write() expected " +expectedStr+ "but found " +actualStr, expectedStr.equals(actualStr)); + StringBuilder stringBuilder = new StringBuilder(); + Appendable appendable = jsonObject.write(stringBuilder); + actualStr = appendable.toString(); + assertTrue("write() expected " +expectedStr+ + "but found " +actualStr, + expectedStr.equals(actualStr)); + } + + /** + * Exercise the JSONObject write(Appendable, int, int) method + */ + @Test + public void write3Param() { + String str0 = "{\"key1\":\"value1\",\"key2\":[1,false,3.14]}"; + String str2 = + "{\n" + + " \"key1\": \"value1\",\n" + + " \"key2\": [\n" + + " 1,\n" + + " false,\n" + + " 3.14\n" + + " ]\n" + + " }"; + String expectedStr = str0; + JSONObject jsonObject = new JSONObject(str0); + StringWriter stringWriter = new StringWriter(); + Writer writer = jsonObject.write(stringWriter,0,0); + String actualStr = writer.toString(); + assertEquals(expectedStr, actualStr); + expectedStr = str0; + StringBuilder stringBuilder = new StringBuilder(); + Appendable appendable = jsonObject.write(stringBuilder,0,0); + actualStr = appendable.toString(); + assertEquals(expectedStr, actualStr); + expectedStr = str2; + stringBuilder = new StringBuilder(); + appendable = jsonObject.write(stringBuilder,2,1); + actualStr = appendable.toString(); + assertEquals(expectedStr, actualStr); } /** @@ -1966,4 +2074,72 @@ public class JSONObjectTest { String json = "{ \"\\url\": \"value\" }"; new JSONObject(json); } + + /** + * Exercise JSONObject toMap() method. + */ + @Test + public void toMap() { + String jsonObjectStr = + "{" + + "\"key1\":" + + "[1,2," + + "{\"key3\":true}" + + "]," + + "\"key2\":" + + "{\"key1\":\"val1\",\"key2\":" + + "{\"key2\":null}," + + "\"key3\":42" + + "}," + + "\"key3\":" + + "[" + + "[\"value1\",2.1]" + + "," + + "[null]" + + "]" + + "}"; + + JSONObject jsonObject = new JSONObject(jsonObjectStr); + Map map = jsonObject.toMap(); + + assertTrue("Map should not be null", map != null); + assertTrue("Map should have 3 elements", map.size() == 3); + + List key1List = (List)map.get("key1"); + assertTrue("key1 should not be null", key1List != null); + assertTrue("key1 list should have 3 elements", key1List.size() == 3); + assertTrue("key1 value 1 should be 1", key1List.get(0).equals(Integer.valueOf(1))); + assertTrue("key1 value 2 should be 2", key1List.get(1).equals(Integer.valueOf(2))); + + Map key1Value3Map = (Map)key1List.get(2); + assertTrue("Map should not be null", key1Value3Map != null); + assertTrue("Map should have 1 element", key1Value3Map.size() == 1); + assertTrue("Map key3 should be true", key1Value3Map.get("key3").equals(Boolean.TRUE)); + + Map key2Map = (Map)map.get("key2"); + assertTrue("key2 should not be null", key2Map != null); + assertTrue("key2 map should have 3 elements", key2Map.size() == 3); + assertTrue("key2 map key 1 should be val1", key2Map.get("key1").equals("val1")); + assertTrue("key2 map key 3 should be 42", key2Map.get("key3").equals(Integer.valueOf(42))); + + Map key2Val2Map = (Map)key2Map.get("key2"); + assertTrue("key2 map key 2 should not be null", key2Val2Map != null); + assertTrue("key2 map key 2 should have an entry", key2Val2Map.containsKey("key2")); + assertTrue("key2 map key 2 value should be null", key2Val2Map.get("key2") == null); + + List key3List = (List)map.get("key3"); + assertTrue("key3 should not be null", key3List != null); + assertTrue("key3 list should have 3 elements", key3List.size() == 2); + + List key3Val1List = (List)key3List.get(0); + assertTrue("key3 list val 1 should not be null", key3Val1List != null); + assertTrue("key3 list val 1 should have 2 elements", key3Val1List.size() == 2); + assertTrue("key3 list val 1 list element 1 should be value1", key3Val1List.get(0).equals("value1")); + assertTrue("key3 list val 1 list element 2 should be 2.1", key3Val1List.get(1).equals(Double.valueOf("2.1"))); + + List key3Val2List = (List)key3List.get(1); + assertTrue("key3 list val 2 should not be null", key3Val2List != null); + assertTrue("key3 list val 2 should have 1 element", key3Val2List.size() == 1); + assertTrue("key3 list val 2 list element 1 should be null", key3Val2List.get(0) == null); + } } From ae77b5cd83121555152a13407fce230992afc0c0 Mon Sep 17 00:00:00 2001 From: Nicholas Cull Date: Sat, 23 Jul 2016 22:51:50 +1000 Subject: [PATCH 3/7] Tests for deep copy and mutability of toList() and toMap(). Both toMap() and toList() return deep copies, which are also mutable. That is, any changes to the JSONObject or JSONArray do not affect the newly create Map or List, and vice-versa. The resulting objects can be altered. --- src/test/java/org/json/junit/JSONArrayTest.java | 8 ++++++++ src/test/java/org/json/junit/JSONObjectTest.java | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index c818e8b..9f0e773 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -920,5 +920,13 @@ public class JSONArrayTest { assertTrue("val3 list val 2 should not be null", val3Val2List != null); assertTrue("val3 list val 2 should have 1 element", val3Val2List.size() == 1); assertTrue("val3 list val 2 list element 1 should be null", val3Val2List.get(0) == null); + + // assert that toList() is a deep copy + jsonArray.getJSONObject(1).put("key1", "still val1"); + assertTrue("val2 map key 1 should be val1", val2Map.get("key1").equals("val1")); + + // assert that the new list is mutable + assertTrue("Removing an entry should succeed", list.remove(2) != null); + assertTrue("List should have 2 elements", list.size() == 2); } } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 73029e7..10405b0 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -2141,5 +2141,14 @@ public class JSONObjectTest { assertTrue("key3 list val 2 should not be null", key3Val2List != null); assertTrue("key3 list val 2 should have 1 element", key3Val2List.size() == 1); assertTrue("key3 list val 2 list element 1 should be null", key3Val2List.get(0) == null); + + // Assert that toMap() is a deep copy + jsonObject.getJSONArray("key3").getJSONArray(0).put(0, "still value 1"); + assertTrue("key3 list val 1 list element 1 should be value1", key3Val1List.get(0).equals("value1")); + + // assert that the new map is mutable + assertTrue("Removing a key should succeed", map.remove("key3") != null); + assertTrue("Map should have 2 elements", map.size() == 2); + } } From ffcfa66d7798061df9a5450ce9579d6ee6bbce9f Mon Sep 17 00:00:00 2001 From: Nicholas Cull Date: Sun, 24 Jul 2016 18:56:08 +1000 Subject: [PATCH 4/7] Add JSONString test class. This set of tests demonstrates what happens when JSONString returns various results from its toJSONString() method. Tests for null returns and exceptions thrown. Also tests what happens for non-JSONString objects. The intent is to cover JSONObject's valueToString() and writeValue() methods. --- .../java/org/json/junit/JSONStringTest.java | 310 ++++++++++++++++++ .../java/org/json/junit/JunitTestSuite.java | 7 +- 2 files changed, 314 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/json/junit/JSONStringTest.java diff --git a/src/test/java/org/json/junit/JSONStringTest.java b/src/test/java/org/json/junit/JSONStringTest.java new file mode 100644 index 0000000..c7d9d3e --- /dev/null +++ b/src/test/java/org/json/junit/JSONStringTest.java @@ -0,0 +1,310 @@ +package org.json.junit; + +import static org.junit.Assert.*; + +import java.io.StringWriter; +import java.util.*; + +import org.json.*; +import org.junit.Test; + +/** + * Tests for JSONString implementations, and the difference between + * {@link JSONObject#valueToString} and {@link JSONObject#writeValue}. + */ +public class JSONStringTest { + + /** + * This tests the JSONObject.writeValue() method. We can't test directly + * due to it being a package-protected method. Instead, we can call + * JSONArray.write(), which delegates the writing of each entry to + * writeValue(). + */ + @Test + public void writeValues() throws Exception { + JSONArray jsonArray = new JSONArray(); + jsonArray.put((Object)null); + + StringWriter writer = new StringWriter(); + String output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[null]".equals(output)); + + jsonArray = new JSONArray(); + jsonArray.put(JSONObject.NULL); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[null]".equals(output)); + + jsonArray = new JSONArray(); + jsonArray.put(new JSONObject()); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[{}]".equals(output)); + + jsonArray = new JSONArray(); + jsonArray.put(new JSONArray()); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[[]]".equals(output)); + + jsonArray = new JSONArray(); + Map singleMap = Collections.singletonMap("key1", "value1"); + jsonArray.put((Object)singleMap); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[{\"key1\":\"value1\"}]".equals(output)); + + jsonArray = new JSONArray(); + List singleList = Collections.singletonList("entry1"); + jsonArray.put((Object)singleList); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[[\"entry1\"]]".equals(output)); + + jsonArray = new JSONArray(); + int[] intArray = new int[] { 1, 2, 3 }; + jsonArray.put(intArray); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[[1,2,3]]".equals(output)); + + jsonArray = new JSONArray(); + jsonArray.put(24); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[24]".equals(output)); + + jsonArray = new JSONArray(); + jsonArray.put("string value"); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[\"string value\"]".equals(output)); + + jsonArray = new JSONArray(); + jsonArray.put(true); + writer = new StringWriter(); + output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[true]".equals(output)); + + } + + /** + * This tests the JSONObject.valueToString() method. These should be + * identical to the values above, except for the enclosing [ and ]. + */ + @Test + public void valuesToString() throws Exception { + + String output = JSONObject.valueToString(null); + assertTrue("String values should be equal", "null".equals(output)); + + output = JSONObject.valueToString(JSONObject.NULL); + assertTrue("String values should be equal", "null".equals(output)); + + output = JSONObject.valueToString(new JSONObject()); + assertTrue("String values should be equal", "{}".equals(output)); + + output = JSONObject.valueToString(new JSONArray()); + assertTrue("String values should be equal", "[]".equals(output)); + + Map singleMap = Collections.singletonMap("key1", "value1"); + output = JSONObject.valueToString(singleMap); + assertTrue("String values should be equal", "{\"key1\":\"value1\"}".equals(output)); + + List singleList = Collections.singletonList("entry1"); + output = JSONObject.valueToString(singleList); + assertTrue("String values should be equal", "[\"entry1\"]".equals(output)); + + int[] intArray = new int[] { 1, 2, 3 }; + output = JSONObject.valueToString(intArray); + assertTrue("String values should be equal", "[1,2,3]".equals(output)); + + output = JSONObject.valueToString(24); + assertTrue("String values should be equal", "24".equals(output)); + + output = JSONObject.valueToString("string value"); + assertTrue("String values should be equal", "\"string value\"".equals(output)); + + output = JSONObject.valueToString(true); + assertTrue("String values should be equal", "true".equals(output)); + + } + + /** + * Test what happens when toJSONString() returns a well-formed JSON value. + * This is the usual case. + */ + @Test + public void testJSONStringValue() throws Exception { + JSONStringValue jsonString = new JSONStringValue(); + JSONArray jsonArray = new JSONArray(); + + jsonArray.put(jsonString); + + StringWriter writer = new StringWriter(); + String output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[\"the JSON string value\"]".equals(output)); + + output = JSONObject.valueToString(jsonString); + assertTrue("String values should be equal", "\"the JSON string value\"".equals(output)); + } + + /** + * Test what happens when toJSONString() returns null. In one case, + * use the object's toString() method. In the other, throw a JSONException. + */ + @Test + public void testJSONNullStringValue() throws Exception { + JSONNullStringValue jsonString = new JSONNullStringValue(); + JSONArray jsonArray = new JSONArray(); + + jsonArray.put(jsonString); + + StringWriter writer = new StringWriter(); + String output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[\"the toString value\"]".equals(output)); + + // The first different between writeValue() and valueToString(): + // in this case, valueToString throws a JSONException + try { + output = JSONObject.valueToString(jsonString); + fail("Expected an exception, got a String value"); + } catch (Exception e) { + assertTrue("Expected JSONException", e instanceof JSONException); + assertTrue("Exception message does not match", "Bad value from toJSONString: null".equals(e.getMessage())); + } + } + + /** + * Test what happens when toJSONString() returns an exception. In both + * cases, a JSONException is thrown, with the cause and message set from + * the original exception. + */ + @Test + public void testJSONStringExceptionValue() throws Exception { + JSONStringExceptionValue jsonString = new JSONStringExceptionValue(); + JSONArray jsonArray = new JSONArray(); + + jsonArray.put(jsonString); + + StringWriter writer = new StringWriter(); + String output = null; + try { + output = jsonArray.write(writer).toString(); + fail("Expected an exception, got a String value"); + } catch (Exception e) { + assertTrue("Expected JSONException", e instanceof JSONException); + assertTrue("Exception message does not match", "the exception value".equals(e.getMessage())); + } + + try { + output = JSONObject.valueToString(jsonString); + fail("Expected an exception, got a String value"); + } catch (Exception e) { + assertTrue("Expected JSONException", e instanceof JSONException); + assertTrue("Exception message does not match", "the exception value".equals(e.getMessage())); + } + } + + /** + * Test what happens when a Java object's toString() returns a String value. + * This is the usual case. + */ + @Test + public void testStringValue() throws Exception { + StringValue nonJsonString = new StringValue(); + JSONArray jsonArray = new JSONArray(); + + jsonArray.put(nonJsonString); + + StringWriter writer = new StringWriter(); + String output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[\"the toString value for StringValue\"]".equals(output)); + + output = JSONObject.valueToString(nonJsonString); + assertTrue("String values should be equal", "\"the toString value for StringValue\"".equals(output)); + } + + /** + * Test what happens when a Java object's toString() returns null. + * Defaults to empty string. + */ + @Test + public void testNullStringValue() throws Exception { + NullStringValue nonJsonString = new NullStringValue(); + JSONArray jsonArray = new JSONArray(); + + jsonArray.put(nonJsonString); + + StringWriter writer = new StringWriter(); + String output = jsonArray.write(writer).toString(); + assertTrue("String values should be equal", "[\"\"]".equals(output)); + + output = JSONObject.valueToString(nonJsonString); + assertTrue("String values should be equal", "\"\"".equals(output)); + } + + /** + * A JSONString that returns a valid JSON string value. + */ + private static final class JSONStringValue implements JSONString { + + @Override + public String toJSONString() { + return "\"the JSON string value\""; + } + + @Override + public String toString() { + return "the toString value for JSONStringValue"; + } + } + + /** + * A JSONString that returns null when calling toJSONString(). + */ + private static final class JSONNullStringValue implements JSONString { + + @Override + public String toJSONString() { + return null; + } + + @Override + public String toString() { + return "the toString value"; + } + } + + /** + * A JSONString that throw an exception when calling toJSONString(). + */ + private static final class JSONStringExceptionValue implements JSONString { + + @Override + public String toJSONString() { + throw new IllegalStateException("the exception value"); + } + + @Override + public String toString() { + return "the toString value for JSONStringExceptionValue"; + } + } + + public static final class StringValue { + + @Override + public String toString() { + return "the toString value for StringValue"; + } + } + + public static final class NullStringValue { + + @Override + public String toString() { + return null; + } + } +} diff --git a/src/test/java/org/json/junit/JunitTestSuite.java b/src/test/java/org/json/junit/JunitTestSuite.java index 3863931..3a7223e 100644 --- a/src/test/java/org/json/junit/JunitTestSuite.java +++ b/src/test/java/org/json/junit/JunitTestSuite.java @@ -15,7 +15,8 @@ import org.junit.runners.Suite; JSONObjectTest.class, JSONArrayTest.class, EnumTest.class, - JSONPointerTest.class + JSONPointerTest.class, + JSONStringTest.class }) -public class JunitTestSuite { -} +public class JunitTestSuite { +} From 1246e12827fce05f70ce6758df647ea436d6578b Mon Sep 17 00:00:00 2001 From: Nicholas Cull Date: Sun, 24 Jul 2016 19:39:52 +1000 Subject: [PATCH 5/7] Factor out Writer from Appendable tests. --- .../java/org/json/junit/JSONArrayTest.java | 64 +++++++++++++++---- .../java/org/json/junit/JSONObjectTest.java | 61 ++++++++++++++---- 2 files changed, 102 insertions(+), 23 deletions(-) diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 9f0e773..13dbb39 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -802,24 +802,36 @@ public class JSONArrayTest { @Test public void write() { String str = "[\"value1\",\"value2\",{\"key1\":1,\"key2\":2,\"key3\":3}]"; - String expectedStr = str; JSONArray jsonArray = new JSONArray(str); + String expectedStr = str; StringWriter stringWriter = new StringWriter(); Writer writer = jsonArray.write(stringWriter); String actualStr = writer.toString(); assertTrue("write() expected " + expectedStr + - "but found " + actualStr, - expectedStr.equals(actualStr)); - StringBuilder stringBuilder = new StringBuilder(); - Appendable appendable = jsonArray.write(stringBuilder); - actualStr = appendable.toString(); - assertTrue("write() expected " + expectedStr + - "but found " + actualStr, + " but found " + actualStr, expectedStr.equals(actualStr)); } /** - * Exercise the JSONArray write(Appendable, int, int) method + * Exercise the JSONArray write() method using Appendable. + */ +/* + @Test + public void writeAppendable() { + String str = "[\"value1\",\"value2\",{\"key1\":1,\"key2\":2,\"key3\":3}]"; + JSONArray jsonArray = new JSONArray(str); + String expectedStr = str; + StringBuilder stringBuilder = new StringBuilder(); + Appendable appendable = jsonArray.write(stringBuilder); + String actualStr = appendable.toString(); + assertTrue("write() expected " + expectedStr + + " but found " + actualStr, + expectedStr.equals(actualStr)); + } +*/ + + /** + * Exercise the JSONArray write(Writer, int, int) method */ @Test public void write3Param() { @@ -834,23 +846,51 @@ public class JSONArrayTest { " \"key3\": 3.14\n" + " }\n" + " ]"; - String expectedStr = str0; JSONArray jsonArray = new JSONArray(str0); + String expectedStr = str0; StringWriter stringWriter = new StringWriter(); Writer writer = jsonArray.write(stringWriter, 0, 0); String actualStr = writer.toString(); assertEquals(expectedStr, actualStr); - expectedStr = str0; + + expectedStr = str2; + stringWriter = new StringWriter(); + writer = jsonArray.write(stringWriter, 2, 1); + actualStr = writer.toString(); + assertEquals(expectedStr, actualStr); + } + + /** + * Exercise the JSONArray write(Appendable, int, int) method + */ +/* + @Test + public void write3ParamAppendable() { + String str0 = "[\"value1\",\"value2\",{\"key1\":1,\"key2\":false,\"key3\":3.14}]"; + String str2 = + "[\n" + + " \"value1\",\n" + + " \"value2\",\n" + + " {\n" + + " \"key1\": 1,\n" + + " \"key2\": false,\n" + + " \"key3\": 3.14\n" + + " }\n" + + " ]"; + JSONArray jsonArray = new JSONArray(str0); + String expectedStr = str0; StringBuilder stringBuilder = new StringBuilder(); Appendable appendable = jsonArray.write(stringBuilder, 0, 0); - actualStr = appendable.toString(); + String actualStr = appendable.toString(); assertEquals(expectedStr, actualStr); + expectedStr = str2; stringBuilder = new StringBuilder(); appendable = jsonArray.write(stringBuilder, 2, 1); actualStr = appendable.toString(); assertEquals(expectedStr, actualStr); } +*/ /** * Exercise JSONArray toString() method with various indent levels. diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 10405b0..df1b141 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -1916,18 +1916,30 @@ public class JSONObjectTest { Writer writer = jsonObject.write(stringWriter); String actualStr = writer.toString(); assertTrue("write() expected " +expectedStr+ - "but found " +actualStr, - expectedStr.equals(actualStr)); - StringBuilder stringBuilder = new StringBuilder(); - Appendable appendable = jsonObject.write(stringBuilder); - actualStr = appendable.toString(); - assertTrue("write() expected " +expectedStr+ - "but found " +actualStr, + " but found " +actualStr, expectedStr.equals(actualStr)); } /** - * Exercise the JSONObject write(Appendable, int, int) method + * Exercise the JSONObject write() method + */ +/* + @Test + public void writeAppendable() { + String str = "{\"key1\":\"value1\",\"key2\":[1,2,3]}"; + String expectedStr = str; + JSONObject jsonObject = new JSONObject(str); + StringBuilder stringBuilder = new StringBuilder(); + Appendable appendable = jsonObject.write(stringBuilder); + String actualStr = appendable.toString(); + assertTrue("write() expected " +expectedStr+ + " but found " +actualStr, + expectedStr.equals(actualStr)); + } +*/ + + /** + * Exercise the JSONObject write(Writer, int, int) method */ @Test public void write3Param() { @@ -1941,23 +1953,50 @@ public class JSONObjectTest { " 3.14\n" + " ]\n" + " }"; - String expectedStr = str0; JSONObject jsonObject = new JSONObject(str0); + String expectedStr = str0; StringWriter stringWriter = new StringWriter(); Writer writer = jsonObject.write(stringWriter,0,0); String actualStr = writer.toString(); assertEquals(expectedStr, actualStr); - expectedStr = str0; + + expectedStr = str2; + stringWriter = new StringWriter(); + writer = jsonObject.write(stringWriter,2,1); + actualStr = writer.toString(); + assertEquals(expectedStr, actualStr); + } + + /** + * Exercise the JSONObject write(Appendable, int, int) method + */ +/* + @Test + public void write3ParamAppendable() { + String str0 = "{\"key1\":\"value1\",\"key2\":[1,false,3.14]}"; + String str2 = + "{\n" + + " \"key1\": \"value1\",\n" + + " \"key2\": [\n" + + " 1,\n" + + " false,\n" + + " 3.14\n" + + " ]\n" + + " }"; + JSONObject jsonObject = new JSONObject(str0); + String expectedStr = str0; StringBuilder stringBuilder = new StringBuilder(); Appendable appendable = jsonObject.write(stringBuilder,0,0); - actualStr = appendable.toString(); + String actualStr = appendable.toString(); assertEquals(expectedStr, actualStr); + expectedStr = str2; stringBuilder = new StringBuilder(); appendable = jsonObject.write(stringBuilder,2,1); actualStr = appendable.toString(); assertEquals(expectedStr, actualStr); } +*/ /** * Exercise the JSONObject equals() method From efe33a1e370917ca571db5b95a0372b44a052afb Mon Sep 17 00:00:00 2001 From: Nicholas Cull Date: Sun, 24 Jul 2016 19:57:01 +1000 Subject: [PATCH 6/7] Fix comment. --- src/test/java/org/json/junit/JSONStringTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/json/junit/JSONStringTest.java b/src/test/java/org/json/junit/JSONStringTest.java index c7d9d3e..cba5d09 100644 --- a/src/test/java/org/json/junit/JSONStringTest.java +++ b/src/test/java/org/json/junit/JSONStringTest.java @@ -164,7 +164,7 @@ public class JSONStringTest { String output = jsonArray.write(writer).toString(); assertTrue("String values should be equal", "[\"the toString value\"]".equals(output)); - // The first different between writeValue() and valueToString(): + // The only different between writeValue() and valueToString(): // in this case, valueToString throws a JSONException try { output = JSONObject.valueToString(jsonString); From e57881f8fa9d81ccda83e17d2379f3597b0af213 Mon Sep 17 00:00:00 2001 From: run2000 Date: Mon, 25 Jul 2016 09:44:43 +1000 Subject: [PATCH 7/7] Fail when exceptions are not thrown as expected The idiom was started in the first few methods, but not continued further down where JSONException was expected. False success may have resulted. --- src/test/java/org/json/junit/JSONStringerTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/org/json/junit/JSONStringerTest.java b/src/test/java/org/json/junit/JSONStringerTest.java index d4376df..99cdd6f 100644 --- a/src/test/java/org/json/junit/JSONStringerTest.java +++ b/src/test/java/org/json/junit/JSONStringerTest.java @@ -60,6 +60,7 @@ public class JSONStringerTest { jsonStringer.object().endObject(); try { jsonStringer.array(); + assertTrue("Expected an exception", false); } catch (JSONException e) { assertTrue("Expected an exception message", "Misplaced array.". @@ -77,6 +78,7 @@ public class JSONStringerTest { jsonStringer.object(); try { jsonStringer.endArray(); + assertTrue("Expected an exception", false); } catch (JSONException e) { assertTrue("Expected an exception message", "Misplaced endArray.". @@ -94,6 +96,7 @@ public class JSONStringerTest { jsonStringer.array(); try { jsonStringer.endObject(); + assertTrue("Expected an exception", false); } catch (JSONException e) { assertTrue("Expected an exception message", "Misplaced endObject.". @@ -111,6 +114,7 @@ public class JSONStringerTest { jsonStringer.object().endObject(); try { jsonStringer.object(); + assertTrue("Expected an exception", false); } catch (JSONException e) { assertTrue("Expected an exception message", "Misplaced object.".