From c8563ff93daee506201b075faf203f726319afd7 Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Thu, 22 Sep 2016 12:38:30 -0400 Subject: [PATCH 01/16] new test case for XML changes --- src/test/java/org/json/junit/XMLTest.java | 31 ++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 2f3fea7..11c05d4 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -267,6 +267,35 @@ public void shouldHandleSimpleXML() { compareFileToJSONObject(xmlStr, expectedStr); } + /** + * Tests to verify that supported escapes in XML are converted to actual values. + */ + @Test + public void testXmlEscapeToJson(){ + String xmlStr = + "\n"+ + ""+ + "\""+ + "A €33"+ + "A €22€"+ + "some text ©"+ + "" " & ' < >"+ + ""; + String expectedStr = + "{\"root\":{" + + "\"rawQuote\":\"\\\"\"," + + "\"euro\":\"A €33\"," + + "\"euroX\":\"A €22€\"," + + "\"unknown\":\"some text ©\"," + + "\"known\":\"\\\" \\\" & ' < >\"" + + "}}"; + + compareStringToJSONObject(xmlStr, expectedStr); + compareReaderToJSONObject(xmlStr, expectedStr); + compareFileToJSONObject(xmlStr, expectedStr); + + } + /** * Valid XML with comments to JSONObject */ @@ -675,8 +704,8 @@ public void contentOperations() { * @param expectedStr the expected JSON string */ private void compareStringToJSONObject(String xmlStr, String expectedStr) { - JSONObject expectedJsonObject = new JSONObject(expectedStr); JSONObject jsonObject = XML.toJSONObject(xmlStr); + JSONObject expectedJsonObject = new JSONObject(expectedStr); Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); } From 5027a283c1b9c1bc81663441f0a0b23de48115cc Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Thu, 22 Sep 2016 13:09:32 -0400 Subject: [PATCH 02/16] Adds test for escaping from a JSONObject to XML --- src/test/java/org/json/junit/XMLTest.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 11c05d4..800dc93 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1,6 +1,7 @@ package org.json.junit; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -293,7 +294,19 @@ public void testXmlEscapeToJson(){ compareStringToJSONObject(xmlStr, expectedStr); compareReaderToJSONObject(xmlStr, expectedStr); compareFileToJSONObject(xmlStr, expectedStr); - + } + + /** + * Tests that certain unicode characters are escaped. + */ + @Test + public void testJsonToXmlEscape(){ + JSONObject json = new JSONObject("{ \"amount\": \"10,00 €\", \"description\": \"Ação Válida\" }"); + String xml = XML.toString(json); + assertFalse("Escaping € failed. Found in XML output.", xml.contains("€")); + assertTrue("Escaping ç failed. Not found in XML output.", xml.contains("ç")); + assertTrue("Escaping ã failed. Not found in XML output.", xml.contains("ã")); + assertTrue("Escaping á failed. Not found in XML output.", xml.contains("á")); } /** From 2b87f334d0343774a77b1779011eaba250a2a0c9 Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Thu, 22 Sep 2016 14:13:48 -0400 Subject: [PATCH 03/16] Update test cases to support ISO Control encoding changes. --- src/test/java/org/json/junit/XMLTest.java | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 800dc93..91ee420 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -297,16 +297,30 @@ public void testXmlEscapeToJson(){ } /** - * Tests that certain unicode characters are escaped. + * Tests that control characters are escaped. */ @Test public void testJsonToXmlEscape(){ - JSONObject json = new JSONObject("{ \"amount\": \"10,00 €\", \"description\": \"Ação Válida\" }"); + final String jsonSrc = "{\"amount\":\"10,00 €\"," + + "\"description\":\"Ação Válida\u0085\"," + + "\"xmlEntities\":\"\\\" ' & < >\"" + + "}"; + JSONObject json = new JSONObject(jsonSrc); String xml = XML.toString(json); - assertFalse("Escaping € failed. Found in XML output.", xml.contains("€")); + //test control character not existing + assertFalse("Escaping \u0085 failed. Found in XML output.", xml.contains("\u0085")); + assertTrue("Escaping \u0085 failed. Entity not found in XML output.", xml.contains("…")); + // test normal unicode existing + assertTrue("Escaping € failed. Not found in XML output.", xml.contains("€")); assertTrue("Escaping ç failed. Not found in XML output.", xml.contains("ç")); assertTrue("Escaping ã failed. Not found in XML output.", xml.contains("ã")); assertTrue("Escaping á failed. Not found in XML output.", xml.contains("á")); + // test XML Entities converted + assertTrue("Escaping \" failed. Not found in XML output.", xml.contains(""")); + assertTrue("Escaping ' failed. Not found in XML output.", xml.contains("'")); + assertTrue("Escaping & failed. Not found in XML output.", xml.contains("&")); + assertTrue("Escaping < failed. Not found in XML output.", xml.contains("<")); + assertTrue("Escaping > failed. Not found in XML output.", xml.contains(">")); } /** From f6a00e94c77e3b1ca6c74308696600502751efa4 Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Thu, 22 Sep 2016 16:12:00 -0400 Subject: [PATCH 04/16] adds test for unicode that has surrogate pairs --- src/test/java/org/json/junit/XMLTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 91ee420..264fa44 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -281,6 +281,7 @@ public void testXmlEscapeToJson(){ "A €22€"+ "some text ©"+ "" " & ' < >"+ + "𝄢 𐅥" + ""; String expectedStr = "{\"root\":{" + @@ -288,7 +289,8 @@ public void testXmlEscapeToJson(){ "\"euro\":\"A €33\"," + "\"euroX\":\"A €22€\"," + "\"unknown\":\"some text ©\"," + - "\"known\":\"\\\" \\\" & ' < >\"" + + "\"known\":\"\\\" \\\" & ' < >\"," + + "\"high\":\"𝄢 𐅥\""+ "}}"; compareStringToJSONObject(xmlStr, expectedStr); From d0ea807884728782b2bc1722ca4a79e56e58e245 Mon Sep 17 00:00:00 2001 From: stleary Date: Sat, 8 Dec 2018 14:51:01 -0600 Subject: [PATCH 05/16] xml parser config tests --- README.md | 39 +- .../java/org/json/junit/JunitTestSuite.java | 3 +- .../org/json/junit/XMLConfigurationTest.java | 930 ++++++++++++++++++ 3 files changed, 934 insertions(+), 38 deletions(-) create mode 100755 src/test/java/org/json/junit/XMLConfigurationTest.java diff --git a/README.md b/README.md index 1ca5c64..e6e61b5 100644 --- a/README.md +++ b/README.md @@ -89,43 +89,8 @@ Execution failed for task ':compileJava'. > invalid flag: -parameters ``` -A unit test has the following stages: - -| Test phase |Description | -|----|----| -| No test | No test specifically for this class has been written, or the class contains no executable code. | -| In progress | Unit tests have been started for this class. | -| Coverage > 90% | Initial goal of 90% coverage has been reached. Test quality may be questionable | -| Reasonable test cases | 90% coverage. Functionality and behavior has been confirmed | -| Checked against previous unit tests | Historical unit tests have been checked in case something important was missed | -| Completed | The unit test is completed | - - -| Test file name | Coverage | Comments | -| ------------- | ------------- | ---- | -| Total coverage | 90.6% | | | -| | | | -| CDL.java | 98.8% | Reasonable test cases. | -| Cookie.java | 98.9% | Reasonable test cases. | -| CookieList.java |96.5% | Reasonable test cases. | -| HTTP.java | 98.8%| Coverage > 90% | -| HTTPTokener.java |93.2% | No test | -| JSONArray.java |88.3% | Reasonable test cases. Need new tests for newer API functions | -| JSONException.java | 100% | No test | -| JSONML.java | 84.4%| In progress | -| JSONObject | 96.7% | Reasonable test cases | -| JSONObject.Null | 77.8% | No test | -| JSONPointer | 96.3% | Reasonable test cases | -| JSONPointerException | 100% | No test | -| JSONString.java | | No test | -| JSONStringer.java | 93.8%| Coverage > 90% | -| JSONTokener.java | 87.5% | In progress | -| JSONWriter.java | 89.15% | No test | -| Property.java | 95.8% | Coverage > 90% | -| XML.java | 77.3% | In progress | -| XMLTokener.java| 82.4%| No test | - -| Files used in test | + +| Resource files used in test | | ------------- | | EnumTest.java | | MyBean.java | diff --git a/src/test/java/org/json/junit/JunitTestSuite.java b/src/test/java/org/json/junit/JunitTestSuite.java index 9c9a325..68b5acb 100644 --- a/src/test/java/org/json/junit/JunitTestSuite.java +++ b/src/test/java/org/json/junit/JunitTestSuite.java @@ -18,7 +18,8 @@ EnumTest.class, JSONPointerTest.class, JSONStringTest.class, - JSONTokenerTest.class + JSONTokenerTest.class, + XMLConfigurationTest.class }) public class JunitTestSuite { } diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java new file mode 100755 index 0000000..a2d0b85 --- /dev/null +++ b/src/test/java/org/json/junit/XMLConfigurationTest.java @@ -0,0 +1,930 @@ +package org.json.junit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.XML; +import org.json.XMLParserConfiguration; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + + +/** + * Tests for JSON-Java XML.java with XMLParserConfiguration.java + */ +public class XMLConfigurationTest { + /** + * JUnit supports temporary files and folders that are cleaned up after the test. + * https://garygregory.wordpress.com/2010/01/20/junit-tip-use-rules-to-manage-temporary-files-and-folders/ + */ + @Rule + public TemporaryFolder testFolder = new TemporaryFolder(); + + /** + * JSONObject from a null XML string. + * Expects a NullPointerException + */ + @Test(expected=NullPointerException.class) + public void shouldHandleNullXML() { + String xmlStr = null; + JSONObject jsonObject = + XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS); + assertTrue("jsonObject should be empty", jsonObject.isEmpty()); + } + + /** + * Empty JSONObject from an empty XML string. + */ + @Test + public void shouldHandleEmptyXML() { + + String xmlStr = ""; + JSONObject jsonObject = + XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS); + assertTrue("jsonObject should be empty", jsonObject.isEmpty()); + } + + /** + * Empty JSONObject from a non-XML string. + */ + @Test + public void shouldHandleNonXML() { + String xmlStr = "{ \"this is\": \"not xml\"}"; + JSONObject jsonObject = + XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS); + assertTrue("xml string should be empty", jsonObject.isEmpty()); + } + + /** + * Invalid XML string (tag contains a frontslash). + * Expects a JSONException + */ + @Test + public void shouldHandleInvalidSlashInTag() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " \n"+ + " abc street\n"+ + "
\n"+ + "
"; + try { + XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS); + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertEquals("Expecting an exception message", + "Misshaped tag at 176 [character 14 line 4]", + e.getMessage()); + } + } + + /** + * Invalid XML string ('!' char in tag) + * Expects a JSONException + */ + @Test + public void shouldHandleInvalidBangInTag() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " \n"+ + " \n"+ + "
\n"+ + "
"; + try { + XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS); + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertEquals("Expecting an exception message", + "Misshaped meta tag at 214 [character 12 line 7]", + e.getMessage()); + } + } + + /** + * Invalid XML string ('!' char and no closing tag brace) + * Expects a JSONException + */ + @Test + public void shouldHandleInvalidBangNoCloseInTag() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " \n"+ + " \n"+ + ""; + try { + XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS); + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertEquals("Expecting an exception message", + "Misshaped meta tag at 213 [character 12 line 7]", + e.getMessage()); + } + } + + /** + * Invalid XML string (no end brace for tag) + * Expects JSONException + */ + @Test + public void shouldHandleNoCloseStartTag() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " \n"+ + " \n"+ + ""; + try { + XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS); + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertEquals("Expecting an exception message", + "Misplaced '<' at 193 [character 4 line 6]", + e.getMessage()); + } + } + + /** + * Invalid XML string (partial CDATA chars in tag name) + * Expects JSONException + */ + @Test + public void shouldHandleInvalidCDATABangInTag() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " Joe Tester\n"+ + " \n"+ + "
\n"+ + "
"; + try { + XMLParserConfiguration config = + new XMLParserConfiguration("altContent"); + XML.toJSONObject(xmlStr, config); + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertEquals("Expecting an exception message", + "Expected 'CDATA[' at 204 [character 11 line 5]", + e.getMessage()); + } + } + + /** + * Null JSONObject in XML.toString() + */ + @Test + public void shouldHandleNullJSONXML() { + JSONObject jsonObject= null; + String actualXml = XML.toString(jsonObject, null, + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("generated XML does not equal expected XML","\"null\"",actualXml); + } + + /** + * Empty JSONObject in XML.toString() + */ + @Test + public void shouldHandleEmptyJSONXML() { + JSONObject jsonObject= new JSONObject(); + String xmlStr = XML.toString(jsonObject, null, + XMLParserConfiguration.KEEP_STRINGS); + assertTrue("xml string should be empty", xmlStr.isEmpty()); + } + + /** + * No SML start tag. The ending tag ends up being treated as content. + */ + @Test + public void shouldHandleNoStartTag() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " \n"+ + " >\n"+ + "
\n"+ + "
"; + String expectedStr = + "{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+ + "content\":\">\"},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+ + "xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}"; + JSONObject jsonObject = XML.toJSONObject(xmlStr, + XMLParserConfiguration.KEEP_STRINGS); + JSONObject expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + } + + /** + * Valid XML to JSONObject + */ + @Test + public void shouldHandleSimpleXML() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " Joe Tester\n"+ + " [CDATA[Baker street 5]\n"+ + " \n"+ + " true\n"+ + " false\n"+ + " null\n"+ + " 42\n"+ + " -23\n"+ + " -23.45\n"+ + " -23x.45\n"+ + " 1, 2, 3, 4.1, 5.2\n"+ + "
\n"+ + "
"; + + String expectedStr = + "{\"addresses\":{\"address\":{\"street\":\"[CDATA[Baker street 5]\","+ + "\"name\":\"Joe Tester\",\"NothingHere\":\"\",TrueValue:true,\n"+ + "\"FalseValue\":false,\"NullValue\":null,\"PositiveValue\":42,\n"+ + "\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":-23x.45,\n"+ + "\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+ + "},\"xsi:noNamespaceSchemaLocation\":"+ + "\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+ + "XMLSchema-instance\"}}"; + + XMLParserConfiguration config = + new XMLParserConfiguration("altContent"); + compareStringToJSONObject(xmlStr, expectedStr, config); + compareReaderToJSONObject(xmlStr, expectedStr, config); + compareFileToJSONObject(xmlStr, expectedStr); + } + + /** + * Valid XML with comments to JSONObject + */ + @Test + public void shouldHandleCommentsInXML() { + + String xmlStr = + "\n"+ + "\n"+ + "\n"+ + "
\n"+ + " comment ]]>\n"+ + " Joe Tester\n"+ + " \n"+ + " Baker street 5\n"+ + "
\n"+ + "
"; + XMLParserConfiguration config = + new XMLParserConfiguration("altContent"); + JSONObject jsonObject = XML.toJSONObject(xmlStr, config); + String expectedStr = "{\"addresses\":{\"address\":{\"street\":\"Baker "+ + "street 5\",\"name\":\"Joe Tester\",\"altContent\":\" this is -- "+ + " comment \"}}}"; + JSONObject expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + } + + /** + * Valid XML to XML.toString() + */ + @Test + public void shouldHandleToString() { + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " [CDATA[Joe & T > e < s " t ' er]]\n"+ + " Baker street 5\n"+ + " 1, 2, 3, 4.1, 5.2\n"+ + "
\n"+ + "
"; + + String expectedStr = + "{\"addresses\":{\"address\":{\"street\":\"Baker street 5\","+ + "\"name\":\"[CDATA[Joe & T > e < s \\\" t \\\' er]]\","+ + "\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+ + "},\"xsi:noNamespaceSchemaLocation\":"+ + "\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+ + "XMLSchema-instance\"}}"; + + JSONObject jsonObject = XML.toJSONObject(xmlStr, + XMLParserConfiguration.KEEP_STRINGS); + String xmlToStr = XML.toString(jsonObject, null, + XMLParserConfiguration.KEEP_STRINGS); + JSONObject finalJsonObject = XML.toJSONObject(xmlToStr, + XMLParserConfiguration.KEEP_STRINGS); + JSONObject expectedJsonObject = new JSONObject(expectedStr); + Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject); + } + + /** + * Converting a JSON doc containing '>' content to JSONObject, then + * XML.toString() should result in valid XML. + */ + @Test + public void shouldHandleContentNoArraytoString() { + String expectedStr = + "{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+ + "altContent\":\">\"},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+ + "xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}"; + JSONObject expectedJsonObject = new JSONObject(expectedStr); + XMLParserConfiguration config = new XMLParserConfiguration("altContent"); + String finalStr = XML.toString(expectedJsonObject, null, config); + String expectedFinalStr = "
>"+ + "
test.xsdhttp://www.w3.org/2001/XMLSche"+ + "ma-instance
"; + assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+ + finalStr+"]", expectedFinalStr.equals(finalStr)); + } + + /** + * Converting a JSON doc containing a 'content' array to JSONObject, then + * XML.toString() should result in valid XML. + * TODO: This is probably an error in how the 'content' keyword is used. + */ + @Test + public void shouldHandleContentArraytoString() { + String expectedStr = + "{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+ + "altContent\":[1, 2, 3]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+ + "xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}"; + JSONObject expectedJsonObject = new JSONObject(expectedStr); + XMLParserConfiguration config = new XMLParserConfiguration("altContent"); + String finalStr = XML.toString(expectedJsonObject, null, config); + String expectedFinalStr = "
"+ + "1\n2\n3"+ + "
test.xsdhttp://www.w3.org/2001/XMLSche"+ + "ma-instance
"; + assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+ + finalStr+"]", expectedFinalStr.equals(finalStr)); + } + + /** + * Converting a JSON doc containing a named array to JSONObject, then + * XML.toString() should result in valid XML. + */ + @Test + public void shouldHandleArraytoString() { + String expectedStr = + "{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\","+ + "\"something\":[1, 2, 3]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+ + "xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}"; + JSONObject expectedJsonObject = new JSONObject(expectedStr); + String finalStr = XML.toString(expectedJsonObject, null, + XMLParserConfiguration.KEEP_STRINGS); + String expectedFinalStr = "
"+ + "123"+ + "
test.xsdhttp://www.w3.org/2001/XMLSche"+ + "ma-instance
"; + assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+ + finalStr+"]", expectedFinalStr.equals(finalStr)); + } + + /** + * Tests that the XML output for empty arrays is consistent. + */ + @Test + public void shouldHandleEmptyArray(){ + final JSONObject jo1 = new JSONObject(); + jo1.put("array",new Object[]{}); + final JSONObject jo2 = new JSONObject(); + jo2.put("array",new JSONArray()); + + final String expected = ""; + String output1 = XML.toString(jo1, "jo", + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("Expected an empty root tag", expected, output1); + String output2 = XML.toString(jo2, "jo", + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("Expected an empty root tag", expected, output2); + } + + /** + * Tests that the XML output for arrays is consistent when an internal array is empty. + */ + @Test + public void shouldHandleEmptyMultiArray(){ + final JSONObject jo1 = new JSONObject(); + jo1.put("arr",new Object[]{"One", new String[]{}, "Four"}); + final JSONObject jo2 = new JSONObject(); + jo2.put("arr",new JSONArray(new Object[]{"One", new JSONArray(new String[]{}), "Four"})); + + final String expected = "OneFour"; + String output1 = XML.toString(jo1, "jo", + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("Expected a matching array", expected, output1); + String output2 = XML.toString(jo2, "jo", + XMLParserConfiguration.KEEP_STRINGS); + + assertEquals("Expected a matching array", expected, output2); + } + + /** + * Tests that the XML output for arrays is consistent when arrays are not empty. + */ + @Test + public void shouldHandleNonEmptyArray(){ + final JSONObject jo1 = new JSONObject(); + jo1.put("arr",new String[]{"One", "Two", "Three"}); + final JSONObject jo2 = new JSONObject(); + jo2.put("arr",new JSONArray(new String[]{"One", "Two", "Three"})); + + final String expected = "OneTwoThree"; + String output1 = XML.toString(jo1, "jo", + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("Expected a non empty root tag", expected, output1); + String output2 = XML.toString(jo2, "jo", + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("Expected a non empty root tag", expected, output2); + } + + /** + * Tests that the XML output for arrays is consistent when arrays are not empty and contain internal arrays. + */ + @Test + public void shouldHandleMultiArray(){ + final JSONObject jo1 = new JSONObject(); + jo1.put("arr",new Object[]{"One", new String[]{"Two", "Three"}, "Four"}); + final JSONObject jo2 = new JSONObject(); + jo2.put("arr",new JSONArray(new Object[]{"One", new JSONArray(new String[]{"Two", "Three"}), "Four"})); + + final String expected = "OneTwoThreeFour"; + String output1 = XML.toString(jo1, "jo", + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("Expected a matching array", expected, output1); + String output2 = XML.toString(jo2, "jo", + XMLParserConfiguration.KEEP_STRINGS); + assertEquals("Expected a matching array", expected, output2); + } + + /** + * Converting a JSON doc containing a named array of nested arrays to + * JSONObject, then XML.toString() should result in valid XML. + */ + @Test + public void shouldHandleNestedArraytoString() { + String xmlStr = + "{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\","+ + "\"outer\":[[1], [2], [3]]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+ + "xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}"; + JSONObject jsonObject = new JSONObject(xmlStr); + String finalStr = XML.toString(jsonObject, null, + XMLParserConfiguration.ORIGINAL); + JSONObject finalJsonObject = XML.toJSONObject(finalStr); + String expectedStr = "
"+ + "12"+ + "3"+ + "
test.xsdhttp://www.w3.org/2001/XMLSche"+ + "ma-instance
"; + JSONObject expectedJsonObject = XML.toJSONObject(expectedStr, + XMLParserConfiguration.ORIGINAL); + Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject); + } + + + /** + * Possible bug: + * Illegal node-names must be converted to legal XML-node-names. + * The given example shows 2 nodes which are valid for JSON, but not for XML. + * Therefore illegal arguments should be converted to e.g. an underscore (_). + */ + @Test + public void shouldHandleIllegalJSONNodeNames() + { + JSONObject inputJSON = new JSONObject(); + inputJSON.append("123IllegalNode", "someValue1"); + inputJSON.append("Illegal@node", "someValue2"); + + String result = XML.toString(inputJSON, null, + XMLParserConfiguration.KEEP_STRINGS); + + /* + * This is invalid XML. Names should not begin with digits or contain + * certain values, including '@'. One possible solution is to replace + * illegal chars with '_', in which case the expected output would be: + * <___IllegalNode>someValue1someValue2 + */ + String expected = "<123IllegalNode>someValue1someValue2"; + + assertEquals(expected, result); + } + + /** + * JSONObject with NULL value, to XML.toString() + */ + @Test + public void shouldHandleNullNodeValue() + { + JSONObject inputJSON = new JSONObject(); + inputJSON.put("nullValue", JSONObject.NULL); + // This is a possible preferred result + // String expectedXML = ""; + /** + * This is the current behavior. JSONObject.NULL is emitted as + * the string, "null". + */ + String actualXML = "null"; + String resultXML = XML.toString(inputJSON, null, + XMLParserConfiguration.KEEP_STRINGS); + assertEquals(actualXML, resultXML); + } + + /** + * Investigate exactly how the "content" keyword works + */ + @Test + public void contentOperations() { + /* + * When a standalone 0) then return]]>"; + JSONObject jsonObject = XML.toJSONObject(xmlStr, + XMLParserConfiguration.KEEP_STRINGS); + assertTrue("1. 3 items", 3 == jsonObject.length()); + assertTrue("1. empty tag1", "".equals(jsonObject.get("tag1"))); + assertTrue("1. empty tag2", "".equals(jsonObject.get("tag2"))); + assertTrue("1. content found", "if (a < b && a > 0) then return".equals(jsonObject.get("content"))); + + // multiple consecutive standalone cdatas are accumulated into an array + xmlStr = " 0) then return]]>"; + jsonObject = XML.toJSONObject(xmlStr, + new XMLParserConfiguration(true, "altContent")); + assertTrue("2. 3 items", 3 == jsonObject.length()); + assertTrue("2. empty tag1", "".equals(jsonObject.get("tag1"))); + assertTrue("2. empty tag2", "".equals(jsonObject.get("tag2"))); + assertTrue("2. content array found", jsonObject.get("altContent") instanceof JSONArray); + JSONArray jsonArray = jsonObject.getJSONArray("altContent"); + assertTrue("2. array size", jsonArray.length() == 2); + assertTrue("2. content array entry 0", "if (a < b && a > 0) then return".equals(jsonArray.get(0))); + assertTrue("2. content array entry 1", "here is another cdata".equals(jsonArray.get(1))); + + /* + * text content is accumulated in a "content" inside a local JSONObject. + * If there is only one instance, it is saved in the context (a different JSONObject + * from the calling code. and the content element is discarded. + */ + xmlStr = "value 1"; + jsonObject = XML.toJSONObject(xmlStr, + new XMLParserConfiguration(true, "altContent")); + assertTrue("3. 2 items", 1 == jsonObject.length()); + assertTrue("3. value tag1", "value 1".equals(jsonObject.get("tag1"))); + + /* + * array-style text content (multiple tags with the same name) is + * accumulated in a local JSONObject with key="content" and value=JSONArray, + * saved in the context, and then the local JSONObject is discarded. + */ + xmlStr = "value 12true"; + jsonObject = XML.toJSONObject(xmlStr, + new XMLParserConfiguration(true, "altContent")); + assertTrue("4. 1 item", 1 == jsonObject.length()); + assertTrue("4. content array found", jsonObject.get("tag1") instanceof JSONArray); + jsonArray = jsonObject.getJSONArray("tag1"); + assertTrue("4. array size", jsonArray.length() == 3); + assertTrue("4. content array entry 0", "value 1".equals(jsonArray.get(0))); + assertTrue("4. content array entry 1", jsonArray.getInt(1) == 2); + assertTrue("4. content array entry 2", jsonArray.getBoolean(2) == true); + + /* + * Complex content is accumulated in a "content" field. For example, an element + * may contain a mix of child elements and text. Each text segment is + * accumulated to content. + */ + xmlStr = "val1val2"; + jsonObject = XML.toJSONObject(xmlStr, + new XMLParserConfiguration(true, "altContent")); + assertTrue("5. 1 item", 1 == jsonObject.length()); + assertTrue("5. jsonObject found", jsonObject.get("tag1") + instanceof JSONObject); + jsonObject = jsonObject.getJSONObject("tag1"); + assertTrue("5. 2 contained items", 2 == jsonObject.length()); + assertTrue("5. contained tag", "".equals(jsonObject.get("tag2"))); + assertTrue("5. contained content jsonArray found", + jsonObject.get("altContent") instanceof JSONArray); + jsonArray = jsonObject.getJSONArray("altContent"); + assertTrue("5. array size", jsonArray.length() == 2); + assertTrue("5. content array entry 0", "val1".equals(jsonArray.get(0))); + assertTrue("5. content array entry 1", "val2".equals(jsonArray.get(1))); + + /* + * If there is only 1 complex text content, then it is accumulated in a + * "content" field as a string. + */ + xmlStr = "val1"; + jsonObject = XML.toJSONObject(xmlStr, + new XMLParserConfiguration(true, "altContent")); + assertTrue("6. 1 item", 1 == jsonObject.length()); + assertTrue("6. jsonObject found", jsonObject.get("tag1") instanceof JSONObject); + jsonObject = jsonObject.getJSONObject("tag1"); + assertTrue("6. contained content found", + "val1".equals(jsonObject.get("altContent"))); + assertTrue("6. contained tag2", "".equals(jsonObject.get("tag2"))); + + /* + * In this corner case, the content sibling happens to have key=content + * We end up with an array within an array, and no content element. + * This is probably a bug. + */ + xmlStr = "val1"; + jsonObject = XML.toJSONObject(xmlStr, + new XMLParserConfiguration(true, "altContent")); + assertTrue("7. 1 item", 1 == jsonObject.length()); + assertTrue("7. jsonArray found", + jsonObject.get("tag1") instanceof JSONArray); + jsonArray = jsonObject.getJSONArray("tag1"); + assertTrue("array size 1", jsonArray.length() == 1); + assertTrue("7. contained array found", jsonArray.get(0) + instanceof JSONArray); + jsonArray = jsonArray.getJSONArray(0); + assertTrue("7. inner array size 2", jsonArray.length() == 2); + assertTrue("7. inner array item 0", "val1".equals(jsonArray.get(0))); + assertTrue("7. inner array item 1", "".equals(jsonArray.get(1))); + + /* + * Confirm behavior of original issue + */ + String jsonStr = + "{"+ + "\"Profile\": {"+ + "\"list\": {"+ + "\"history\": {"+ + "\"entries\": ["+ + "{"+ + "\"deviceId\": \"id\","+ + "\"altContent\": {"+ + "\"material\": ["+ + "{"+ + "\"stuff\": false"+ + "}"+ + "]"+ + "}"+ + "}"+ + "]"+ + "}"+ + "}"+ + "}"+ + "}"; + jsonObject = new JSONObject(jsonStr); + xmlStr = XML.toString(jsonObject, null, + new XMLParserConfiguration(true, "altContent")); + /* + * This is the created XML. Looks like content was mistaken for + * complex (child node + text) XML. + * + * + * + * + * id + * {"material":[{"stuff":false}]} + * + * + * + * + */ + assertTrue("nothing to test here, see comment on created XML, above", true); + } + + /** + * JSON string lost leading zero and converted "True" to true. + */ + @Test + public void testToJSONArray_jsonOutput() { + final String originalXml = "011000True"; + final String expectedJsonString = "{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}"; + final JSONObject actualJsonOutput = XML.toJSONObject(originalXml, + new XMLParserConfiguration(false)); + assertEquals(expectedJsonString, actualJsonOutput.toString()); + } + + /** + * JSON string cannot be reverted to original xml. + */ + @Test + public void testToJSONArray_reversibility() { + final String originalXml = "011000True"; + XMLParserConfiguration config = new XMLParserConfiguration(false); + final String revertedXml = + XML.toString(XML.toJSONObject(originalXml, config), + null, config); + assertNotEquals(revertedXml, originalXml); + } + + /** + * test passes when using the new method toJsonArray. + */ + @Test + public void testToJsonXML() { + final String originalXml = "011000True"; + final String expectedJsonString = "{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",\"1\",\"00\",\"0\"],\"title\":\"True\"}}"; + + final JSONObject json = XML.toJSONObject(originalXml, + new XMLParserConfiguration(true)); + assertEquals(expectedJsonString, json.toString()); + + final String reverseXml = XML.toString(json); + // this reversal isn't exactly the same. use JSONML for an exact reversal + final String expectedReverseXml = "01011000True"; + + assertEquals(expectedReverseXml, reverseXml); + } + + /** + * test to validate certain conditions of XML unescaping. + */ + @Test + public void testUnescape() { + assertEquals("{\"xml\":\"Can cope <;\"}", + XML.toJSONObject("Can cope <; ", + XMLParserConfiguration.KEEP_STRINGS).toString()); + assertEquals("Can cope <; ", XML.unescape("Can cope <; ")); + + assertEquals("{\"xml\":\"Can cope & ;\"}", + XML.toJSONObject("Can cope & ; ", + XMLParserConfiguration.KEEP_STRINGS).toString()); + assertEquals("Can cope & ; ", XML.unescape("Can cope & ; ")); + + assertEquals("{\"xml\":\"Can cope &;\"}", + XML.toJSONObject("Can cope &; ", + XMLParserConfiguration.KEEP_STRINGS).toString()); + assertEquals("Can cope &; ", XML.unescape("Can cope &; ")); + + // unicode entity + assertEquals("{\"xml\":\"Can cope 4;\"}", + XML.toJSONObject("Can cope 4; ", + XMLParserConfiguration.KEEP_STRINGS).toString()); + assertEquals("Can cope 4; ", XML.unescape("Can cope 4; ")); + + // double escaped + assertEquals("{\"xml\":\"Can cope <\"}", + XML.toJSONObject("Can cope &lt; ", + XMLParserConfiguration.KEEP_STRINGS).toString()); + assertEquals("Can cope < ", XML.unescape("Can cope &lt; ")); + + assertEquals("{\"xml\":\"Can cope 4\"}", + XML.toJSONObject("Can cope &#x34; ", + XMLParserConfiguration.KEEP_STRINGS).toString()); + assertEquals("Can cope 4 ", XML.unescape("Can cope &#x34; ")); + + } + + /** + * Confirm XMLParserConfiguration functionality + */ + @Test + public void testConfig() { + /** + * 1st param is whether to keep the raw string, or call + * XML.stringToValue(), which may convert the token to + * boolean, null, or number. + * 2nd param is what JSON name to use for strings that are + * evaluated as xml content data in complex objects, e.g. + * + * value + * content data + * + */ + + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " content 1\n"+ + " Sherlock Holmes\n"+ + " content 2\n"+ + " Baker street 5\n"+ + " content 3\n"+ + " 1\n"+ + "
\n"+ + "
"; + + // keep strings, use the altContent tag + XMLParserConfiguration config = + new XMLParserConfiguration(true, "altContent"); + JSONObject jsonObject = XML.toJSONObject(xmlStr, config); + // num is parsed as a string + assertEquals(jsonObject.getJSONObject("addresses"). + getJSONObject("address").getString("num"), "1"); + // complex content is collected in an 'altContent' array + JSONArray jsonArray = jsonObject.getJSONObject("addresses"). + getJSONObject("address").getJSONArray("altContent"); + String expectedStr = "[\"content 1\", \"content 2\", \"content 3\"]"; + JSONArray expectedJsonArray = new JSONArray(expectedStr); + Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); + + // keepstrings only + jsonObject = XML.toJSONObject(xmlStr, + XMLParserConfiguration.KEEP_STRINGS); + // num is parsed as a string + assertEquals(jsonObject.getJSONObject("addresses"). + getJSONObject("address").getString("num"), "1"); + // complex content is collected in an 'content' array + jsonArray = jsonObject.getJSONObject("addresses"). + getJSONObject("address").getJSONArray("content"); + expectedJsonArray = new JSONArray(expectedStr); + Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); + + // use alternate content name + config = new XMLParserConfiguration("altContent"); + jsonObject = XML.toJSONObject(xmlStr, config); + // num is parsed as a number + assertEquals(jsonObject.getJSONObject("addresses"). + getJSONObject("address").getInt("num"), 1); + // complex content is collected in an 'altContent' array + jsonArray = jsonObject.getJSONObject("addresses"). + getJSONObject("address").getJSONArray("altContent"); + expectedJsonArray = new JSONArray(expectedStr); + Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); + + } + + + /** + * Convenience method, given an input string and expected result, + * convert to JSONObject and compare actual to expected result. + * @param xmlStr the string to parse + * @param expectedStr the expected JSON string + * @param config provides more flexible XML parsing + * flexible XML parsing. + */ + private void compareStringToJSONObject(String xmlStr, String expectedStr, + XMLParserConfiguration config) { + JSONObject expectedJsonObject = new JSONObject(expectedStr); + JSONObject jsonObject = XML.toJSONObject(xmlStr, config); + Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + } + + /** + * Convenience method, given an input string and expected result, + * convert to JSONObject via reader and compare actual to expected result. + * @param xmlStr the string to parse + * @param expectedStr the expected JSON string + * @param config provides more flexible XML parsing + */ + private void compareReaderToJSONObject(String xmlStr, String expectedStr, + XMLParserConfiguration config) { + /* + * Commenting out this method until the JSON-java code is updated + * to support XML.toJSONObject(reader) + JSONObject expectedJsonObject = new JSONObject(expectedStr); + Reader reader = new StringReader(xmlStr); + JSONObject jsonObject = XML.toJSONObject(reader); + Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + */ + } + + /** + * Convenience method, given an input string and expected result, convert to + * JSONObject via file and compare actual to expected result. + * + * @param xmlStr + * the string to parse + * @param expectedStr + * the expected JSON string + * @throws IOException + */ + private void compareFileToJSONObject(String xmlStr, String expectedStr) { + /* + * Commenting out this method until the JSON-java code is updated + * to support XML.toJSONObject(reader) + try { + JSONObject expectedJsonObject = new JSONObject(expectedStr); + File tempFile = testFolder.newFile("fileToJSONObject.xml"); + FileWriter fileWriter = new FileWriter(tempFile); + fileWriter.write(xmlStr); + fileWriter.close(); + Reader reader = new FileReader(tempFile); + JSONObject jsonObject = XML.toJSONObject(reader); + Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + } catch (IOException e) { + assertTrue("file writer error: " +e.getMessage(), false); + } + */ + } +} \ No newline at end of file From e7f7d348cd13e2e6d168e13398f6d7384294cc2a Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Mon, 10 Dec 2018 11:45:10 -0500 Subject: [PATCH 06/16] * updates tests to cover more cases of tokenizing * uncomments tests that should now work --- src/test/java/org/json/junit/CDLTest.java | 10 +- .../java/org/json/junit/JSONTokenerTest.java | 94 +++++++++++++++++++ src/test/java/org/json/junit/XMLTest.java | 32 +++---- 3 files changed, 115 insertions(+), 21 deletions(-) diff --git a/src/test/java/org/json/junit/CDLTest.java b/src/test/java/org/json/junit/CDLTest.java index b1f9561..721fd3c 100644 --- a/src/test/java/org/json/junit/CDLTest.java +++ b/src/test/java/org/json/junit/CDLTest.java @@ -30,7 +30,7 @@ public class CDLTest { ); /** - * CDL.toJSONArray() adds all values asstrings, with no filtering or + * CDL.toJSONArray() adds all values as strings, with no filtering or * conversions. For testing, this means that the expected JSONObject * values all must be quoted in the cases where the JSONObject parsing * might normally convert the value into a non-string. @@ -264,8 +264,8 @@ public void checkSpecialChars() { */ @Test public void textToJSONArray() { - JSONArray jsonArray = CDL.toJSONArray(lines); - JSONArray expectedJsonArray = new JSONArray(expectedLines); + JSONArray jsonArray = CDL.toJSONArray(this.lines); + JSONArray expectedJsonArray = new JSONArray(this.expectedLines); Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); } @@ -289,10 +289,10 @@ public void jsonArrayToJSONArray() { */ @Test public void textToJSONArrayAndBackToString() { - JSONArray jsonArray = CDL.toJSONArray(lines); + JSONArray jsonArray = CDL.toJSONArray(this.lines); String jsonStr = CDL.toString(jsonArray); JSONArray finalJsonArray = CDL.toJSONArray(jsonStr); - JSONArray expectedJsonArray = new JSONArray(expectedLines); + JSONArray expectedJsonArray = new JSONArray(this.expectedLines); Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray); } diff --git a/src/test/java/org/json/junit/JSONTokenerTest.java b/src/test/java/org/json/junit/JSONTokenerTest.java index dced89f..de1564d 100644 --- a/src/test/java/org/json/junit/JSONTokenerTest.java +++ b/src/test/java/org/json/junit/JSONTokenerTest.java @@ -12,7 +12,9 @@ import java.io.Reader; import java.io.StringReader; +import org.json.JSONArray; import org.json.JSONException; +import org.json.JSONObject; import org.json.JSONTokener; import org.junit.Test; @@ -64,7 +66,99 @@ public void verifyBackFailureDoubleBack() throws IOException { } } } + + @Test + public void testValid() { + checkValid("0",Number.class); + checkValid(" 0 ",Number.class); + checkValid("23",Number.class); + checkValid("23.5",Number.class); + checkValid(" 23.5 ",Number.class); + checkValid("null",null); + checkValid(" null ",null); + checkValid("true",Boolean.class); + checkValid(" true\n",Boolean.class); + checkValid("false",Boolean.class); + checkValid("\nfalse ",Boolean.class); + checkValid("{}",JSONObject.class); + checkValid(" {} ",JSONObject.class); + checkValid("{\"a\":1}",JSONObject.class); + checkValid(" {\"a\":1} ",JSONObject.class); + checkValid("[]",JSONArray.class); + checkValid(" [] ",JSONArray.class); + checkValid("[1,2]",JSONArray.class); + checkValid("\n\n[1,2]\n\n",JSONArray.class); + checkValid("1 2", String.class); + } + + @Test + public void testErrors() { + // Check that stream can detect that a value is found after + // the first one + checkError(" { \"a\":1 } 4 "); + checkError("null \"a\""); + checkError("{} true"); + } + + private Object checkValid(String testStr, Class aClass) { + Object result = nextValue(testStr); + // Check class of object returned + if( null == aClass ) { + if(JSONObject.NULL.equals(result)) { + // OK + } else { + throw new JSONException("Unexpected class: "+result.getClass().getSimpleName()); + } + } else { + if( null == result ) { + throw new JSONException("Unexpected null result"); + } else if(!aClass.isAssignableFrom(result.getClass()) ) { + throw new JSONException("Unexpected class: "+result.getClass().getSimpleName()); + } + } + + return result; + } + + private void checkError(String testStr) { + try { + nextValue(testStr); + + fail("Error should be triggered: (\""+testStr+"\")"); + } catch (JSONException e) { + // OK + } + } + + /** + * Verifies that JSONTokener can read a stream that contains a value. After + * the reading is done, check that the stream is left in the correct state + * by reading the characters after. All valid cases should reach end of stream. + * @param testStr + * @return + * @throws Exception + */ + private Object nextValue(String testStr) throws JSONException { + try(StringReader sr = new StringReader(testStr);){ + JSONTokener tokener = new JSONTokener(sr); + + Object result = tokener.nextValue(); + + if( result == null ) { + throw new JSONException("Unable to find value token in JSON stream: ("+tokener+"): "+testStr); + } + + char c = tokener.nextClean(); + if( 0 != c ) { + throw new JSONException("Unexpected character found at end of JSON stream: "+c+ " ("+tokener+"): "+testStr); + } + + return result; + } + + } + /** * Tests the failure of the skipTo method with a buffered reader. Preferably * we'd like this not to fail but at this time we don't have a good recovery. diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 1cff326..83a7cc2 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -6,6 +6,13 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -743,14 +750,10 @@ private void compareStringToJSONObject(String xmlStr, String expectedStr) { * @param expectedStr the expected JSON string */ private void compareReaderToJSONObject(String xmlStr, String expectedStr) { - /* - * Commenting out this method until the JSON-java code is updated - * to support XML.toJSONObject(reader) JSONObject expectedJsonObject = new JSONObject(expectedStr); Reader reader = new StringReader(xmlStr); JSONObject jsonObject = XML.toJSONObject(reader); Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); - */ } /** @@ -764,22 +767,19 @@ private void compareReaderToJSONObject(String xmlStr, String expectedStr) { * @throws IOException */ private void compareFileToJSONObject(String xmlStr, String expectedStr) { - /* - * Commenting out this method until the JSON-java code is updated - * to support XML.toJSONObject(reader) try { JSONObject expectedJsonObject = new JSONObject(expectedStr); - File tempFile = testFolder.newFile("fileToJSONObject.xml"); - FileWriter fileWriter = new FileWriter(tempFile); - fileWriter.write(xmlStr); - fileWriter.close(); - Reader reader = new FileReader(tempFile); - JSONObject jsonObject = XML.toJSONObject(reader); - Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + File tempFile = this.testFolder.newFile("fileToJSONObject.xml"); + try(FileWriter fileWriter = new FileWriter(tempFile);){ + fileWriter.write(xmlStr); + } + try(Reader reader = new FileReader(tempFile);){ + JSONObject jsonObject = XML.toJSONObject(reader); + Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); + } } catch (IOException e) { - assertTrue("file writer error: " +e.getMessage(), false); + fail("file writer error: " +e.getMessage()); } - */ } /** From 614e8359b91eb997142d313a0469aa69b707394e Mon Sep 17 00:00:00 2001 From: meiskalt7 Date: Thu, 18 Apr 2019 21:42:57 +0700 Subject: [PATCH 07/16] add test for xsi:nil to null conversion --- src/test/java/org/json/junit/XMLTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 83a7cc2..195f706 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -17,6 +17,7 @@ import org.json.JSONException; import org.json.JSONObject; import org.json.XML; +import org.json.XMLParserConfiguration; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -856,4 +857,15 @@ public void testUnescape() { } + /** + * test passes when xsi:nil="true" converting to null (JSON specification-like conversion) + */ + @Test + public void testToJsonWithNull() { + final String originalXml = ""; + final String expectedJsonString = "{\"root\":{\"id\":null}}"; + + final JSONObject json = XML.toJSONObject(originalXml,new XMLParserConfiguration(false, "content", true)); + assertEquals(expectedJsonString, json.toString()); + } } \ No newline at end of file From fa173fa51a61ba68c5c721c3170869f5ae93a927 Mon Sep 17 00:00:00 2001 From: meiskalt7 Date: Sun, 21 Apr 2019 00:53:39 +0700 Subject: [PATCH 08/16] add test for xsi:nil to null conversion disabled --- src/test/java/org/json/junit/XMLTest.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 195f706..b74daff 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -858,14 +858,26 @@ public void testUnescape() { } /** - * test passes when xsi:nil="true" converting to null (JSON specification-like conversion) + * test passes when xsi:nil="true" converting to null (JSON specification-like nil conversion enabled) */ @Test - public void testToJsonWithNull() { + public void testToJsonWithNullWhenNilConversionEnabled() { final String originalXml = ""; final String expectedJsonString = "{\"root\":{\"id\":null}}"; - final JSONObject json = XML.toJSONObject(originalXml,new XMLParserConfiguration(false, "content", true)); + final JSONObject json = XML.toJSONObject(originalXml, new XMLParserConfiguration(false, "content", true)); + assertEquals(expectedJsonString, json.toString()); + } + + /** + * test passes when xsi:nil="true" not converting to null (JSON specification-like nil conversion disabled) + */ + @Test + public void testToJsonWithNullWhenNilConversionDisabled() { + final String originalXml = ""; + final String expectedJsonString = "{\"root\":{\"id\":{\"xsi:nil\":true}}}"; + + final JSONObject json = XML.toJSONObject(originalXml, new XMLParserConfiguration()); assertEquals(expectedJsonString, json.toString()); } } \ No newline at end of file From 3e7a0b13d1c2ed0b18d5ba143ddaaf171c72932a Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Tue, 17 Sep 2019 10:36:48 -0400 Subject: [PATCH 09/16] new test case for issue 484 --- src/test/java/org/json/junit/JSONMLTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 84b33ba..26f4f90 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -803,4 +803,16 @@ public void testToJSONObject_reversibility() { // // assertEquals(expectedJsonString, actualJsonString); // } + + @Test (timeout = 6000) + public void testIssue484InfinteLoop() { + try { + JSONML.toJSONObject("??*^M??|?CglR^F??`??>?w??PIlr^E??D^X^]?$?-^R?o??O?*??{OD?^FY??`2a????NM?b^Tq?:O?>S$^K?J?^FB.gUK?m^H??zE??^??!v]?^A???^[^A??^U?c??????h???s???g^Z???`?q^Dbi??:^QZl?)?}1^??k?0??:$V?$?Ovs(}J??^V????2;^QgQ?^_^A?^D?^U?Tg?K?`?h%c?hmGA? Date: Tue, 17 Sep 2019 10:47:16 -0400 Subject: [PATCH 10/16] Test cases updates for standardized exception messages --- src/test/java/org/json/junit/JSONArrayTest.java | 8 ++++---- src/test/java/org/json/junit/JSONMLTest.java | 6 +++--- src/test/java/org/json/junit/JSONObjectTest.java | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 3b70446..5aef340 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -346,14 +346,14 @@ public void failedGetArrayValues() { assertTrue("expected getDouble to fail", false); } catch (JSONException e) { assertEquals("Expected an exception message", - "JSONArray[4] is not a number.",e.getMessage()); + "JSONArray[4] is not a double.",e.getMessage()); } try { jsonArray.getInt(4); assertTrue("expected getInt to fail", false); } catch (JSONException e) { assertEquals("Expected an exception message", - "JSONArray[4] is not a number.",e.getMessage()); + "JSONArray[4] is not a int.",e.getMessage()); } try { jsonArray.getJSONArray(4); @@ -374,14 +374,14 @@ public void failedGetArrayValues() { assertTrue("expected getLong to fail", false); } catch (JSONException e) { assertEquals("Expected an exception message", - "JSONArray[4] is not a number.",e.getMessage()); + "JSONArray[4] is not a long.",e.getMessage()); } try { jsonArray.getString(5); assertTrue("expected getString to fail", false); } catch (JSONException e) { assertEquals("Expected an exception message", - "JSONArray[5] not a string.",e.getMessage()); + "JSONArray[5] is not a String.",e.getMessage()); } } diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 84b33ba..fe3cd87 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -133,9 +133,9 @@ public void emptyTagException() { JSONML.toString(jsonArray); assertTrue("Expecting an exception", false); } catch (JSONException e) { - assertTrue("Expecting an exception message", - "JSONArray[0] not a string.". - equals(e.getMessage())); + assertEquals("Expecting an exception message", + "JSONArray[0] is not a String.", + e.getMessage()); } } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 8d32649..ac67980 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -1041,7 +1041,7 @@ public void jsonObjectNonAndWrongValues() { fail("Expected an exception"); } catch (JSONException e) { assertEquals("Expecting an exception message", - "JSONObject[\"trueKey\"] not a string.", + "JSONObject[\"trueKey\"] is not a string.", e.getMessage()); } try { @@ -1057,7 +1057,7 @@ public void jsonObjectNonAndWrongValues() { fail("Expected an exception"); } catch (JSONException e) { assertEquals("Expecting an exception message", - "JSONObject[\"stringKey\"] is not a number.", + "JSONObject[\"stringKey\"] is not a double.", e.getMessage()); } try { @@ -1073,7 +1073,7 @@ public void jsonObjectNonAndWrongValues() { fail("Expected an exception"); } catch (JSONException e) { assertEquals("Expecting an exception message", - "JSONObject[\"stringKey\"] is not a number.", + "JSONObject[\"stringKey\"] is not a float.", e.getMessage()); } try { @@ -1089,7 +1089,7 @@ public void jsonObjectNonAndWrongValues() { fail("Expected an exception"); } catch (JSONException e) { assertEquals("Expecting an exception message", - "JSONObject[\"stringKey\"] is not a number.", + "JSONObject[\"stringKey\"] is not a int.", e.getMessage()); } try { @@ -1105,7 +1105,7 @@ public void jsonObjectNonAndWrongValues() { fail("Expected an exception"); } catch (JSONException e) { assertEquals("Expecting an exception message", - "JSONObject[\"stringKey\"] is not a number.", + "JSONObject[\"stringKey\"] is not a long.", e.getMessage()); } try { @@ -2087,7 +2087,7 @@ public void jsonObjectParsingErrors() { fail("Expected an exception"); } catch (JSONException e) { assertEquals("Expecting an exception message", - "JSONObject[myKey] is not a JSONArray.", + "JSONObject[\"myKey\"] is not a JSONArray (null).", e.getMessage()); } try { From 67e59888a2764d5b36fa133473563d70da4136ac Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Tue, 17 Sep 2019 11:14:41 -0400 Subject: [PATCH 11/16] add second case for data in #484 --- src/test/java/org/json/junit/JSONMLTest.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 26f4f90..b7afe40 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -2,6 +2,8 @@ import static org.junit.Assert.*; +import java.util.Base64; + import org.json.*; import org.junit.Test; @@ -805,7 +807,7 @@ public void testToJSONObject_reversibility() { // } @Test (timeout = 6000) - public void testIssue484InfinteLoop() { + public void testIssue484InfinteLoop1() { try { JSONML.toJSONObject("??*^M??|?CglR^F??`??>?w??PIlr^E??D^X^]?$?-^R?o??O?*??{OD?^FY??`2a????NM?b^Tq?:O?>S$^K?J?^FB.gUK?m^H??zE??^??!v]?^A???^[^A??^U?c??????h???s???g^Z???`?q^Dbi??:^QZl?)?}1^??k?0??:$V?$?Ovs(}J??^V????2;^QgQ?^_^A?^D?^U?Tg?K?`?h%c?hmGA??w??PIlr??D?$?-?o??O?*??{OD?Y??`2a????NM?bq?:O?>S$ ?J?B.gUK?m\b??zE???!v]???????c??????h???s???g???`?qbi??:Zl?)?}1^??k?0??:$V?$?Ovs(}J??????2;gQ????Tg?K?`?h%c?hmGA? Date: Tue, 17 Sep 2019 11:15:25 -0400 Subject: [PATCH 12/16] remove unused import --- src/test/java/org/json/junit/JSONMLTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index b7afe40..3687fe5 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -2,8 +2,6 @@ import static org.junit.Assert.*; -import java.util.Base64; - import org.json.*; import org.junit.Test; From 16da56eb34b6036f145dea7e6bf638b6ad418b5e Mon Sep 17 00:00:00 2001 From: Alanscut Date: Sat, 28 Dec 2019 17:53:27 +0800 Subject: [PATCH 13/16] improve the confused assert message --- .../java/org/json/junit/JSONObjectTest.java | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index ac67980..438e55e 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -589,19 +589,19 @@ public void jsonObjectByBean2() { jsonObject.has("someString")); assertFalse("Normal field name (myDouble) processing did not work", jsonObject.has("myDouble")); - assertFalse("Normal field name (someFloat) found", + assertFalse("Normal field name (someFloat) processing did not work", jsonObject.has("someFloat")); - assertFalse("Ignored field found!", + assertFalse("Ignored field not found!", jsonObject.has("ignoredInt")); - assertTrue("Normal field name (someInt) processing did not work", + assertTrue("Normal field name (someInt) found", jsonObject.has("someInt")); - assertTrue("Normal field name (someLong) processing did not work", + assertTrue("Normal field name (someLong) found", jsonObject.has("someLong")); - assertTrue("Overridden String field name (myStringField) not found", + assertTrue("Overridden String field name (myStringField) found", jsonObject.has("myStringField")); - assertTrue("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) not found", + assertTrue("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) found", jsonObject.has("Some Weird NAme that Normally Wouldn't be possible!")); - assertTrue("Overridden String field name (InterfaceField) not found", + assertTrue("Overridden String field name (InterfaceField) found", jsonObject.has("InterfaceField")); } @@ -619,26 +619,29 @@ public void jsonObjectByBean3() { jsonObject.has("someInt")); assertFalse("Normal field name (myDouble) processing did not work", jsonObject.has("myDouble")); - assertFalse("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) FOUND!", + assertFalse("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) not FOUND!", jsonObject.has("Some Weird NAme that Normally Wouldn't be possible!")); - assertFalse("Normal field name (someFloat) found", + assertFalse("Normal field name (someFloat) found, but was overridden", jsonObject.has("someFloat")); - assertFalse("Ignored field found!", + assertFalse("Ignored field found! but was overridden", jsonObject.has("ignoredInt")); - assertFalse("Ignored field at the same level as forced name found", + assertFalse("Ignored field at the same level as forced name not found", jsonObject.has("ShouldBeIgnored")); - assertTrue("Overridden int field name (newIntFieldName) not found", + assertFalse("Normally ignored field (able) with explicit property name not found", + jsonObject.has("able")); + assertTrue("Overridden int field name (newIntFieldName) found", jsonObject.has("newIntFieldName")); - assertTrue("Normal field name (someLong) processing did not work", + assertTrue("Normal field name (someLong) found", jsonObject.has("someLong")); - assertTrue("Overridden String field name (myStringField) not found", + assertTrue("Overridden String field name (myStringField) found", jsonObject.has("myStringField")); - assertTrue(jsonObject.has("AMoreNormalName")); - assertTrue("Overridden String field name (InterfaceField) not found", + assertTrue("Overridden double field name (AMoreNormalName) found", + jsonObject.has("AMoreNormalName")); + assertTrue("Overridden String field name (InterfaceField) found", jsonObject.has("InterfaceField")); - assertTrue("Forced field not found!", + assertTrue("Forced field found!", jsonObject.has("forcedInt")); - assertTrue("Normally ignored field (getable) with explicit property name not found", + assertTrue("Overridden boolean field name (Getable) found", jsonObject.has("Getable")); } From 08719d4b3a6d73918631297030e8e03cc960de24 Mon Sep 17 00:00:00 2001 From: Alan Wang <948467222@qq.com> Date: Mon, 30 Dec 2019 09:51:08 +0800 Subject: [PATCH 14/16] Apply suggestions from code review Co-Authored-By: Sean Leary --- .../java/org/json/junit/JSONObjectTest.java | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 438e55e..b2f501e 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -593,15 +593,20 @@ public void jsonObjectByBean2() { jsonObject.has("someFloat")); assertFalse("Ignored field not found!", jsonObject.has("ignoredInt")); - assertTrue("Normal field name (someInt) found", + // getSomeInt() has no user-defined annotation + assertTrue("Normal field name (someInt) should have been found", jsonObject.has("someInt")); - assertTrue("Normal field name (someLong) found", + // the user-defined annotation does not replace any value, so someLong should be found + assertTrue("Normal field name (someLong) should have been found", jsonObject.has("someLong")); - assertTrue("Overridden String field name (myStringField) found", + // myStringField replaces someString property name via user-defined annotation + assertTrue("Overridden String field name (myStringField) should have been found", jsonObject.has("myStringField")); - assertTrue("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) found", + // weird name replaces myDouble property name via user-defined annotation + assertTrue("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) should have been found", jsonObject.has("Some Weird NAme that Normally Wouldn't be possible!")); - assertTrue("Overridden String field name (InterfaceField) found", + // InterfaceField replaces someFloat property name via user-defined annotation + assertTrue("Overridden String field name (InterfaceField) should have been found", jsonObject.has("InterfaceField")); } @@ -619,29 +624,39 @@ public void jsonObjectByBean3() { jsonObject.has("someInt")); assertFalse("Normal field name (myDouble) processing did not work", jsonObject.has("myDouble")); - assertFalse("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) not FOUND!", + // myDouble was replaced by weird name, and then replaced again by AMoreNormalName via user-defined annotation + assertFalse("Overridden String field name (Some Weird NAme that Normally Wouldn't be possible!) should not be FOUND!", jsonObject.has("Some Weird NAme that Normally Wouldn't be possible!")); assertFalse("Normal field name (someFloat) found, but was overridden", jsonObject.has("someFloat")); assertFalse("Ignored field found! but was overridden", jsonObject.has("ignoredInt")); - assertFalse("Ignored field at the same level as forced name not found", + // shouldNotBeJSON property name was first ignored, then replaced by ShouldBeIgnored via user-defined annotations + assertFalse("Ignored field at the same level as forced name should not have been found", jsonObject.has("ShouldBeIgnored")); - assertFalse("Normally ignored field (able) with explicit property name not found", + // able property name was replaced by Getable via user-defined annotation + assertFalse("Normally ignored field (able) with explicit property name should not have been found", jsonObject.has("able")); - assertTrue("Overridden int field name (newIntFieldName) found", + // property name someInt was replaced by newIntFieldName via user-defined annotation + assertTrue("Overridden int field name (newIntFieldName) should have been found", jsonObject.has("newIntFieldName")); - assertTrue("Normal field name (someLong) found", + // property name someLong was not replaced via user-defined annotation + assertTrue("Normal field name (someLong) should have been found", jsonObject.has("someLong")); - assertTrue("Overridden String field name (myStringField) found", + // property name someString was replaced by myStringField via user-defined annotation + assertTrue("Overridden String field name (myStringField) should have been found", jsonObject.has("myStringField")); - assertTrue("Overridden double field name (AMoreNormalName) found", + // property name myDouble was replaced by a weird name, followed by AMoreNormalName via user-defined annotations + assertTrue("Overridden double field name (AMoreNormalName) should have been found", jsonObject.has("AMoreNormalName")); - assertTrue("Overridden String field name (InterfaceField) found", + // property name someFloat was replaced by InterfaceField via user-defined annotation + assertTrue("Overridden String field name (InterfaceField) should have been found", jsonObject.has("InterfaceField")); - assertTrue("Forced field found!", + // property name ignoredInt was replaced by none, followed by forcedInt via user-defined annotations + assertTrue("Forced field should have been found!", jsonObject.has("forcedInt")); - assertTrue("Overridden boolean field name (Getable) found", + // property name able was replaced by Getable via user-defined annotation + assertTrue("Overridden boolean field name (Getable) should have been found", jsonObject.has("Getable")); } From cd24543e6decdf360adf6bd53ee06fc12a4294c7 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sat, 23 May 2020 10:17:29 -0500 Subject: [PATCH 15/16] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e6e61b5..f27ec95 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # JSON-Java-unit-test + +# This project is no longer the source of truth for JSON-Java unit tests and it not accepting pull requests. The unit tests have been ported to [https://github.com/stleary/JSON-java](https://github.com/stleary/JSON-java) so that code and tests reside together. If this move works out, then future unit test changes will be performed there. + Unit tests to validate the JSON-Java GitHub project code
https://github.com/stleary/JSON-java
From 37294c45c1d61c224b6cb6b2b74a46b14b23eb11 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Wed, 29 Jul 2020 00:35:01 -0500 Subject: [PATCH 16/16] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f27ec95..63d0fd7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # JSON-Java-unit-test -# This project is no longer the source of truth for JSON-Java unit tests and it not accepting pull requests. The unit tests have been ported to [https://github.com/stleary/JSON-java](https://github.com/stleary/JSON-java) so that code and tests reside together. If this move works out, then future unit test changes will be performed there. +# This project is no longer accepting pull requests. It is not the source of truth for JSON-Java unit tests. The unit tests have been ported to [https://github.com/stleary/JSON-java](https://github.com/stleary/JSON-java) so that code and tests reside together. Please submit all pull requests to the new location. Unit tests to validate the JSON-Java GitHub project code