T withMaxNestingDepth(int maxNestingDepth) {
+ T newConfig = (T)this.clone();
+
+ if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
+ newConfig.maxNestingDepth = maxNestingDepth;
+ } else {
+ newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
+ }
+
+ return newConfig;
+ }
+}
diff --git a/src/main/java/org/json/Property.java b/src/main/java/org/json/Property.java
index 7caeebb076bd31f59be2a328511d58ea0a22bfaa..83694c055afd93a31032ad451acc36ffd8a86c8e 100644
--- a/src/main/java/org/json/Property.java
+++ b/src/main/java/org/json/Property.java
@@ -1,27 +1,7 @@
package org.json;
/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import java.util.Enumeration;
diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java
index 33838a15c25d88ae6e67aa9f85e843ac3a1d14fe..925f056b1aec91d7745c17c2e2af5561afe5c726 100644
--- a/src/main/java/org/json/XML.java
+++ b/src/main/java/org/json/XML.java
@@ -1,27 +1,7 @@
package org.json;
/*
-Copyright (c) 2015 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import java.io.Reader;
@@ -118,7 +98,7 @@ public class XML {
/**
* Replace special characters with XML escapes:
*
- * {@code
+ * {@code
* & (ampersand) is replaced by &
* < (less than) is replaced by <
* > (greater than) is replaced by >
@@ -249,10 +229,14 @@ public class XML {
* The JSONObject that will include the new material.
* @param name
* The tag name.
+ * @param config
+ * The XML parser configuration.
+ * @param currentNestingDepth
+ * The current nesting depth.
* @return true if the close tag is processed.
- * @throws JSONException
+ * @throws JSONException Thrown if any parsing error occurs.
*/
- private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config)
+ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, int currentNestingDepth)
throws JSONException {
char c;
int i;
@@ -422,7 +406,11 @@ public class XML {
} else if (token == LT) {
// Nested element
- if (parse(x, jsonObject, tagName, config)) {
+ if (currentNestingDepth == config.getMaxNestingDepth()) {
+ throw x.syntaxError("Maximum nesting depth of " + config.getMaxNestingDepth() + " reached");
+ }
+
+ if (parse(x, jsonObject, tagName, config, currentNestingDepth + 1)) {
if (config.getForceList().contains(tagName)) {
// Force the value to be an array
if (jsonObject.length() == 0) {
@@ -443,7 +431,7 @@ public class XML {
context.accumulate(tagName, jsonObject);
}
}
-
+
return false;
}
}
@@ -507,7 +495,7 @@ public class XML {
}
return string;
}
-
+
/**
* direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
*/
@@ -554,7 +542,7 @@ public class XML {
// integer representation.
// This will narrow any values to the smallest reasonable Object representation
// (Integer, Long, or BigInteger)
-
+
// BigInteger down conversion: We use a similar bitLength compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is
@@ -570,7 +558,7 @@ public class XML {
}
throw new NumberFormatException("val ["+val+"] is not a valid number.");
}
-
+
/**
* direct copy of {@link JSONObject#isDecimalNotation(String)} to maintain Android support.
*/
@@ -588,7 +576,7 @@ public class XML {
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
- * "content" member. Comments, prologs, DTDs, and {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -609,7 +597,7 @@ public class XML {
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
- * "content" member. Comments, prologs, DTDs, and {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -675,7 +663,7 @@ public class XML {
while (x.more()) {
x.skipPast("<");
if(x.more()) {
- parse(x, jo, null, config);
+ parse(x, jo, null, config, 0);
}
}
return jo;
@@ -689,7 +677,7 @@ public class XML {
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
- * "content" member. Comments, prologs, DTDs, and {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -715,7 +703,7 @@ public class XML {
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
- * "content" member. Comments, prologs, DTDs, and {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -772,6 +760,28 @@ public class XML {
*/
public static String toString(final Object object, final String tagName, final XMLParserConfiguration config)
throws JSONException {
+ return toString(object, tagName, config, 0, 0);
+ }
+
+ /**
+ * Convert a JSONObject into a well-formed, element-normal XML string,
+ * either pretty print or single-lined depending on indent factor.
+ *
+ * @param object
+ * A JSONObject.
+ * @param tagName
+ * The optional name of the enclosing tag.
+ * @param config
+ * Configuration that can control output to XML.
+ * @param indentFactor
+ * The number of spaces to add to each level of indentation.
+ * @param indent
+ * The current ident level in spaces.
+ * @return
+ * @throws JSONException
+ */
+ private static String toString(final Object object, final String tagName, final XMLParserConfiguration config, int indentFactor, int indent)
+ throws JSONException {
StringBuilder sb = new StringBuilder();
JSONArray ja;
JSONObject jo;
@@ -781,9 +791,14 @@ public class XML {
// Emit
if (tagName != null) {
+ sb.append(indent(indent));
sb.append('<');
sb.append(tagName);
sb.append('>');
+ if(indentFactor > 0){
+ sb.append("\n");
+ indent += indentFactor;
+ }
}
// Loop thru the keys.
@@ -826,31 +841,39 @@ public class XML {
sb.append('<');
sb.append(key);
sb.append('>');
- sb.append(toString(val, null, config));
+ sb.append(toString(val, null, config, indentFactor, indent));
sb.append("");
sb.append(key);
sb.append('>');
} else {
- sb.append(toString(val, key, config));
+ sb.append(toString(val, key, config, indentFactor, indent));
}
}
} else if ("".equals(value)) {
+ sb.append(indent(indent));
sb.append('<');
sb.append(key);
sb.append("/>");
+ if(indentFactor > 0){
+ sb.append("\n");
+ }
// Emit a new tag
} else {
- sb.append(toString(value, key, config));
+ sb.append(toString(value, key, config, indentFactor, indent));
}
}
if (tagName != null) {
// Emit the close tag
+ sb.append(indent(indent - indentFactor));
sb.append("");
sb.append(tagName);
sb.append('>');
+ if(indentFactor > 0){
+ sb.append("\n");
+ }
}
return sb.toString();
@@ -869,15 +892,85 @@ public class XML {
// XML does not have good support for arrays. If an array
// appears in a place where XML is lacking, synthesize an
// element.
- sb.append(toString(val, tagName == null ? "array" : tagName, config));
+ sb.append(toString(val, tagName == null ? "array" : tagName, config, indentFactor, indent));
}
return sb.toString();
}
+
string = (object == null) ? "null" : escape(object.toString());
- return (tagName == null) ? "\"" + string + "\""
- : (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName
- + ">" + string + "" + tagName + ">";
+ if(tagName == null){
+ return indent(indent) + "\"" + string + "\"" + ((indentFactor > 0) ? "\n" : "");
+ } else if(string.length() == 0){
+ return indent(indent) + "<" + tagName + "/>" + ((indentFactor > 0) ? "\n" : "");
+ } else {
+ return indent(indent) + "<" + tagName
+ + ">" + string + "" + tagName + ">" + ((indentFactor > 0) ? "\n" : "");
+ }
+ }
+
+ /**
+ * Convert a JSONObject into a well-formed, pretty printed element-normal XML string.
+ *
+ * @param object
+ * A JSONObject.
+ * @param indentFactor
+ * The number of spaces to add to each level of indentation.
+ * @return A string.
+ * @throws JSONException Thrown if there is an error parsing the string
+ */
+ public static String toString(Object object, int indentFactor){
+ return toString(object, null, XMLParserConfiguration.ORIGINAL, indentFactor);
+ }
+
+ /**
+ * Convert a JSONObject into a well-formed, pretty printed element-normal XML string.
+ *
+ * @param object
+ * A JSONObject.
+ * @param tagName
+ * The optional name of the enclosing tag.
+ * @param indentFactor
+ * The number of spaces to add to each level of indentation.
+ * @return A string.
+ * @throws JSONException Thrown if there is an error parsing the string
+ */
+ public static String toString(final Object object, final String tagName, int indentFactor) {
+ return toString(object, tagName, XMLParserConfiguration.ORIGINAL, indentFactor);
+ }
+
+ /**
+ * Convert a JSONObject into a well-formed, pretty printed element-normal XML string.
+ *
+ * @param object
+ * A JSONObject.
+ * @param tagName
+ * The optional name of the enclosing tag.
+ * @param config
+ * Configuration that can control output to XML.
+ * @param indentFactor
+ * The number of spaces to add to each level of indentation.
+ * @return A string.
+ * @throws JSONException Thrown if there is an error parsing the string
+ */
+ public static String toString(final Object object, final String tagName, final XMLParserConfiguration config, int indentFactor)
+ throws JSONException {
+ return toString(object, tagName, config, indentFactor, 0);
+ }
+
+ /**
+ * Return a String consisting of a number of space characters specified by indent
+ *
+ * @param indent
+ * The number of spaces to be appended to the String.
+ * @return
+ */
+ private static final String indent(int indent) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < indent; i++) {
+ sb.append(' ');
+ }
+ return sb.toString();
}
}
diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java
index a1fd63eb7c7a3d04779192e92d2db712d986abc0..566146d6daa1a7cb6ea42ada9642687a841a9cad 100644
--- a/src/main/java/org/json/XMLParserConfiguration.java
+++ b/src/main/java/org/json/XMLParserConfiguration.java
@@ -1,26 +1,6 @@
package org.json;
/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import java.util.Collections;
@@ -35,7 +15,13 @@ import java.util.Set;
* @author AylwardJ
*/
@SuppressWarnings({""})
-public class XMLParserConfiguration {
+public class XMLParserConfiguration extends ParserConfiguration {
+
+ /**
+ * The default maximum nesting depth when parsing a XML document to JSON.
+ */
+// public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; // We could override
+
/** Original Configuration of the XML Parser. */
public static final XMLParserConfiguration ORIGINAL
= new XMLParserConfiguration();
@@ -43,19 +29,13 @@ public class XMLParserConfiguration {
public static final XMLParserConfiguration KEEP_STRINGS
= new XMLParserConfiguration().withKeepStrings(true);
- /**
- * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if
- * they should try to be guessed into JSON values (numeric, boolean, string)
- */
- private boolean keepStrings;
-
/**
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use null to indicate no CDATA
* processing.
*/
private String cDataTagName;
-
+
/**
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(false), or they should be converted to
@@ -79,7 +59,7 @@ public class XMLParserConfiguration {
* values), and the CDATA Tag Name is "content".
*/
public XMLParserConfiguration () {
- this.keepStrings = false;
+ super();
this.cDataTagName = "content";
this.convertNilAttributeToNull = false;
this.xsiTypeMap = Collections.emptyMap();
@@ -126,7 +106,7 @@ public class XMLParserConfiguration {
*/
@Deprecated
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName) {
- this.keepStrings = keepStrings;
+ super(keepStrings, DEFAULT_MAXIMUM_NESTING_DEPTH);
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = false;
}
@@ -145,7 +125,7 @@ public class XMLParserConfiguration {
*/
@Deprecated
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull) {
- this.keepStrings = keepStrings;
+ super(keepStrings, DEFAULT_MAXIMUM_NESTING_DEPTH);
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = convertNilAttributeToNull;
}
@@ -160,11 +140,13 @@ public class XMLParserConfiguration {
* false to parse values with attribute xsi:nil="true" as {"xsi:nil":true}.
* @param xsiTypeMap new HashMap>() to parse values with attribute
* xsi:type="integer" as integer, xsi:type="string" as string
- * @param forceList new HashSet() to parse the provided tags' values as arrays
+ * @param forceList new HashSet() to parse the provided tags' values as arrays
+ * @param maxNestingDepth int to limit the nesting depth
*/
private XMLParserConfiguration (final boolean keepStrings, final String cDataTagName,
- final boolean convertNilAttributeToNull, final Map> xsiTypeMap, final Set forceList ) {
- this.keepStrings = keepStrings;
+ final boolean convertNilAttributeToNull, final Map> xsiTypeMap, final Set forceList,
+ final int maxNestingDepth) {
+ super(keepStrings, maxNestingDepth);
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = convertNilAttributeToNull;
this.xsiTypeMap = Collections.unmodifiableMap(xsiTypeMap);
@@ -186,40 +168,30 @@ public class XMLParserConfiguration {
this.cDataTagName,
this.convertNilAttributeToNull,
this.xsiTypeMap,
- this.forceList
+ this.forceList,
+ this.maxNestingDepth
);
}
-
- /**
- * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if
- * they should try to be guessed into JSON values (numeric, boolean, string)
- *
- * @return The keepStrings configuration value.
- */
- public boolean isKeepStrings() {
- return this.keepStrings;
- }
/**
* When parsing the XML into JSON, specifies if values should be kept as strings (true), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
- *
+ *
* @param newVal
* new value to use for the keepStrings configuration option.
- *
+ *
* @return The existing configuration will not be modified. A new configuration is returned.
*/
+ @Override
public XMLParserConfiguration withKeepStrings(final boolean newVal) {
- XMLParserConfiguration newConfig = this.clone();
- newConfig.keepStrings = newVal;
- return newConfig;
+ return super.withKeepStrings(newVal);
}
/**
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use null to indicate no CDATA
* processing.
- *
+ *
* @return The cDataTagName configuration value.
*/
public String getcDataTagName() {
@@ -230,10 +202,10 @@ public class XMLParserConfiguration {
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use null to indicate no CDATA
* processing.
- *
+ *
* @param newVal
* new value to use for the cDataTagName configuration option.
- *
+ *
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withcDataTagName(final String newVal) {
@@ -246,7 +218,7 @@ public class XMLParserConfiguration {
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(false), or they should be converted to
* null(true)
- *
+ *
* @return The convertNilAttributeToNull configuration value.
*/
public boolean isConvertNilAttributeToNull() {
@@ -257,10 +229,10 @@ public class XMLParserConfiguration {
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(false), or they should be converted to
* null(true)
- *
+ *
* @param newVal
* new value to use for the convertNilAttributeToNull configuration option.
- *
+ *
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withConvertNilAttributeToNull(final boolean newVal) {
@@ -298,7 +270,7 @@ public class XMLParserConfiguration {
/**
* When parsing the XML into JSON, specifies that tags that will be converted to arrays
- * in this configuration {@code Set} to parse the provided tags' values as arrays
+ * in this configuration {@code Set} to parse the provided tags' values as arrays
* @return forceList unmodifiable configuration set.
*/
public Set getForceList() {
@@ -307,8 +279,8 @@ public class XMLParserConfiguration {
/**
* When parsing the XML into JSON, specifies that tags that will be converted to arrays
- * in this configuration {@code Set} to parse the provided tags' values as arrays
- * @param forceList {@code new HashSet()} to parse the provided tags' values as arrays
+ * in this configuration {@code Set} to parse the provided tags' values as arrays
+ * @param forceList {@code new HashSet()} to parse the provided tags' values as arrays
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withForceList(final Set forceList) {
@@ -317,4 +289,18 @@ public class XMLParserConfiguration {
newConfig.forceList = Collections.unmodifiableSet(cloneForceList);
return newConfig;
}
+
+ /**
+ * Defines the maximum nesting depth that the parser will descend before throwing an exception
+ * when parsing the XML into JSON. The default max nesting depth is 512, which means the parser
+ * will throw a JsonException if the maximum depth is reached.
+ * Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
+ * which means the parses will go as deep as the maximum call stack size allows.
+ * @param maxNestingDepth the maximum nesting depth allowed to the XML parser
+ * @return The existing configuration will not be modified. A new configuration is returned.
+ */
+ @Override
+ public XMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) {
+ return super.withMaxNestingDepth(maxNestingDepth);
+ }
}
diff --git a/src/main/java/org/json/XMLTokener.java b/src/main/java/org/json/XMLTokener.java
index 3bbd3824bc3bdc6c993afb09fa2687767baac744..957498ca27874c82480d36578a2b6a4ac3d0e5d1 100644
--- a/src/main/java/org/json/XMLTokener.java
+++ b/src/main/java/org/json/XMLTokener.java
@@ -1,27 +1,7 @@
package org.json;
/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import java.io.Reader;
diff --git a/src/main/java/org/json/XMLXsiTypeConverter.java b/src/main/java/org/json/XMLXsiTypeConverter.java
index 0f8a8c33259ee82090b220f0f469ad91d4165e39..0011effae8d5a5860d82a0b6458d901bcc57d4e3 100644
--- a/src/main/java/org/json/XMLXsiTypeConverter.java
+++ b/src/main/java/org/json/XMLXsiTypeConverter.java
@@ -1,26 +1,6 @@
package org.json;
/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
/**
diff --git a/src/test/java/org/json/junit/CDLTest.java b/src/test/java/org/json/junit/CDLTest.java
index b8bdede395aab105d37eb459fea2a2ee9c314e1b..f3364fbbab9413443582e1a70492fa3c9caf524b 100644
--- a/src/test/java/org/json/junit/CDLTest.java
+++ b/src/test/java/org/json/junit/CDLTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
diff --git a/src/test/java/org/json/junit/CookieListTest.java b/src/test/java/org/json/junit/CookieListTest.java
index c3f647f900ee92d55c9c74cb5ce3c484d9020e90..0af96401b4eaceb9bbc1dadcbbdeba32122304cd 100644
--- a/src/test/java/org/json/junit/CookieListTest.java
+++ b/src/test/java/org/json/junit/CookieListTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
diff --git a/src/test/java/org/json/junit/CookieTest.java b/src/test/java/org/json/junit/CookieTest.java
index 7e7b62b45d109370052407d67463cfcd3335b771..edd8a7eeb01ff4735679cc5e7f4b51ef196d9fb6 100644
--- a/src/test/java/org/json/junit/CookieTest.java
+++ b/src/test/java/org/json/junit/CookieTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
diff --git a/src/test/java/org/json/junit/EnumTest.java b/src/test/java/org/json/junit/EnumTest.java
index 6867123600fab24014e1cff6aad67ead179ab033..1496a636a07484fcece0b329f21b464c951bb018 100644
--- a/src/test/java/org/json/junit/EnumTest.java
+++ b/src/test/java/org/json/junit/EnumTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.assertEquals;
diff --git a/src/test/java/org/json/junit/HTTPTest.java b/src/test/java/org/json/junit/HTTPTest.java
index 8182b60593803a45f1fe3c7d97a47fdaefc390c8..703d5ad2fd615398926e088e04f527a9ed6338a2 100644
--- a/src/test/java/org/json/junit/HTTPTest.java
+++ b/src/test/java/org/json/junit/HTTPTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java
index 987891e1204858d5eda3c85397225796987bf348..aa8657f069e5a5e8e61495e9884d4dec24087432 100644
--- a/src/test/java/org/json/junit/JSONArrayTest.java
+++ b/src/test/java/org/json/junit/JSONArrayTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -49,7 +29,9 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONPointerException;
+import org.json.JSONString;
import org.json.JSONTokener;
+import org.json.junit.data.MyJsonString;
import org.junit.Test;
import com.jayway.jsonpath.Configuration;
@@ -237,6 +219,10 @@ public class JSONArrayTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObj));
+ Util.checkJSONArrayMaps(expected);
+ Util.checkJSONArrayMaps(jaObj);
+ Util.checkJSONArrayMaps(jaRaw);
+ Util.checkJSONArrayMaps(jaInt);
}
/**
@@ -275,6 +261,7 @@ public class JSONArrayTest {
myList.get(i),
jsonArray.getString(myInts.length + i));
}
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -308,6 +295,9 @@ public class JSONArrayTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaInt));
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ jaRaw, jaObj, jaInt
+ )));
}
@@ -351,6 +341,9 @@ public class JSONArrayTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObjObj));
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ expected, jaRaw, jaStrObj, jaStrInt, jaObjObj
+ )));
}
/**
@@ -397,6 +390,7 @@ public class JSONArrayTest {
new Long(-1).equals(jsonArray.getLong(12)));
assertTrue("Array value null", jsonArray.isNull(-1));
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -463,6 +457,7 @@ public class JSONArrayTest {
assertEquals("Expected an exception message",
"JSONArray[5] is not a String (class java.math.BigDecimal : 0.002345).",e.getMessage());
}
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -499,6 +494,7 @@ public class JSONArrayTest {
assertTrue("expected value4", "value4".equals(jsonArray.query("/10/key4")));
assertTrue("expected 0", Integer.valueOf(0).equals(jsonArray.query("/11")));
assertTrue("expected \"-1\"", "-1".equals(jsonArray.query("/12")));
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -512,6 +508,9 @@ public class JSONArrayTest {
assertTrue("expected JSONArray length 13. instead found "+jsonArray.length(), jsonArray.length() == 13);
JSONArray nestedJsonArray = jsonArray.getJSONArray(9);
assertTrue("expected JSONArray length 1", nestedJsonArray.length() == 1);
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ jsonArray, nestedJsonArray
+ )));
}
/**
@@ -587,6 +586,10 @@ public class JSONArrayTest {
"hello".equals(jsonArray.optString(4)));
assertTrue("Array opt string default implicit",
"".equals(jsonArray.optString(-1)));
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ jsonArray, nestedJsonArray
+ )));
+ Util.checkJSONObjectMaps(nestedJsonObject);
}
/**
@@ -601,7 +604,9 @@ public class JSONArrayTest {
assertTrue("unexpected optLong value",ja.optLong(0,0)==123);
assertTrue("unexpected optDouble value",ja.optDouble(0,0.0)==123.0);
assertTrue("unexpected optBigInteger value",ja.optBigInteger(0,BigInteger.ZERO).compareTo(new BigInteger("123"))==0);
- assertTrue("unexpected optBigDecimal value",ja.optBigDecimal(0,BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0); }
+ assertTrue("unexpected optBigDecimal value",ja.optBigDecimal(0,BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0);
+ Util.checkJSONArrayMaps(ja);
+ }
/**
* Exercise the JSONArray.put(value) method with various parameters
@@ -677,6 +682,8 @@ public class JSONArrayTest {
assertTrue("expected 2 items in [9]", ((List>)(JsonPath.read(doc, "$[9]"))).size() == 2);
assertTrue("expected 1", Integer.valueOf(1).equals(jsonArray.query("/9/0")));
assertTrue("expected 2", Integer.valueOf(2).equals(jsonArray.query("/9/1")));
+ Util.checkJSONArrayMaps(jsonArray);
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -756,6 +763,8 @@ public class JSONArrayTest {
assertTrue("expected 2", Integer.valueOf(2).equals(jsonArray.query("/9/1")));
assertTrue("expected 1 item in [10]", ((Map,?>)(JsonPath.read(doc, "$[10]"))).size() == 1);
assertTrue("expected v1", "v1".equals(jsonArray.query("/10/k1")));
+ Util.checkJSONObjectMaps(jsonObject);
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -772,6 +781,7 @@ public class JSONArrayTest {
jsonArray.remove(0);
assertTrue("array should be empty", null == jsonArray.remove(5));
assertTrue("jsonArray should be empty", jsonArray.isEmpty());
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -811,6 +821,12 @@ public class JSONArrayTest {
otherJsonArray.put("world");
assertTrue("arrays values differ",
!jsonArray.similar(otherJsonArray));
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ jsonArray, otherJsonArray
+ )));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject, otherJsonObject
+ )));
}
/**
@@ -894,6 +910,7 @@ public class JSONArrayTest {
for (String s : jsonArray4Strs) {
list.contains(s);
}
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -905,6 +922,9 @@ public class JSONArrayTest {
JSONArray jsonArray = new JSONArray();
assertTrue("toJSONObject should return null",
null == jsonArray.toJSONObject(names));
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ names, jsonArray
+ )));
}
/**
@@ -926,6 +946,7 @@ public class JSONArrayTest {
assertTrue("expected 5", Integer.valueOf(5).equals(jsonArray.query("/4")));
assertTrue("expected 6", Integer.valueOf(6).equals(jsonArray.query("/5")));
assertTrue("expected 7", Integer.valueOf(7).equals(jsonArray.query("/6")));
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -968,6 +989,10 @@ public class JSONArrayTest {
assertTrue("Array value string long",
new Long(-1).equals(Long.parseLong((String) it.next())));
assertTrue("should be at end of array", !it.hasNext());
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ jsonArray, nestedJsonArray
+ )));
+ Util.checkJSONObjectMaps(nestedJsonObject);
}
@Test(expected = JSONPointerException.class)
@@ -1010,6 +1035,7 @@ public class JSONArrayTest {
} finally {
stringWriter.close();
}
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1069,9 +1095,11 @@ public class JSONArrayTest {
&& actualStr.contains("\"key2\": false")
&& actualStr.contains("\"key3\": 3.14")
);
+ Util.checkJSONArrayMaps(finalArray);
} finally {
stringWriter.close();
}
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1182,6 +1210,7 @@ public class JSONArrayTest {
// 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);
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1190,13 +1219,13 @@ public class JSONArrayTest {
*/
@Test
public void testJSONArrayInt() {
- assertNotNull(new JSONArray(0));
- assertNotNull(new JSONArray(5));
- // Check Size -> Even though the capacity of the JSONArray can be specified using a positive
- // integer but the length of JSONArray always reflects upon the items added into it.
- assertEquals(0l, new JSONArray(10).length());
+ assertNotNull(new JSONArray(0));
+ assertNotNull(new JSONArray(5));
+ // Check Size -> Even though the capacity of the JSONArray can be specified using a positive
+ // integer but the length of JSONArray always reflects upon the items added into it.
+ // assertEquals(0l, new JSONArray(10).length());
try {
- assertNotNull("Should throw an exception", new JSONArray(-1));
+ assertNotNull("Should throw an exception", new JSONArray(-1));
} catch (JSONException e) {
assertEquals("Expected an exception message",
"JSONArray initial capacity cannot be negative.",
@@ -1223,8 +1252,8 @@ public class JSONArrayTest {
((Collection)o).add("test");
((Collection)o).add(false);
try {
- a = new JSONArray(o);
- assertNull("Should error", a);
+ JSONArray a0 = new JSONArray(o);
+ assertNull("Should error", a0);
} catch (JSONException ex) {
}
@@ -1232,10 +1261,11 @@ public class JSONArrayTest {
// this is required for backwards compatibility
o = a;
try {
- a = new JSONArray(o);
- assertNull("Should error", a);
+ JSONArray a1 = new JSONArray(o);
+ assertNull("Should error", a1);
} catch (JSONException ex) {
}
+ Util.checkJSONArrayMaps(a);
}
/**
@@ -1252,6 +1282,9 @@ public class JSONArrayTest {
for(int i = 0; i < a1.length(); i++) {
assertEquals("index " + i + " are equal", a1.get(i), a2.get(i));
}
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ a1, a2
+ )));
}
/**
@@ -1269,6 +1302,9 @@ public class JSONArrayTest {
for(int i = 0; i < a1.length(); i++) {
assertEquals("index " + i + " are equal", a1.get(i), a2.get(i));
}
+ Util.checkJSONArraysMaps(new ArrayList(Arrays.asList(
+ a1, a2
+ )));
}
/**
@@ -1284,6 +1320,7 @@ public class JSONArrayTest {
jsonArray.clear(); //Clears the JSONArray
assertTrue("expected jsonArray.length() == 0", jsonArray.length() == 0); //Check if its length is 0
jsonArray.getInt(0); //Should throws org.json.JSONException: JSONArray[0] not found
+ Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1297,5 +1334,27 @@ public class JSONArrayTest {
JSONArray json_input = new JSONArray(tokener);
assertNotNull(json_input);
fail("Excepected Exception.");
+ Util.checkJSONArrayMaps(json_input);
+ }
+
+ @Test
+ public void testIssue682SimilarityOfJSONString() {
+ JSONArray ja1 = new JSONArray()
+ .put(new MyJsonString())
+ .put(2);
+ JSONArray ja2 = new JSONArray()
+ .put(new MyJsonString())
+ .put(2);
+ assertTrue(ja1.similar(ja2));
+
+ JSONArray ja3 = new JSONArray()
+ .put(new JSONString() {
+ @Override
+ public String toJSONString() {
+ return "\"different value\"";
+ }
+ })
+ .put(2);
+ assertFalse(ja1.similar(ja3));
}
}
diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java
index 390cbd82eb96d1602b9d2d7b580f18d2f6326752..35c0af2c48d292cfcc351b456b4f58383933f8d3 100644
--- a/src/test/java/org/json/junit/JSONMLTest.java
+++ b/src/test/java/org/json/junit/JSONMLTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
@@ -31,19 +11,19 @@ import org.junit.Test;
/**
* Tests for org.json.JSONML.java
- *
+ *
* Certain inputs are expected to result in exceptions. These tests are
* executed first. JSONML provides an API to:
- * Convert an XML string into a JSONArray or a JSONObject.
+ * Convert an XML string into a JSONArray or a JSONObject.
* Convert a JSONArray or JSONObject into an XML string.
* Both fromstring and tostring operations operations should be symmetrical
- * within the limits of JSONML.
+ * within the limits of JSONML.
* It should be possible to perform the following operations, which should
* result in the original string being recovered, within the limits of the
* underlying classes:
* Convert a string -> JSONArray -> string -> JSONObject -> string
* Convert a string -> JSONObject -> string -> JSONArray -> string
- *
+ *
*/
public class JSONMLTest {
@@ -76,7 +56,7 @@ public class JSONMLTest {
/**
* Attempts to call JSONML.toString() with a null JSONArray.
- * Expects a NullPointerException.
+ * Expects a NullPointerException.
*/
@Test(expected=NullPointerException.class)
public void nullJSONXMLException() {
@@ -89,7 +69,7 @@ public class JSONMLTest {
/**
* Attempts to call JSONML.toString() with a null JSONArray.
- * Expects a JSONException.
+ * Expects a JSONException.
*/
@Test
public void emptyJSONXMLException() {
@@ -145,7 +125,7 @@ public class JSONMLTest {
"[\"addresses\","+
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
- // this array has no name
+ // this array has no name
"["+
"[\"name\"],"+
"[\"nocontent\"],"+
@@ -200,7 +180,7 @@ public class JSONMLTest {
}
/**
- * Attempts to transform a malformed XML document
+ * Attempts to transform a malformed XML document
* (element tag has a frontslash) to a JSONArray.\
* Expects a JSONException
*/
@@ -211,7 +191,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because the 'name' element
* contains an invalid frontslash.
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -236,7 +216,7 @@ public class JSONMLTest {
*/
@Test
public void invalidBangInTagException() {
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -266,7 +246,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* starts with '!' and has no closing tag
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -296,7 +276,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* has no closing '>'.
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -326,7 +306,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* has no name after the closing tag ''.
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -356,7 +336,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* has '>' after the closing tag '' and name.
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -384,9 +364,9 @@ public class JSONMLTest {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because an element
- * does not have a complete CDATA string.
+ * does not have a complete CDATA string.
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -408,7 +388,7 @@ public class JSONMLTest {
/**
* Convert an XML document into a JSONArray, then use JSONML.toString()
* to convert it into a string. This string is then converted back into
- * a JSONArray. Both JSONArrays are compared against a control to
+ * a JSONArray. Both JSONArrays are compared against a control to
* confirm the contents.
*/
@Test
@@ -425,7 +405,7 @@ public class JSONMLTest {
* which is used to create a final JSONArray, which is also compared
* against the expected JSONArray.
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -434,7 +414,7 @@ public class JSONMLTest {
" >\n"+
"\n"+
" ";
- String expectedStr =
+ String expectedStr =
"[\"addresses\","+
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
@@ -454,12 +434,12 @@ public class JSONMLTest {
}
/**
- * Convert an XML document into a JSONObject. Use JSONML.toString() to
+ * Convert an XML document into a JSONObject. Use JSONML.toString() to
* convert it back into a string, and then re-convert it into a JSONObject.
* Both JSONObjects are compared against a control JSONObject to confirm
* the contents.
*
- * Next convert the XML document into a JSONArray. Use JSONML.toString() to
+ * Next convert the XML document into a JSONArray. Use JSONML.toString() to
* convert it back into a string, and then re-convert it into a JSONArray.
* Both JSONArrays are compared against a control JSONArray to confirm
* the contents.
@@ -472,23 +452,23 @@ public class JSONMLTest {
/**
* xmlStr contains XML text which is transformed into a JSONObject,
* restored to XML, transformed into a JSONArray, and then restored
- * to XML again. Both JSONObject and JSONArray should contain the same
+ * to XML again. Both JSONObject and JSONArray should contain the same
* information and should produce the same XML, allowing for non-ordered
* attributes.
- *
+ *
* Transformation to JSONObject:
* The elementName is stored as a string where key="tagName"
* Attributes are simply stored as key/value pairs
* If the element has either content or child elements, they are stored
* in a jsonArray with key="childNodes".
- *
+ *
* Transformation to JSONArray:
* 1st entry = elementname
* 2nd entry = attributes object (if present)
* 3rd entry = content (if present)
* 4th entry = child element JSONArrays (if present)
*/
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
@@ -605,7 +585,7 @@ public class JSONMLTest {
"\"tagName\":\"addresses\""+
"}";
- String expectedJSONArrayStr =
+ String expectedJSONArrayStr =
"["+
"\"addresses\","+
"{"+
@@ -665,12 +645,12 @@ public class JSONMLTest {
JSONObject finalJsonObject = JSONML.toJSONObject(jsonObjectXmlToStr);
Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject);
- // create a JSON array from the original string and make sure it
+ // create a JSON array from the original string and make sure it
// looks as expected
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
JSONArray expectedJsonArray = new JSONArray(expectedJSONArrayStr);
Util.compareActualVsExpectedJsonArrays(jsonArray,expectedJsonArray);
-
+
// restore the XML, then make another JSONArray and make sure it
// looks as expected
String jsonArrayXmlToStr = JSONML.toString(jsonArray);
@@ -688,14 +668,14 @@ public class JSONMLTest {
* Convert an XML document which contains embedded comments into
* a JSONArray. Use JSONML.toString() to turn it into a string, then
* reconvert it into a JSONArray. Compare both JSONArrays to a control
- * JSONArray to confirm the contents.
+ * JSONArray to confirm the contents.
*
* This test shows how XML comments are handled.
*/
@Test
public void commentsInXML() {
- String xmlStr =
+ String xmlStr =
"\n"+
"\n"+
"\n"+
@@ -754,7 +734,7 @@ public class JSONMLTest {
final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",\"1\"],[\"id\",\"00\"],[\"id\",\"0\"],[\"item\",{\"id\":\"01\"}],[\"title\",\"True\"]]";
final JSONArray json = JSONML.toJSONArray(originalXml,true);
assertEquals(expectedJsonString, json.toString());
-
+
final String reverseXml = JSONML.toString(json);
assertEquals(originalXml, reverseXml);
}
@@ -769,7 +749,7 @@ public class JSONMLTest {
final String revertedXml = JSONML.toString(jsonArray);
assertEquals(revertedXml, originalXml);
}
-
+
/**
* JSON string cannot be reverted to original xml. See test result in
* comment below.
@@ -790,7 +770,7 @@ public class JSONMLTest {
// 1. Our XML parser does not handle generic HTML entities, only valid XML entities. Hence
// or other HTML specific entities would fail on reversability
// 2. Our JSON implementation for storing the XML attributes uses the standard unordered map.
-// This means that can not be reversed reliably.
+// This means that can not be reversed reliably.
//
// /**
// * Test texts taken from jsonml.org. Currently our implementation FAILS this conversion but shouldn't.
@@ -803,13 +783,13 @@ public class JSONMLTest {
// final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"\u00A0\",[\"span\",{ \"style\" : \"background-color:maroon\" },\"\u00A9\"],\"\u00A0\"]]]";
// final JSONArray json = JSONML.toJSONArray(originalXml,true);
// final String actualJsonString = json.toString();
-//
+//
// final String reverseXml = JSONML.toString(json);
// assertNotEquals(originalXml, reverseXml);
//
// assertNotEquals(expectedJsonString, actualJsonString);
// }
-//
+//
// /**
// * Test texts taken from jsonml.org but modified to have XML entities only.
// */
@@ -819,15 +799,15 @@ public class JSONMLTest {
// final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"&\",[\"span\",{ \"style\" : \"background-color:maroon\" },\">\"],\"<\"]]]";
// final JSONArray jsonML = JSONML.toJSONArray(originalXml,true);
// final String actualJsonString = jsonML.toString();
-//
+//
// final String reverseXml = JSONML.toString(jsonML);
// // currently not equal because the hashing of the attribute objects makes the attribute
-// // order not happen the same way twice
+// // order not happen the same way twice
// assertEquals(originalXml, reverseXml);
//
// assertEquals(expectedJsonString, actualJsonString);
// }
-
+
@Test (timeout = 6000)
public void testIssue484InfinteLoop1() {
try {
@@ -839,11 +819,11 @@ public class JSONMLTest {
ex.getMessage());
}
}
-
+
@Test (timeout = 6000)
public void testIssue484InfinteLoop2() {
try {
- String input = "??*\n" +
+ String input = "??*\n" +
"??|?CglR??`??>?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?");
+
+ final int maxNestingDepth = 42;
+
+ try {
+ JSONML.toJSONArray(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
+ }
+ }
+
+
+ @Test
+ public void testToJSONArrayMaxNestingDepthIsRespectedWithValidXML() {
+ final String perfectlyFineXML = "\n" +
+ " \n" +
+ " sonoo \n" +
+ " 56000 \n" +
+ " true \n" +
+ " \n" +
+ " \n";
+
+ final int maxNestingDepth = 1;
+
+ try {
+ JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
+ }
+ }
+
+ @Test
+ public void testToJSONArrayMaxNestingDepthWithValidFittingXML() {
+ final String perfectlyFineXML = "\n" +
+ " \n" +
+ " sonoo \n" +
+ " 56000 \n" +
+ " true \n" +
+ " \n" +
+ " \n";
+
+ final int maxNestingDepth = 3;
+
+ try {
+ JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
+ "parameter of the JSONMLParserConfiguration used");
+ }
+ }
+
+
+ @Test
+ public void testToJSONObjectMaxDefaultNestingDepthIsRespected() {
+ final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "");
+
+ try {
+ JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL);
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH));
+ }
+ }
+
+ @Test
+ public void testToJSONObjectUnlimitedNestingDepthIsPossible() {
+ int actualDepth = JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH +10;
+ final String deeperThanDefaultMax = new String(new char[actualDepth]).replace("\0", " ") +
+ "value" +
+ new String(new char[actualDepth]).replace("\0", " ");
+
+ try {
+ JSONML.toJSONObject(deeperThanDefaultMax, JSONMLParserConfiguration.ORIGINAL
+ .withMaxNestingDepth(JSONMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ fail("XML document should be parsed beyond the default maximum depth if maxNestingDepth " +
+ "parameter is set to -1 in JSONMLParserConfiguration");
+ }
+ }
+
+
+ @Test
+ public void testToJSONObjectMaxNestingDepthOf42IsRespected() {
+ final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "");
+
+ final int maxNestingDepth = 42;
+
+ try {
+ JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
+ }
+ }
+
+ @Test
+ public void testToJSONObjectMaxNestingDepthIsRespectedWithValidXML() {
+ final String perfectlyFineXML = "\n" +
+ " \n" +
+ " sonoo \n" +
+ " 56000 \n" +
+ " true \n" +
+ " \n" +
+ " \n";
+
+ final int maxNestingDepth = 1;
+
+ try {
+ JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
+ }
+ }
+
+ @Test
+ public void testToJSONObjectMaxNestingDepthWithValidFittingXML() {
+ final String perfectlyFineXML = "\n" +
+ " \n" +
+ " sonoo \n" +
+ " 56000 \n" +
+ " true \n" +
+ " \n" +
+ " \n";
+
+ final int maxNestingDepth = 3;
+
+ try {
+ JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
+ "parameter of the JSONMLParserConfiguration used");
+ }
+ }
+
}
diff --git a/src/test/java/org/json/junit/JSONObjectLocaleTest.java b/src/test/java/org/json/junit/JSONObjectLocaleTest.java
index 5112bf56ee24604cf7d52d191f44626715497af8..1cdaf743d872252fc6440d17fff569fa4b79717d 100755
--- a/src/test/java/org/json/junit/JSONObjectLocaleTest.java
+++ b/src/test/java/org/json/junit/JSONObjectLocaleTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
diff --git a/src/test/java/org/json/junit/JSONObjectNumberTest.java b/src/test/java/org/json/junit/JSONObjectNumberTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6e13c63d8071802fa40ddf534b191d246ee5408
--- /dev/null
+++ b/src/test/java/org/json/junit/JSONObjectNumberTest.java
@@ -0,0 +1,126 @@
+package org.json.junit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(value = Parameterized.class)
+public class JSONObjectNumberTest {
+ private final String objectString;
+ private Integer value = 50;
+
+ @Parameters(name = "{index}: {0}")
+ public static Collection data() {
+ return Arrays.asList(new Object[][]{
+ {"{value:50}", 1},
+ {"{value:50.0}", 1},
+ {"{value:5e1}", 1},
+ {"{value:5E1}", 1},
+ {"{value:5e1}", 1},
+ {"{value:'50'}", 1},
+ {"{value:-50}", -1},
+ {"{value:-50.0}", -1},
+ {"{value:-5e1}", -1},
+ {"{value:-5E1}", -1},
+ {"{value:-5e1}", -1},
+ {"{value:'-50'}", -1}
+ // JSON does not support octal or hex numbers;
+ // see https://stackoverflow.com/a/52671839/6323312
+ // "{value:062}", // octal 50
+ // "{value:0x32}" // hex 50
+ });
+ }
+
+ public JSONObjectNumberTest(String objectString, int resultIsNegative) {
+ this.objectString = objectString;
+ this.value *= resultIsNegative;
+ }
+
+ private JSONObject object;
+
+ @Before
+ public void setJsonObject() {
+ object = new JSONObject(objectString);
+ }
+
+ @Test
+ public void testGetNumber() {
+ assertEquals(value.intValue(), object.getNumber("value").intValue());
+ }
+
+ @Test
+ public void testGetBigDecimal() {
+ assertTrue(BigDecimal.valueOf(value).compareTo(object.getBigDecimal("value")) == 0);
+ }
+
+ @Test
+ public void testGetBigInteger() {
+ assertEquals(BigInteger.valueOf(value), object.getBigInteger("value"));
+ }
+
+ @Test
+ public void testGetFloat() {
+ assertEquals(value.floatValue(), object.getFloat("value"), 0.0f);
+ }
+
+ @Test
+ public void testGetDouble() {
+ assertEquals(value.doubleValue(), object.getDouble("value"), 0.0d);
+ }
+
+ @Test
+ public void testGetInt() {
+ assertEquals(value.intValue(), object.getInt("value"));
+ }
+
+ @Test
+ public void testGetLong() {
+ assertEquals(value.longValue(), object.getLong("value"));
+ }
+
+ @Test
+ public void testOptNumber() {
+ assertEquals(value.intValue(), object.optNumber("value").intValue());
+ }
+
+ @Test
+ public void testOptBigDecimal() {
+ assertTrue(BigDecimal.valueOf(value).compareTo(object.optBigDecimal("value", null)) == 0);
+ }
+
+ @Test
+ public void testOptBigInteger() {
+ assertEquals(BigInteger.valueOf(value), object.optBigInteger("value", null));
+ }
+
+ @Test
+ public void testOptFloat() {
+ assertEquals(value.floatValue(), object.optFloat("value"), 0.0f);
+ }
+
+ @Test
+ public void testOptDouble() {
+ assertEquals(value.doubleValue(), object.optDouble("value"), 0.0d);
+ }
+
+ @Test
+ public void testOptInt() {
+ assertEquals(value.intValue(), object.optInt("value"));
+ }
+
+ @Test
+ public void testOptLong() {
+ assertEquals(value.longValue(), object.optLong("value"));
+ }
+}
diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java
index 2ba58bf6e1e6b943485e10b8b2fd51ac2d95d8c7..ea0cec39c79044622129e4209f378d0bb24d4335 100644
--- a/src/test/java/org/json/junit/JSONObjectTest.java
+++ b/src/test/java/org/json/junit/JSONObjectTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -41,14 +21,7 @@ import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
@@ -57,6 +30,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONPointerException;
+import org.json.JSONString;
import org.json.JSONTokener;
import org.json.XML;
import org.json.junit.data.BrokenToString;
@@ -80,6 +54,7 @@ import org.json.junit.data.Singleton;
import org.json.junit.data.SingletonEnum;
import org.json.junit.data.WeirdList;
import org.junit.Test;
+import org.json.junit.Util;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
@@ -140,8 +115,12 @@ public class JSONObjectTest {
JSONObject first = new JSONObject("{\"a\": 1, \"b\": 2, \"c\": 3}");
JSONObject second = new JSONObject("{\"a\": 1, \"b\": 2.0, \"c\": 4}");
assertFalse("first-second should eval to false", first.similar(second));
+ List jsonObjects = new ArrayList(
+ Arrays.asList(obj1, obj2, obj3, obj4, obj5)
+ );
+ Util.checkJSONObjectsMaps(jsonObjects);
}
-
+
@Test
public void timeNumberParsing() {
// test data to use
@@ -214,7 +193,9 @@ public class JSONObjectTest {
*/
@Test(expected=NullPointerException.class)
public void jsonObjectByNullBean() {
- assertNull("Expected an exception",new JSONObject((MyBean)null));
+ JSONObject jsonObject = new JSONObject((MyBean)null);
+ assertNull("Expected an exception", jsonObject);
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -232,6 +213,7 @@ public class JSONObjectTest {
assertTrue("expected value1", textStr.contains("\"value1\""));
assertTrue("expected key2", textStr.contains("\"key2\""));
assertTrue("expected 42", textStr.contains("42"));
+ Util.checkJSONObjectMaps(jsonObject);
}
@Test
@@ -252,6 +234,7 @@ public class JSONObjectTest {
final String actualString = json.optString("key");
assert str.equals(actualString) : "Incorrect key value. Got "
+ actualString + " expected " + str;
+ Util.checkJSONObjectMaps(json);
}
/**
@@ -261,6 +244,7 @@ public class JSONObjectTest {
public void emptyJsonObject() {
JSONObject jsonObject = new JSONObject();
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -291,6 +275,7 @@ public class JSONObjectTest {
assertTrue("expected \"nullKey\":null", JSONObject.NULL.equals(jsonObjectByName.query("/nullKey")));
assertTrue("expected \"stringKey\":\"hello world!\"", "hello world!".equals(jsonObjectByName.query("/stringKey")));
assertTrue("expected \"doubleKey\":-23.45e67", new BigDecimal("-23.45e67").equals(jsonObjectByName.query("/doubleKey")));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(jsonObject, jsonObjectByName)));
}
/**
@@ -304,6 +289,7 @@ public class JSONObjectTest {
Map map = null;
JSONObject jsonObject = new JSONObject(map);
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -329,6 +315,7 @@ public class JSONObjectTest {
assertTrue("expected \"stringKey\":\"hello world!\"", "hello world!".equals(jsonObject.query("/stringKey")));
assertTrue("expected \"escapeStringKey\":\"h\be\tllo w\u1234orld!\"", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/escapeStringKey")));
assertTrue("expected \"doubleKey\":-23.45e67", Double.valueOf("-23.45e67").equals(jsonObject.query("/doubleKey")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -367,6 +354,9 @@ public class JSONObjectTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObjObj));
+ Util.checkJSONObjectsMaps(new ArrayList(
+ Arrays.asList(jaRaw, jaStrObj, jaStrInt, jaObjObj))
+ );
}
/**
@@ -384,8 +374,8 @@ public class JSONObjectTest {
* The only getter is getNumber (key=number), whose return value is
* BigDecimal(42).
*/
- JSONObject jsonObject = new JSONObject(new MyNumberContainer());
- String actual = jsonObject.toString();
+ JSONObject jsonObject0 = new JSONObject(new MyNumberContainer());
+ String actual = jsonObject0.toString();
String expected = "{\"myNumber\":{\"number\":42}}";
assertEquals("Equal", expected , actual);
@@ -397,9 +387,9 @@ public class JSONObjectTest {
* The MyNumber.toString() method is responsible for
* returning a reasonable value: the string '42'.
*/
- jsonObject = new JSONObject();
- jsonObject.put("myNumber", new MyNumber());
- actual = jsonObject.toString();
+ JSONObject jsonObject1 = new JSONObject();
+ jsonObject1.put("myNumber", new MyNumber());
+ actual = jsonObject1.toString();
expected = "{\"myNumber\":42}";
assertEquals("Equal", expected , actual);
@@ -411,8 +401,8 @@ public class JSONObjectTest {
* wrap() inserts the value as a string. That is why 42 comes back
* wrapped in quotes.
*/
- jsonObject = new JSONObject(Collections.singletonMap("myNumber", new AtomicInteger(42)));
- actual = jsonObject.toString();
+ JSONObject jsonObject2 = new JSONObject(Collections.singletonMap("myNumber", new AtomicInteger(42)));
+ actual = jsonObject2.toString();
expected = "{\"myNumber\":\"42\"}";
assertEquals("Equal", expected , actual);
@@ -422,9 +412,9 @@ public class JSONObjectTest {
* AtomicInteger is recognized as a Number, and converted via
* numberToString() into the unquoted string '42'.
*/
- jsonObject = new JSONObject();
- jsonObject.put("myNumber", new AtomicInteger(42));
- actual = jsonObject.toString();
+ JSONObject jsonObject3 = new JSONObject();
+ jsonObject3.put("myNumber", new AtomicInteger(42));
+ actual = jsonObject3.toString();
expected = "{\"myNumber\":42}";
assertEquals("Equal", expected , actual);
@@ -435,11 +425,11 @@ public class JSONObjectTest {
* bean and inserted into a contained JSONObject. It has 2 getters,
* for numerator and denominator.
*/
- jsonObject = new JSONObject(Collections.singletonMap("myNumber", new Fraction(4,2)));
- assertEquals(1, jsonObject.length());
- assertEquals(2, ((JSONObject)(jsonObject.get("myNumber"))).length());
- assertEquals("Numerator", BigInteger.valueOf(4) , jsonObject.query("/myNumber/numerator"));
- assertEquals("Denominator", BigInteger.valueOf(2) , jsonObject.query("/myNumber/denominator"));
+ JSONObject jsonObject4 = new JSONObject(Collections.singletonMap("myNumber", new Fraction(4,2)));
+ assertEquals(1, jsonObject4.length());
+ assertEquals(2, ((JSONObject)(jsonObject4.get("myNumber"))).length());
+ assertEquals("Numerator", BigInteger.valueOf(4) , jsonObject4.query("/myNumber/numerator"));
+ assertEquals("Denominator", BigInteger.valueOf(2) , jsonObject4.query("/myNumber/denominator"));
/**
* JSONObject.put() inserts the Fraction directly into the
@@ -449,11 +439,15 @@ public class JSONObjectTest {
* BigDecimal sanity check fails, so writeValue() defaults
* to returning a safe JSON quoted string. Pretty slick!
*/
- jsonObject = new JSONObject();
- jsonObject.put("myNumber", new Fraction(4,2));
- actual = jsonObject.toString();
+ JSONObject jsonObject5 = new JSONObject();
+ jsonObject5.put("myNumber", new Fraction(4,2));
+ actual = jsonObject5.toString();
expected = "{\"myNumber\":\"4/2\"}"; // valid JSON, bug fixed
assertEquals("Equal", expected , actual);
+
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject0, jsonObject1, jsonObject2, jsonObject3, jsonObject4, jsonObject5
+ )));
}
/**
@@ -488,6 +482,10 @@ public class JSONObjectTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaInt));
+
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jaRaw, jaObj, jaInt
+ )));
}
@@ -531,6 +529,10 @@ public class JSONObjectTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObjObj));
+
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jaRaw, jaStrObj, jaStrInt, jaStrObj
+ )));
}
@@ -553,6 +555,7 @@ public class JSONObjectTest {
assertTrue("expected 2 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected 0 key1 items", ((Map,?>)(JsonPath.read(doc, "$.key1"))).size() == 0);
assertTrue("expected \"key2\":java.lang.Exception","java.lang.Exception".equals(jsonObject.query("/key2")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -580,6 +583,7 @@ public class JSONObjectTest {
assertTrue("expected \"escapeStringKey\":\"h\be\tllo w\u1234orld!\"", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/escapeStringKey")));
assertTrue("expected \"intKey\":42", Long.valueOf("42").equals(jsonObject.query("/intKey")));
assertTrue("expected \"doubleKey\":-23.45e67", Double.valueOf("-23.45e67").equals(jsonObject.query("/doubleKey")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -620,6 +624,7 @@ public class JSONObjectTest {
assertTrue("expected 2 callbacks items", ((List>)(JsonPath.read(doc, "$.callbacks"))).size() == 2);
assertTrue("expected 0 handler items", ((Map,?>)(JsonPath.read(doc, "$.callbacks[0].handler"))).size() == 0);
assertTrue("expected 0 callbacks[1] items", ((Map,?>)(JsonPath.read(doc, "$.callbacks[1]"))).size() == 0);
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -655,6 +660,7 @@ public class JSONObjectTest {
// InterfaceField replaces someFloat property name via user-defined annotation
assertTrue("Overridden String field name (InterfaceField) should have been found",
jsonObject.has("InterfaceField"));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -705,6 +711,7 @@ public class JSONObjectTest {
// property name able was replaced by Getable via user-defined annotation
assertTrue("Overridden boolean field name (Getable) should have been found",
jsonObject.has("Getable"));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -725,6 +732,7 @@ public class JSONObjectTest {
assertTrue("expected 2 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected \"publicString\":\"abc\"", "abc".equals(jsonObject.query("/publicString")));
assertTrue("expected \"publicInt\":42", Integer.valueOf(42).equals(jsonObject.query("/publicInt")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -746,6 +754,7 @@ public class JSONObjectTest {
assertTrue("expected 2 farewells items", ((Map,?>)(JsonPath.read(doc, "$.farewells"))).size() == 2);
assertTrue("expected \"later\":\"Later, \"", "Later, ".equals(jsonObject.query("/farewells/later")));
assertTrue("expected \"world\":\"World!\"", "Alligator!".equals(jsonObject.query("/farewells/gator")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -778,6 +787,7 @@ public class JSONObjectTest {
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/myArray/3")));
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/myArray/4")));
assertTrue("expected -23.45e7", Double.valueOf(-23.45e7).equals(jsonObject.query("/myArray/5")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -809,6 +819,7 @@ public class JSONObjectTest {
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/myArray/3")));
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/myArray/4")));
assertTrue("expected -23.45e7", Double.valueOf(-23.45e7).equals(jsonObject.query("/myArray/5")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -944,6 +955,7 @@ public class JSONObjectTest {
JSONObject jsonObjectInner = jsonObject.getJSONObject("objectKey");
assertTrue("objectKey should be JSONObject",
jsonObjectInner.get("myKey").equals("myVal"));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1006,6 +1018,7 @@ public class JSONObjectTest {
obj = jsonObject.get( "largeExponent" );
assertTrue("largeExponent should evaluate as a BigDecimal",
new BigDecimal("-23.45e2327").equals(obj));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1054,6 +1067,7 @@ public class JSONObjectTest {
jsonObject.get("floatIdentifier").equals(Double.valueOf(0.1)));
assertTrue("doubleIdentifier currently evaluates to double 0.1",
jsonObject.get("doubleIdentifier").equals(Double.valueOf(0.1)));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1205,6 +1219,7 @@ public class JSONObjectTest {
"JSONObject[\"stringKey\"] is not a JSONObject (class java.lang.String : hello world!).",
e.getMessage());
}
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1232,6 +1247,7 @@ public class JSONObjectTest {
assertTrue("3.0 can still be interpreted as a double",
deserialized.getDouble(key30) == 3.0);
assertTrue("3.1 remains a double", deserialized.getDouble(key31) == 3.1);
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1247,9 +1263,9 @@ public class JSONObjectTest {
* value is stored. This should be fixed.
*/
BigInteger bigInteger = new BigInteger("123456789012345678901234567890");
- JSONObject jsonObject = new JSONObject(bigInteger);
- Object obj = jsonObject.get("lowestSetBit");
- assertTrue("JSONObject only has 1 value", jsonObject.length() == 1);
+ JSONObject jsonObject0 = new JSONObject(bigInteger);
+ Object obj = jsonObject0.get("lowestSetBit");
+ assertTrue("JSONObject only has 1 value", jsonObject0.length() == 1);
assertTrue("JSONObject parses BigInteger as the Integer lowestBitSet",
obj instanceof Integer);
assertTrue("this bigInteger lowestBitSet happens to be 1",
@@ -1262,57 +1278,57 @@ public class JSONObjectTest {
*/
BigDecimal bigDecimal = new BigDecimal(
"123456789012345678901234567890.12345678901234567890123456789");
- jsonObject = new JSONObject(bigDecimal);
- assertTrue("large bigDecimal is not stored", jsonObject.isEmpty());
+ JSONObject jsonObject1 = new JSONObject(bigDecimal);
+ assertTrue("large bigDecimal is not stored", jsonObject1.isEmpty());
/**
* JSONObject put(String, Object) method stores and serializes
* bigInt and bigDec correctly. Nothing needs to change.
*/
- jsonObject = new JSONObject();
- jsonObject.put("bigInt", bigInteger);
+ JSONObject jsonObject2 = new JSONObject();
+ jsonObject2.put("bigInt", bigInteger);
assertTrue("jsonObject.put() handles bigInt correctly",
- jsonObject.get("bigInt").equals(bigInteger));
+ jsonObject2.get("bigInt").equals(bigInteger));
assertTrue("jsonObject.getBigInteger() handles bigInt correctly",
- jsonObject.getBigInteger("bigInt").equals(bigInteger));
+ jsonObject2.getBigInteger("bigInt").equals(bigInteger));
assertTrue("jsonObject.optBigInteger() handles bigInt correctly",
- jsonObject.optBigInteger("bigInt", BigInteger.ONE).equals(bigInteger));
+ jsonObject2.optBigInteger("bigInt", BigInteger.ONE).equals(bigInteger));
assertTrue("jsonObject serializes bigInt correctly",
- jsonObject.toString().equals("{\"bigInt\":123456789012345678901234567890}"));
+ jsonObject2.toString().equals("{\"bigInt\":123456789012345678901234567890}"));
assertTrue("BigInteger as BigDecimal",
- jsonObject.getBigDecimal("bigInt").equals(new BigDecimal(bigInteger)));
+ jsonObject2.getBigDecimal("bigInt").equals(new BigDecimal(bigInteger)));
- jsonObject = new JSONObject();
- jsonObject.put("bigDec", bigDecimal);
+ JSONObject jsonObject3 = new JSONObject();
+ jsonObject3.put("bigDec", bigDecimal);
assertTrue("jsonObject.put() handles bigDec correctly",
- jsonObject.get("bigDec").equals(bigDecimal));
+ jsonObject3.get("bigDec").equals(bigDecimal));
assertTrue("jsonObject.getBigDecimal() handles bigDec correctly",
- jsonObject.getBigDecimal("bigDec").equals(bigDecimal));
+ jsonObject3.getBigDecimal("bigDec").equals(bigDecimal));
assertTrue("jsonObject.optBigDecimal() handles bigDec correctly",
- jsonObject.optBigDecimal("bigDec", BigDecimal.ONE).equals(bigDecimal));
+ jsonObject3.optBigDecimal("bigDec", BigDecimal.ONE).equals(bigDecimal));
assertTrue("jsonObject serializes bigDec correctly",
- jsonObject.toString().equals(
+ jsonObject3.toString().equals(
"{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}"));
assertTrue("BigDecimal as BigInteger",
- jsonObject.getBigInteger("bigDec").equals(bigDecimal.toBigInteger()));
+ jsonObject3.getBigInteger("bigDec").equals(bigDecimal.toBigInteger()));
/**
* exercise some exceptions
*/
try {
// bigInt key does not exist
- jsonObject.getBigDecimal("bigInt");
+ jsonObject3.getBigDecimal("bigInt");
fail("expected an exeption");
} catch (JSONException ignored) {}
- obj = jsonObject.optBigDecimal("bigInt", BigDecimal.ONE);
+ obj = jsonObject3.optBigDecimal("bigInt", BigDecimal.ONE);
assertTrue("expected BigDecimal", obj.equals(BigDecimal.ONE));
- jsonObject.put("stringKey", "abc");
+ jsonObject3.put("stringKey", "abc");
try {
- jsonObject.getBigDecimal("stringKey");
+ jsonObject3.getBigDecimal("stringKey");
fail("expected an exeption");
} catch (JSONException ignored) {}
- obj = jsonObject.optBigInteger("bigDec", BigInteger.ONE);
+ obj = jsonObject3.optBigInteger("bigDec", BigInteger.ONE);
assertTrue("expected BigInteger", obj instanceof BigInteger);
assertEquals(bigDecimal.toBigInteger(), obj);
@@ -1345,79 +1361,79 @@ public class JSONObjectTest {
// bigInt map ctor
Map map = new HashMap();
map.put("bigInt", bigInteger);
- jsonObject = new JSONObject(map);
- String actualFromMapStr = jsonObject.toString();
+ JSONObject jsonObject4 = new JSONObject(map);
+ String actualFromMapStr = jsonObject4.toString();
assertTrue("bigInt in map (or array or bean) is a string",
actualFromMapStr.equals(
"{\"bigInt\":123456789012345678901234567890}"));
// bigInt put
- jsonObject = new JSONObject();
- jsonObject.put("bigInt", bigInteger);
- String actualFromPutStr = jsonObject.toString();
+ JSONObject jsonObject5 = new JSONObject();
+ jsonObject5.put("bigInt", bigInteger);
+ String actualFromPutStr = jsonObject5.toString();
assertTrue("bigInt from put is a number",
actualFromPutStr.equals(
"{\"bigInt\":123456789012345678901234567890}"));
// bigDec map ctor
map = new HashMap();
map.put("bigDec", bigDecimal);
- jsonObject = new JSONObject(map);
- actualFromMapStr = jsonObject.toString();
+ JSONObject jsonObject6 = new JSONObject(map);
+ actualFromMapStr = jsonObject6.toString();
assertTrue("bigDec in map (or array or bean) is a bigDec",
actualFromMapStr.equals(
"{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}"));
// bigDec put
- jsonObject = new JSONObject();
- jsonObject.put("bigDec", bigDecimal);
- actualFromPutStr = jsonObject.toString();
+ JSONObject jsonObject7 = new JSONObject();
+ jsonObject7.put("bigDec", bigDecimal);
+ actualFromPutStr = jsonObject7.toString();
assertTrue("bigDec from put is a number",
actualFromPutStr.equals(
"{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}"));
// bigInt,bigDec put
- JSONArray jsonArray = new JSONArray();
- jsonArray.put(bigInteger);
- jsonArray.put(bigDecimal);
- actualFromPutStr = jsonArray.toString();
+ JSONArray jsonArray0 = new JSONArray();
+ jsonArray0.put(bigInteger);
+ jsonArray0.put(bigDecimal);
+ actualFromPutStr = jsonArray0.toString();
assertTrue("bigInt, bigDec from put is a number",
actualFromPutStr.equals(
"[123456789012345678901234567890,123456789012345678901234567890.12345678901234567890123456789]"));
- assertTrue("getBigInt is bigInt", jsonArray.getBigInteger(0).equals(bigInteger));
- assertTrue("getBigDec is bigDec", jsonArray.getBigDecimal(1).equals(bigDecimal));
- assertTrue("optBigInt is bigInt", jsonArray.optBigInteger(0, BigInteger.ONE).equals(bigInteger));
- assertTrue("optBigDec is bigDec", jsonArray.optBigDecimal(1, BigDecimal.ONE).equals(bigDecimal));
- jsonArray.put(Boolean.TRUE);
+ assertTrue("getBigInt is bigInt", jsonArray0.getBigInteger(0).equals(bigInteger));
+ assertTrue("getBigDec is bigDec", jsonArray0.getBigDecimal(1).equals(bigDecimal));
+ assertTrue("optBigInt is bigInt", jsonArray0.optBigInteger(0, BigInteger.ONE).equals(bigInteger));
+ assertTrue("optBigDec is bigDec", jsonArray0.optBigDecimal(1, BigDecimal.ONE).equals(bigDecimal));
+ jsonArray0.put(Boolean.TRUE);
try {
- jsonArray.getBigInteger(2);
+ jsonArray0.getBigInteger(2);
fail("should not be able to get big int");
} catch (Exception ignored) {}
try {
- jsonArray.getBigDecimal(2);
+ jsonArray0.getBigDecimal(2);
fail("should not be able to get big dec");
} catch (Exception ignored) {}
- assertTrue("optBigInt is default", jsonArray.optBigInteger(2, BigInteger.ONE).equals(BigInteger.ONE));
- assertTrue("optBigDec is default", jsonArray.optBigDecimal(2, BigDecimal.ONE).equals(BigDecimal.ONE));
+ assertTrue("optBigInt is default", jsonArray0.optBigInteger(2, BigInteger.ONE).equals(BigInteger.ONE));
+ assertTrue("optBigDec is default", jsonArray0.optBigDecimal(2, BigDecimal.ONE).equals(BigDecimal.ONE));
// bigInt,bigDec list ctor
List list = new ArrayList();
list.add(bigInteger);
list.add(bigDecimal);
- jsonArray = new JSONArray(list);
- String actualFromListStr = jsonArray.toString();
+ JSONArray jsonArray1 = new JSONArray(list);
+ String actualFromListStr = jsonArray1.toString();
assertTrue("bigInt, bigDec in list is a bigInt, bigDec",
actualFromListStr.equals(
"[123456789012345678901234567890,123456789012345678901234567890.12345678901234567890123456789]"));
// bigInt bean ctor
MyBigNumberBean myBigNumberBean = mock(MyBigNumberBean.class);
when(myBigNumberBean.getBigInteger()).thenReturn(new BigInteger("123456789012345678901234567890"));
- jsonObject = new JSONObject(myBigNumberBean);
- String actualFromBeanStr = jsonObject.toString();
+ JSONObject jsonObject8 = new JSONObject(myBigNumberBean);
+ String actualFromBeanStr = jsonObject8.toString();
// can't do a full string compare because mockery adds an extra key/value
assertTrue("bigInt from bean ctor is a bigInt",
actualFromBeanStr.contains("123456789012345678901234567890"));
// bigDec bean ctor
myBigNumberBean = mock(MyBigNumberBean.class);
when(myBigNumberBean.getBigDecimal()).thenReturn(new BigDecimal("123456789012345678901234567890.12345678901234567890123456789"));
- jsonObject = new JSONObject(myBigNumberBean);
- actualFromBeanStr = jsonObject.toString();
+ jsonObject8 = new JSONObject(myBigNumberBean);
+ actualFromBeanStr = jsonObject8.toString();
// can't do a full string compare because mockery adds an extra key/value
assertTrue("bigDec from bean ctor is a bigDec",
actualFromBeanStr.contains("123456789012345678901234567890.12345678901234567890123456789"));
@@ -1426,7 +1442,12 @@ public class JSONObjectTest {
assertTrue("wrap() returns big num",obj.equals(bigInteger));
obj = JSONObject.wrap(bigDecimal);
assertTrue("wrap() returns string",obj.equals(bigDecimal));
-
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject0, jsonObject1, jsonObject2, jsonObject3, jsonObject4,
+ jsonObject5, jsonObject6, jsonObject7, jsonObject8
+ )));
+ Util.checkJSONArrayMaps(jsonArray0, jsonObject0.getMapType());
+ Util.checkJSONArrayMaps(jsonArray1, jsonObject0.getMapType());
}
/**
@@ -1438,7 +1459,6 @@ public class JSONObjectTest {
*/
@Test
public void jsonObjectNames() {
- JSONObject jsonObject;
// getNames() from null JSONObject
assertTrue("null names from null Object",
@@ -1449,16 +1469,16 @@ public class JSONObjectTest {
null == JSONObject.getNames(new MyJsonString()));
// getNames from new JSONOjbect
- jsonObject = new JSONObject();
- String [] names = JSONObject.getNames(jsonObject);
+ JSONObject jsonObject0 = new JSONObject();
+ String [] names = JSONObject.getNames(jsonObject0);
assertTrue("names should be null", names == null);
// getNames() from empty JSONObject
String emptyStr = "{}";
- jsonObject = new JSONObject(emptyStr);
+ JSONObject jsonObject1 = new JSONObject(emptyStr);
assertTrue("empty JSONObject should have null names",
- null == JSONObject.getNames(jsonObject));
+ null == JSONObject.getNames(jsonObject1));
// getNames() from JSONObject
String str =
@@ -1467,13 +1487,13 @@ public class JSONObjectTest {
"\"falseKey\":false,"+
"\"stringKey\":\"hello world!\","+
"}";
- jsonObject = new JSONObject(str);
- names = JSONObject.getNames(jsonObject);
- JSONArray jsonArray = new JSONArray(names);
+ JSONObject jsonObject2 = new JSONObject(str);
+ names = JSONObject.getNames(jsonObject2);
+ JSONArray jsonArray0 = new JSONArray(names);
// validate JSON
Object doc = Configuration.defaultConfiguration().jsonProvider()
- .parse(jsonArray.toString());
+ .parse(jsonArray0.toString());
List> docList = JsonPath.read(doc, "$");
assertTrue("expected 3 items", docList.size() == 3);
assertTrue(
@@ -1494,9 +1514,9 @@ public class JSONObjectTest {
names = JSONObject.getNames(myEnumField);
// validate JSON
- jsonArray = new JSONArray(names);
+ JSONArray jsonArray1 = new JSONArray(names);
doc = Configuration.defaultConfiguration().jsonProvider()
- .parse(jsonArray.toString());
+ .parse(jsonArray1.toString());
docList = JsonPath.read(doc, "$");
assertTrue("expected 3 items", docList.size() == 3);
assertTrue(
@@ -1518,9 +1538,9 @@ public class JSONObjectTest {
names = JSONObject.getNames(myPublicClass);
// validate JSON
- jsonArray = new JSONArray(names);
+ JSONArray jsonArray2 = new JSONArray(names);
doc = Configuration.defaultConfiguration().jsonProvider()
- .parse(jsonArray.toString());
+ .parse(jsonArray2.toString());
docList = JsonPath.read(doc, "$");
assertTrue("expected 2 items", docList.size() == 2);
assertTrue(
@@ -1529,6 +1549,12 @@ public class JSONObjectTest {
assertTrue(
"expected to find publicInt",
((List>) JsonPath.read(doc, "$[?(@=='publicInt')]")).size() == 1);
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject0, jsonObject1, jsonObject2
+ )));
+ Util.checkJSONArrayMaps(jsonArray0, jsonObject0.getMapType());
+ Util.checkJSONArrayMaps(jsonArray1, jsonObject0.getMapType());
+ Util.checkJSONArrayMaps(jsonArray2, jsonObject0.getMapType());
}
/**
@@ -1540,6 +1566,8 @@ public class JSONObjectTest {
JSONObject jsonObject = new JSONObject();
JSONArray jsonArray = jsonObject.names();
assertTrue("jsonArray should be null", jsonArray == null);
+ Util.checkJSONObjectMaps(jsonObject);
+ Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
}
/**
@@ -1564,6 +1592,8 @@ public class JSONObjectTest {
assertTrue("expected to find trueKey", ((List>) JsonPath.read(doc, "$[?(@=='trueKey')]")).size() == 1);
assertTrue("expected to find falseKey", ((List>) JsonPath.read(doc, "$[?(@=='falseKey')]")).size() == 1);
assertTrue("expected to find stringKey", ((List>) JsonPath.read(doc, "$[?(@=='stringKey')]")).size() == 1);
+ Util.checkJSONObjectMaps(jsonObject);
+ Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
}
/**
@@ -1682,7 +1712,9 @@ public class JSONObjectTest {
// this.put(key, new Float((Float) value + 1));
// Probably it would be better to deprecate the method and remove some day, while convenient processing the "payload" is not
// really in the scope of a JSON-library (IMHO.)
-
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject, inc
+ )));
}
/**
@@ -1780,6 +1812,12 @@ public class JSONObjectTest {
JSONObject bCompareArrayJsonObject = new JSONObject(bCompareArrayStr);
assertTrue("different nested JSONArrays should not be similar",
!aCompareArrayJsonObject.similar(bCompareArrayJsonObject));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject, expectedJsonObject, aCompareValueJsonObject,
+ aCompareArrayJsonObject, aCompareObjectJsonObject, aCompareArrayJsonObject,
+ bCompareValueJsonObject, bCompareArrayJsonObject, bCompareObjectJsonObject,
+ bCompareArrayJsonObject
+ )));
}
/**
@@ -1815,6 +1853,7 @@ public class JSONObjectTest {
assertTrue("expected myVal2", "myVal2".equals(jsonObject.query("/objectKey/myKey2")));
assertTrue("expected myVal3", "myVal3".equals(jsonObject.query("/objectKey/myKey3")));
assertTrue("expected myVal4", "myVal4".equals(jsonObject.query("/objectKey/myKey4")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1888,6 +1927,9 @@ public class JSONObjectTest {
JSONObject jo = new JSONObject().put("TABLE", new JSONObject().put("yhoo", new JSONObject()));
assertEquals("toString(2)","{\"TABLE\": {\"yhoo\": {}}}", jo.toString(2));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject, jo
+ )));
}
/**
@@ -1909,6 +1951,7 @@ public class JSONObjectTest {
assertTrue("expected 1 top level item", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 1);
assertTrue("expected 1 key item", ((Map,?>)(JsonPath.read(doc, "$.key"))).size() == 1);
assertTrue("expected def", "def".equals(jsonObject.query("/key/abc")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1931,6 +1974,7 @@ public class JSONObjectTest {
assertTrue("expected 1 top level item", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 1);
assertTrue("expected 1 key item", ((List>)(JsonPath.read(doc, "$.key"))).size() == 1);
assertTrue("expected abc", "abc".equals(jsonObject.query("/key/0")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1978,7 +2022,9 @@ public class JSONObjectTest {
jsonArray.toString().equals(JSONObject.valueToString(collection)));
Integer[] array = { new Integer(1), new Integer(2), new Integer(3) };
assertTrue("array valueToString() incorrect",
- jsonArray.toString().equals(JSONObject.valueToString(array)));
+ jsonArray.toString().equals(JSONObject.valueToString(array)));
+ Util.checkJSONObjectMaps(jsonObject);
+ Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
}
/**
@@ -2082,6 +2128,11 @@ public class JSONObjectTest {
assertTrue("expected val1", "val1".equals(mapJsonObject.query("/key1")));
assertTrue("expected val2", "val2".equals(mapJsonObject.query("/key2")));
assertTrue("expected val3", "val3".equals(mapJsonObject.query("/key3")));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObject, mapJsonObject
+ )));
+ Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
+ Util.checkJSONArrayMaps(integerArrayJsonArray, jsonObject.getMapType());
}
@@ -2096,6 +2147,7 @@ public class JSONObjectTest {
try {
JSONObject jo = new JSONObject(source);
assertTrue("Expected "+charString+"("+i+") in the JSON Object but did not find it.",charString.equals(jo.getString("key")));
+ Util.checkJSONObjectMaps(jo);
} catch (JSONException ex) {
assertTrue("Only \\0 (U+0000), \\n (U+000A), and \\r (U+000D) should cause an error. Instead "+charString+"("+i+") caused an error",
i=='\0' || i=='\n' || i=='\r'
@@ -2395,6 +2447,7 @@ public class JSONObjectTest {
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
jsonObject.putOnce(null, "");
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2430,6 +2483,7 @@ public class JSONObjectTest {
42l == jsonObject.optNumber("myKey", Long.valueOf(42)).longValue());
assertTrue("optString() should return default string",
"hi".equals(jsonObject.optString("hiKey", "hi")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2466,6 +2520,7 @@ public class JSONObjectTest {
42l == jsonObject.optNumber("myKey", Long.valueOf(42)).longValue());
assertTrue("optString() should return default string",
"hi".equals(jsonObject.optString("hiKey", "hi")));
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2484,6 +2539,7 @@ public class JSONObjectTest {
assertTrue("unexpected optBigDecimal value",jo.optBigDecimal("int",BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0);
assertTrue("unexpected optBigDecimal value",jo.optBigDecimal("int",BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0);
assertTrue("unexpected optNumber value",jo.optNumber("int",BigInteger.ZERO).longValue()==123l);
+ Util.checkJSONObjectMaps(jo);
}
/**
@@ -2518,6 +2574,7 @@ public class JSONObjectTest {
assertNotEquals((int)Double.parseDouble("19007199254740993.35481234487103587486413587843213584"), jo.optInt("largeNumberStr"));
assertEquals(19007199254740992l, (long)Double.parseDouble("19007199254740993.35481234487103587486413587843213584"));
assertEquals(2147483647, (int)Double.parseDouble("19007199254740993.35481234487103587486413587843213584"));
+ Util.checkJSONObjectMaps(jo);
}
/**
@@ -2540,6 +2597,7 @@ public class JSONObjectTest {
assertNull(jo.optBigDecimal("nullVal", null));
assertEquals(jo.optBigDecimal("float", null),jo.getBigDecimal("float"));
assertEquals(jo.optBigDecimal("double", null),jo.getBigDecimal("double"));
+ Util.checkJSONObjectMaps(jo);
}
/**
@@ -2560,6 +2618,7 @@ public class JSONObjectTest {
assertEquals(new BigInteger("1234"),jo.optBigInteger("bigInteger", null));
assertEquals(new BigInteger("1234"),jo.optBigInteger("bigDecimal", null));
assertNull(jo.optBigDecimal("nullVal", null));
+ Util.checkJSONObjectMaps(jo);
}
/**
@@ -2577,8 +2636,9 @@ public class JSONObjectTest {
JSONObject jsonObjectPutNull = new JSONObject(str);
jsonObjectPutNull.put("myKey", (Object) null);
assertTrue("jsonObject should be empty", jsonObjectPutNull.isEmpty());
-
-
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObjectRemove, jsonObjectPutNull
+ )));
}
/**
@@ -2663,6 +2723,7 @@ public class JSONObjectTest {
} finally {
stringWriter.close();
}
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2745,7 +2806,7 @@ public class JSONObjectTest {
writer.close();
} catch (Exception e) {}
}
-
+ Util.checkJSONObjectMaps(jsonObject);
}
@@ -2813,6 +2874,7 @@ public class JSONObjectTest {
stringWriter.close();
} catch (Exception e) {}
}
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2855,6 +2917,7 @@ public class JSONObjectTest {
JSONObject aJsonObject = new JSONObject(str);
assertTrue("Same JSONObject should be equal to itself",
aJsonObject.equals(aJsonObject));
+ Util.checkJSONObjectMaps(aJsonObject);
}
/**
@@ -2940,6 +3003,9 @@ public class JSONObjectTest {
"null ".equals(sJONull));
String sNull = XML.toString(jsonObjectNull);
assertTrue("null should emit an empty string", "".equals(sNull));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jsonObjectJONull, jsonObjectNull
+ )));
}
@Test(expected = JSONPointerException.class)
@@ -3037,6 +3103,7 @@ public class JSONObjectTest {
// 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);
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -3061,6 +3128,9 @@ public class JSONObjectTest {
// ensure our original jo hasn't changed.
assertEquals(0, jo.get("someInt"));
assertEquals(null, jo.opt("someString"));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jo, jo2
+ )));
}
/**
@@ -3085,6 +3155,9 @@ public class JSONObjectTest {
// ensure our original jo hasn't changed.
assertEquals(0, jo.get("someInt"));
assertEquals(null, jo.opt("someString"));
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ jo, jo2
+ )));
}
/**
@@ -3100,6 +3173,7 @@ public class JSONObjectTest {
assertEquals("Expected the getter to only be called once",
1, bean.genericGetCounter);
assertEquals(0, bean.genericSetCounter);
+ Util.checkJSONObjectMaps(jo);
}
/**
@@ -3115,6 +3189,7 @@ public class JSONObjectTest {
assertEquals("Expected the getter to only be called once",
1, bean.genericGetCounter);
assertEquals(0, bean.genericSetCounter);
+ Util.checkJSONObjectMaps(jo);
}
/**
@@ -3133,6 +3208,7 @@ public class JSONObjectTest {
assertEquals("Expected 1 key to be mapped. Instead found: "+jo.keySet().toString(),
1, jo.length());
assertNotNull(jo.get("ALL"));
+ Util.checkJSONObjectMaps(jo);
}
/**
@@ -3150,6 +3226,8 @@ public class JSONObjectTest {
BigDecimal wantedValue = BigDecimal.valueOf(value);
assertEquals(current, wantedValue);
+ Util.checkJSONObjectMaps(jsonObject);
+ Util.checkJSONArrayMaps(array, jsonObject.getMapType());
}
/**
@@ -3163,6 +3241,7 @@ public class JSONObjectTest {
1, jo.length());
assertTrue(jo.get("closeable") instanceof JSONObject);
assertTrue(jo.getJSONObject("closeable").has("string"));
+ Util.checkJSONObjectMaps(jo);
}
@Test(expected=NullPointerException.class)
@@ -3289,9 +3368,12 @@ public class JSONObjectTest {
ObjC.setRef(ObjA);
ObjB.setRef(ObjA);
ObjB.setRef2(ObjA);
- new JSONObject(ObjC);
- new JSONObject(ObjB);
- new JSONObject(ObjA);
+ JSONObject j0 = new JSONObject(ObjC);
+ JSONObject j1 = new JSONObject(ObjB);
+ JSONObject j2 = new JSONObject(ObjA);
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ j0, j1, j2
+ )));
}
@Test
public void testLongRepeatObjectNotRecursive() {
@@ -3307,17 +3389,21 @@ public class JSONObjectTest {
ObjB.setRef2(ObjD);
ObjA.setRef(ObjD);
ObjD.setRef(ObjE);
- new JSONObject(ObjC);
- new JSONObject(ObjB);
- new JSONObject(ObjA);
- new JSONObject(ObjD);
- new JSONObject(ObjE);
+ JSONObject j0 = new JSONObject(ObjC);
+ JSONObject j1 = new JSONObject(ObjB);
+ JSONObject j2 = new JSONObject(ObjA);
+ JSONObject j3 = new JSONObject(ObjD);
+ JSONObject j4 = new JSONObject(ObjE);
+ Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(
+ j0, j1, j2, j3, j4
+ )));
}
@Test(expected=JSONException.class)
public void testRecursiveEquals() {
RecursiveBeanEquals a = new RecursiveBeanEquals("same");
a.setRef(a);
- new JSONObject(a);
+ JSONObject j0 = new JSONObject(a);
+ Util.checkJSONObjectMaps(j0);
}
@Test
public void testNotRecursiveEquals() {
@@ -3326,7 +3412,8 @@ public class JSONObjectTest {
RecursiveBeanEquals c = new RecursiveBeanEquals("same");
a.setRef(b);
b.setRef(c);
- new JSONObject(a);
+ JSONObject j0 = new JSONObject(a);
+ Util.checkJSONObjectMaps(j0);
}
@@ -3336,6 +3423,7 @@ public class JSONObjectTest {
assertTrue("missing expected key 'empty_json_array'", jsonObject.has("empty_json_array"));
assertNotNull("'empty_json_array' should be an array", jsonObject.getJSONArray("empty_json_array"));
assertEquals("'empty_json_array' should have a length of 0", 0, jsonObject.getJSONArray("empty_json_array").length());
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -3351,6 +3439,7 @@ public class JSONObjectTest {
jsonObject.clear(); //Clears the JSONObject
assertTrue("expected jsonObject.length() == 0", jsonObject.length() == 0); //Check if its length is 0
jsonObject.getInt("key1"); //Should throws org.json.JSONException: JSONObject["asd"] not found
+ Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -3364,6 +3453,7 @@ public class JSONObjectTest {
JSONObject json_input = new JSONObject(input);
assertNotNull(json_input);
fail("Excepected Exception.");
+ Util.checkJSONObjectMaps(json_input);
}
/**
@@ -3373,7 +3463,7 @@ public class JSONObjectTest {
public void issue654IncorrectNestingNoKey1() {
JSONObject json_input = new JSONObject("{{\"a\":0}}");
assertNotNull(json_input);
- fail("Excepected Exception.");
+ fail("Expected Exception.");
}
/**
@@ -3398,4 +3488,25 @@ public class JSONObjectTest {
assertNotNull(json_input);
fail("Excepected Exception.");
}
+
+ @Test
+ public void testIssue682SimilarityOfJSONString() {
+ JSONObject jo1 = new JSONObject()
+ .put("a", new MyJsonString())
+ .put("b", 2);
+ JSONObject jo2 = new JSONObject()
+ .put("a", new MyJsonString())
+ .put("b", 2);
+ assertTrue(jo1.similar(jo2));
+
+ JSONObject jo3 = new JSONObject()
+ .put("a", new JSONString() {
+ @Override
+ public String toJSONString() {
+ return "\"different value\"";
+ }
+ })
+ .put("b", 2);
+ assertFalse(jo1.similar(jo3));
+ }
}
diff --git a/src/test/java/org/json/junit/JSONPointerTest.java b/src/test/java/org/json/junit/JSONPointerTest.java
index 4ea7434543165740bbc1e72c2e7c83709cc6f984..45c7dbd3dc872577c108c7fad0e573668548aa37 100644
--- a/src/test/java/org/json/junit/JSONPointerTest.java
+++ b/src/test/java/org/json/junit/JSONPointerTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -92,8 +72,10 @@ public class JSONPointerTest {
@Test
public void queryByEmptyKeySubObject() {
- assertEquals( "{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some" +
- " other value\"}", query("/obj/").toString());
+ JSONObject json = new JSONObject("{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some" +
+ " other value\"}");
+ JSONObject obj = (JSONObject) query("/obj/");
+ assertTrue(json.similar(obj));
}
@Test
diff --git a/src/test/java/org/json/junit/JSONStringTest.java b/src/test/java/org/json/junit/JSONStringTest.java
index a19961103a157342474dd8b68c7dc5c815f6bf3a..b4fee3eb739fbd1b8f57f15668311a3345cb0f8f 100644
--- a/src/test/java/org/json/junit/JSONStringTest.java
+++ b/src/test/java/org/json/junit/JSONStringTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
diff --git a/src/test/java/org/json/junit/JSONStringerTest.java b/src/test/java/org/json/junit/JSONStringerTest.java
index a99db3b8ce1008815cac96bb1f5636d13cbf4cea..0ecb9d662b542e0fc37e8e600f01ea85d72432c7 100644
--- a/src/test/java/org/json/junit/JSONStringerTest.java
+++ b/src/test/java/org/json/junit/JSONStringerTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
diff --git a/src/test/java/org/json/junit/JSONTokenerTest.java b/src/test/java/org/json/junit/JSONTokenerTest.java
index e8e0f98a947ceab05357d0a61aa29b7cc0ed9e77..59ca6d8f62c1718fad2f5a3a52634597707e4e69 100644
--- a/src/test/java/org/json/junit/JSONTokenerTest.java
+++ b/src/test/java/org/json/junit/JSONTokenerTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -333,4 +313,16 @@ public class JSONTokenerTest {
assertEquals(0, t2.next());
assertFalse(t2.more());
}
+
+ @Test
+ public void testAutoClose(){
+ Reader reader = new StringReader("some test string");
+ try {
+ JSONTokener tokener = new JSONTokener(reader);
+ tokener.close();
+ tokener.next();
+ } catch (Exception exception){
+ assertEquals("Stream closed", exception.getMessage());
+ }
+ }
}
diff --git a/src/test/java/org/json/junit/PropertyTest.java b/src/test/java/org/json/junit/PropertyTest.java
index e1a9b8dcfede250220ffe50bb507d71dd4d1bc23..eee482fbf530230fbc8a3e9a8dcc27e42346afb1 100644
--- a/src/test/java/org/json/junit/PropertyTest.java
+++ b/src/test/java/org/json/junit/PropertyTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import java.util.*;
diff --git a/src/test/java/org/json/junit/Util.java b/src/test/java/org/json/junit/Util.java
index 8dc27ddfa8fda38b72c4db97cc8814391b3662ac..b676045b89aea5b3e3c022f64a97b18f10e61494 100644
--- a/src/test/java/org/json/junit/Util.java
+++ b/src/test/java/org/json/junit/Util.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.*;
@@ -78,7 +58,6 @@ public class Util {
* or something else.
* @param value created by the code to be tested
* @param expectedValue created specifically for comparing
- * @param key key to the jsonObject entry to be compared
*/
private static void compareActualVsExpectedObjects(Object value,
Object expectedValue) {
@@ -117,4 +96,106 @@ public class Util {
);
}
}
+
+ /**
+ * Asserts that all JSONObject maps are the same as the default ctor
+ * @param jsonObjects list of objects to be tested
+ */
+ public static void checkJSONObjectsMaps(List jsonObjects) {
+ if (jsonObjects == null || jsonObjects.size() == 0) {
+ return;
+ }
+ Class extends Map> mapType = new JSONObject().getMapType();
+ for (JSONObject jsonObject : jsonObjects) {
+ if (jsonObject != null) {
+ assertTrue(mapType == jsonObject.getMapType());
+ checkJSONObjectMaps(jsonObject, mapType);
+ }
+ }
+ }
+
+ /**
+ * Asserts that all JSONObject maps are the same as the default ctor
+ * @param jsonObject the object to be tested
+ */
+ public static void checkJSONObjectMaps(JSONObject jsonObject) {
+ if (jsonObject != null) {
+ checkJSONObjectMaps(jsonObject, jsonObject.getMapType());
+ }
+ }
+
+ /**
+ * Asserts that all JSONObject maps are the same as mapType
+ * @param jsonObject object to be tested
+ * @param mapType mapType to test against
+ */
+ public static void checkJSONObjectMaps(JSONObject jsonObject, Class extends Map> mapType) {
+ if (mapType == null) {
+ mapType = new JSONObject().getMapType();
+ }
+ Set keys = jsonObject.keySet();
+ for (String key : keys) {
+ Object val = jsonObject.get(key);
+ if (val instanceof JSONObject) {
+ JSONObject jsonObjectVal = (JSONObject) val;
+ assertTrue(mapType == ((JSONObject) val).getMapType());
+ checkJSONObjectMaps(jsonObjectVal, mapType);
+ } else if (val instanceof JSONArray) {
+ JSONArray jsonArrayVal = (JSONArray)val;
+ checkJSONArrayMaps(jsonArrayVal, mapType);
+ }
+ }
+ }
+
+ /**
+ * Asserts that all JSONObject maps in the JSONArray object match the default map
+ * @param jsonArrays list of JSONArray objects to be tested
+ */
+ public static void checkJSONArraysMaps(List jsonArrays) {
+ if (jsonArrays == null || jsonArrays.size() == 0) {
+ return;
+ }
+ Class extends Map> mapType = new JSONObject().getMapType();
+ for (JSONArray jsonArray : jsonArrays) {
+ if (jsonArray != null) {
+ checkJSONArrayMaps(jsonArray, mapType);
+ }
+ }
+ }
+
+ /**
+ * Asserts that all JSONObject maps in the JSONArray object match mapType
+ * @param jsonArray object to be tested
+ * @param mapType map type to be tested against
+ */
+ public static void checkJSONArrayMaps(JSONArray jsonArray, Class extends Map> mapType) {
+ if (jsonArray == null) {
+ return;
+ }
+ if (mapType == null) {
+ mapType = new JSONObject().getMapType();
+ }
+ Iterator it = jsonArray.iterator();
+ while (it.hasNext()) {
+ Object val = it.next();
+ if (val instanceof JSONObject) {
+ JSONObject jsonObjectVal = (JSONObject)val;
+ checkJSONObjectMaps(jsonObjectVal, mapType);
+ } else if (val instanceof JSONArray) {
+ JSONArray jsonArrayVal = (JSONArray)val;
+ checkJSONArrayMaps(jsonArrayVal, mapType);
+ }
+ }
+ }
+
+ /**
+ * Asserts that all JSONObject maps nested in the JSONArray match
+ * the default mapType
+ * @param jsonArray the object to be tested
+ */
+ public static void checkJSONArrayMaps(JSONArray jsonArray) {
+ if (jsonArray != null) {
+ checkJSONArrayMaps(jsonArray, null);
+ }
+ }
}
diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java
index 2ab06be05aed38f697295118f103ab4d002e7dce..21a2b595ec932fe093d358bf0287060e5b143705 100755
--- a/src/test/java/org/json/junit/XMLConfigurationTest.java
+++ b/src/test/java/org/json/junit/XMLConfigurationTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -1071,6 +1051,29 @@ public class XMLConfigurationTest {
Util.compareActualVsExpectedJsonObjects(jsonObject, expetedJsonObject);
}
+
+ @Test
+ public void testMaxNestingDepthIsSet() {
+ XMLParserConfiguration xmlParserConfiguration = XMLParserConfiguration.ORIGINAL;
+
+ assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH);
+
+ xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(42);
+
+ assertEquals(xmlParserConfiguration.getMaxNestingDepth(), 42);
+
+ xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(0);
+
+ assertEquals(xmlParserConfiguration.getMaxNestingDepth(), 0);
+
+ xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(-31415926);
+
+ assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH);
+
+ xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(Integer.MIN_VALUE);
+
+ assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH);
+ }
/**
* Convenience method, given an input string and expected result,
diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java
index 015547220b93c046093386aa753b8f1c9890cbd8..aefaa49da0707f35d309890c915f85bc8bbea8ad 100644
--- a/src/test/java/org/json/junit/XMLTest.java
+++ b/src/test/java/org/json/junit/XMLTest.java
@@ -1,27 +1,7 @@
package org.json.junit;
/*
-Copyright (c) 2020 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -41,13 +21,7 @@ import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-import org.json.XML;
-import org.json.XMLParserConfiguration;
-import org.json.XMLXsiTypeConverter;
+import org.json.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -1069,4 +1043,276 @@ public class XMLTest {
fail("Expected to be unable to modify the config");
} catch (Exception ignored) { }
}
+
+ @Test
+ public void testIndentComplicatedJsonObject(){
+ String str = "{\n" +
+ " \"success\": true,\n" +
+ " \"error\": null,\n" +
+ " \"response\": [\n" +
+ " {\n" +
+ " \"timestamp\": 1664917200,\n" +
+ " \"dateTimeISO\": \"2022-10-05T00:00:00+03:00\",\n" +
+ " \"loc\": {\n" +
+ " \"lat\": 39.91987,\n" +
+ " \"long\": 32.85427\n" +
+ " },\n" +
+ " \"place\": {\n" +
+ " \"name\": \"ankara\",\n" +
+ " \"state\": \"an\",\n" +
+ " \"country\": \"tr\"\n" +
+ " },\n" +
+ " \"profile\": {\n" +
+ " \"tz\": \"Europe/Istanbul\"\n" +
+ " },\n" +
+ " \"sun\": {\n" +
+ " \"rise\": 1664941721,\n" +
+ " \"riseISO\": \"2022-10-05T06:48:41+03:00\",\n" +
+ " \"set\": 1664983521,\n" +
+ " \"setISO\": \"2022-10-05T18:25:21+03:00\",\n" +
+ " \"transit\": 1664962621,\n" +
+ " \"transitISO\": \"2022-10-05T12:37:01+03:00\",\n" +
+ " \"midnightSun\": false,\n" +
+ " \"polarNight\": false,\n" +
+ " \"twilight\": {\n" +
+ " \"civilBegin\": 1664940106,\n" +
+ " \"civilBeginISO\": \"2022-10-05T06:21:46+03:00\",\n" +
+ " \"civilEnd\": 1664985136,\n" +
+ " \"civilEndISO\": \"2022-10-05T18:52:16+03:00\",\n" +
+ " \"nauticalBegin\": 1664938227,\n" +
+ " \"nauticalBeginISO\": \"2022-10-05T05:50:27+03:00\",\n" +
+ " \"nauticalEnd\": 1664987015,\n" +
+ " \"nauticalEndISO\": \"2022-10-05T19:23:35+03:00\",\n" +
+ " \"astronomicalBegin\": 1664936337,\n" +
+ " \"astronomicalBeginISO\": \"2022-10-05T05:18:57+03:00\",\n" +
+ " \"astronomicalEnd\": 1664988905,\n" +
+ " \"astronomicalEndISO\": \"2022-10-05T19:55:05+03:00\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"moon\": {\n" +
+ " \"rise\": 1664976480,\n" +
+ " \"riseISO\": \"2022-10-05T16:28:00+03:00\",\n" +
+ " \"set\": 1664921520,\n" +
+ " \"setISO\": \"2022-10-05T01:12:00+03:00\",\n" +
+ " \"transit\": 1664994240,\n" +
+ " \"transitISO\": \"2022-10-05T21:24:00+03:00\",\n" +
+ " \"underfoot\": 1664949360,\n" +
+ " \"underfootISO\": \"2022-10-05T08:56:00+03:00\",\n" +
+ " \"phase\": {\n" +
+ " \"phase\": 0.3186,\n" +
+ " \"name\": \"waxing gibbous\",\n" +
+ " \"illum\": 71,\n" +
+ " \"age\": 9.41,\n" +
+ " \"angle\": 0.55\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ "}" ;
+ JSONObject jsonObject = new JSONObject(str);
+ String actualIndentedXmlString = XML.toString(jsonObject, 1);
+ JSONObject actualJsonObject = XML.toJSONObject(actualIndentedXmlString);
+ String expected = "true \n" +
+ "\n" +
+ " 2022-10-05T00:00:00+03:00 \n" +
+ " \n" +
+ " 39.91987 \n" +
+ " 32.85427 \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 0.3186 \n" +
+ " waxing gibbous \n" +
+ " 0.55 \n" +
+ " 71 \n" +
+ " 9.41 \n" +
+ " \n" +
+ " 2022-10-05T01:12:00+03:00 \n" +
+ " 1664949360 \n" +
+ " 1664921520 \n" +
+ " 1664994240 \n" +
+ " 2022-10-05T21:24:00+03:00 \n" +
+ " 2022-10-05T16:28:00+03:00 \n" +
+ " 1664976480 \n" +
+ " 2022-10-05T08:56:00+03:00 \n" +
+ " \n" +
+ " \n" +
+ " Europe/Istanbul \n" +
+ " \n" +
+ " \n" +
+ " tr \n" +
+ " ankara \n" +
+ " an \n" +
+ " \n" +
+ " \n" +
+ " 2022-10-05T18:25:21+03:00 \n" +
+ " false \n" +
+ " 1664983521 \n" +
+ " 1664962621 \n" +
+ " false \n" +
+ " 2022-10-05T12:37:01+03:00 \n" +
+ " 2022-10-05T06:48:41+03:00 \n" +
+ " 1664941721 \n" +
+ " \n" +
+ " 1664985136 \n" +
+ " 1664936337 \n" +
+ " 1664988905 \n" +
+ " 2022-10-05T05:18:57+03:00 \n" +
+ " 1664940106 \n" +
+ " 2022-10-05T19:23:35+03:00 \n" +
+ " 2022-10-05T19:55:05+03:00 \n" +
+ " 1664938227 \n" +
+ " 1664987015 \n" +
+ " 2022-10-05T05:50:27+03:00 \n" +
+ " 2022-10-05T06:21:46+03:00 \n" +
+ " 2022-10-05T18:52:16+03:00 \n" +
+ " \n" +
+ " \n" +
+ " 1664917200 \n" +
+ " \n" +
+ "null \n";
+ JSONObject expectedJsonObject = XML.toJSONObject(expected);
+ assertTrue(expectedJsonObject.similar(actualJsonObject));
+
+
+ }
+ @Test
+ public void testIndentSimpleJsonObject(){
+ String str = "{ \"employee\": { \n" +
+ " \"name\": \"sonoo\", \n" +
+ " \"salary\": 56000, \n" +
+ " \"married\": true \n" +
+ " }}";
+ JSONObject jsonObject = new JSONObject(str);
+ String actual = XML.toString(jsonObject, "Test", 2);
+ JSONObject actualJsonObject = XML.toJSONObject(actual);
+ String expected = "\n" +
+ " \n" +
+ " sonoo \n" +
+ " 56000 \n" +
+ " true \n" +
+ " \n" +
+ " \n";
+ JSONObject expectedJsonObject = XML.toJSONObject(expected);
+ assertTrue(expectedJsonObject.similar(actualJsonObject));
+ }
+
+ @Test
+ public void testIndentSimpleJsonArray(){
+ String str = "[ \n" +
+ " {\"name\":\"Ram\", \"email\":\"Ram@gmail.com\"}, \n" +
+ " {\"name\":\"Bob\", \"email\":\"bob32@gmail.com\"} \n" +
+ "] ";
+ JSONArray jsonObject = new JSONArray(str);
+ String actual = XML.toString(jsonObject, 2);
+ JSONObject actualJsonObject = XML.toJSONObject(actual);
+ String expected = "\n" +
+ " Ram \n" +
+ " Ram@gmail.com \n" +
+ " \n" +
+ "\n" +
+ " Bob \n" +
+ " bob32@gmail.com \n" +
+ " \n";
+ JSONObject expectedJsonObject = XML.toJSONObject(expected);
+ assertTrue(expectedJsonObject.similar(actualJsonObject));
+
+
+ }
+
+ @Test
+ public void testIndentComplicatedJsonObjectWithArrayAndWithConfig(){
+ try {
+ InputStream jsonStream = null;
+ try {
+ jsonStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.json");
+ final JSONObject object = new JSONObject(new JSONTokener(jsonStream));
+ String actualString = XML.toString(object, null, XMLParserConfiguration.KEEP_STRINGS,2);
+ InputStream xmlStream = null;
+ try {
+ xmlStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.xml");
+ int bufferSize = 1024;
+ char[] buffer = new char[bufferSize];
+ StringBuilder expected = new StringBuilder();
+ Reader in = new InputStreamReader(xmlStream, "UTF-8");
+ for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) {
+ expected.append(buffer, 0, numRead);
+ }
+ assertEquals(expected.toString(), actualString.replaceAll("\\n|\\r\\n", System.getProperty("line.separator")));
+ } finally {
+ if (xmlStream != null) {
+ xmlStream.close();
+ }
+ }
+ } finally {
+ if (jsonStream != null) {
+ jsonStream.close();
+ }
+ }
+ } catch (IOException e) {
+ fail("file writer error: " +e.getMessage());
+ }
+ }
+
+ @Test
+ public void testMaxNestingDepthOf42IsRespected() {
+ final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "");
+
+ final int maxNestingDepth = 42;
+
+ try {
+ XML.toJSONObject(wayTooLongMalformedXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
+ }
+ }
+
+ @Test
+ public void testMaxNestingDepthIsRespectedWithValidXML() {
+ final String perfectlyFineXML = "\n" +
+ " \n" +
+ " sonoo \n" +
+ " 56000 \n" +
+ " true \n" +
+ " \n" +
+ " \n";
+
+ final int maxNestingDepth = 1;
+
+ try {
+ XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
+ }
+ }
+
+ @Test
+ public void testMaxNestingDepthWithValidFittingXML() {
+ final String perfectlyFineXML = "\n" +
+ " \n" +
+ " sonoo \n" +
+ " 56000 \n" +
+ " true \n" +
+ " \n" +
+ " \n";
+
+ final int maxNestingDepth = 3;
+
+ try {
+ XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
+ "parameter of the XMLParserConfiguration used");
+ }
+ }
}
+
+
+
diff --git a/src/test/resources/Issue593.json b/src/test/resources/Issue593.json
new file mode 100644
index 0000000000000000000000000000000000000000..213625af23438cef7e8883b16403cb8e75c9ef1c
--- /dev/null
+++ b/src/test/resources/Issue593.json
@@ -0,0 +1,704 @@
+{
+ "success": true,
+ "error": null,
+ "response": [
+ {
+ "loc": {
+ "long": 31.25,
+ "lat": 30.063
+ },
+ "interval": "day",
+ "place": {
+ "name": "cairo",
+ "state": "qh",
+ "country": "eg"
+ },
+ "periods": [
+ {
+ "timestamp": 1665032400,
+ "validTime": "2022-10-06T07:00:00+02:00",
+ "dateTimeISO": "2022-10-06T07:00:00+02:00",
+ "maxTempC": 32,
+ "maxTempF": 90,
+ "minTempC": 19,
+ "minTempF": 66,
+ "avgTempC": 25,
+ "avgTempF": 78,
+ "tempC": null,
+ "tempF": null,
+ "maxFeelslikeC": 32,
+ "maxFeelslikeF": 89,
+ "minFeelslikeC": 21,
+ "minFeelslikeF": 70,
+ "avgFeelslikeC": 26,
+ "avgFeelslikeF": 80,
+ "feelslikeC": 21,
+ "feelslikeF": 70,
+ "maxDewpointC": 17,
+ "maxDewpointF": 63,
+ "minDewpointC": 11,
+ "minDewpointF": 52,
+ "avgDewpointC": 14,
+ "avgDewpointF": 58,
+ "dewpointC": 17,
+ "dewpointF": 63,
+ "maxHumidity": 77,
+ "minHumidity": 29,
+ "humidity": 77,
+ "pop": 0,
+ "precipMM": 0,
+ "precipIN": 0,
+ "iceaccum": null,
+ "iceaccumMM": null,
+ "iceaccumIN": null,
+ "snowCM": 0,
+ "snowIN": 0,
+ "pressureMB": 1015,
+ "pressureIN": 29.97,
+ "windDir": "N",
+ "windDirDEG": 353,
+ "windSpeedKTS": 5,
+ "windSpeedKPH": 9,
+ "windSpeedMPH": 6,
+ "windGustKTS": 21,
+ "windGustKPH": 40,
+ "windGustMPH": 25,
+ "windDirMax": "NNW",
+ "windDirMaxDEG": 342,
+ "windSpeedMaxKTS": 9,
+ "windSpeedMaxKPH": 16,
+ "windSpeedMaxMPH": 10,
+ "windDirMin": "N",
+ "windDirMinDEG": 353,
+ "windSpeedMinKTS": 1,
+ "windSpeedMinKPH": 2,
+ "windSpeedMinMPH": 1,
+ "windDir80m": "N",
+ "windDir80mDEG": 11,
+ "windSpeed80mKTS": 12,
+ "windSpeed80mKPH": 22,
+ "windSpeed80mMPH": 13,
+ "windGust80mKTS": 22,
+ "windGust80mKPH": 41,
+ "windGust80mMPH": 25,
+ "windDirMax80m": "NNW",
+ "windDirMax80mDEG": 343,
+ "windSpeedMax80mKTS": 22,
+ "windSpeedMax80mKPH": 41,
+ "windSpeedMax80mMPH": 25,
+ "windDirMin80m": "E",
+ "windDirMin80mDEG": 95,
+ "windSpeedMin80mKTS": 8,
+ "windSpeedMin80mKPH": 15,
+ "windSpeedMin80mMPH": 10,
+ "sky": 22,
+ "cloudsCoded": "FW",
+ "weather": "Mostly Sunny",
+ "weatherCoded": [],
+ "weatherPrimary": "Mostly Sunny",
+ "weatherPrimaryCoded": "::FW",
+ "icon": "fair.png",
+ "visibilityKM": 24.135,
+ "visibilityMI": 15,
+ "uvi": 6,
+ "solradWM2": 5608,
+ "solradMinWM2": 0,
+ "solradMaxWM2": 778,
+ "isDay": true,
+ "maxCoverage": "",
+ "sunrise": 1665028274,
+ "sunset": 1665070502,
+ "sunriseISO": "2022-10-06T05:51:14+02:00",
+ "sunsetISO": "2022-10-06T17:35:02+02:00"
+ },
+ {
+ "timestamp": 1665118800,
+ "validTime": "2022-10-07T07:00:00+02:00",
+ "dateTimeISO": "2022-10-07T07:00:00+02:00",
+ "maxTempC": 30,
+ "maxTempF": 86,
+ "minTempC": 19,
+ "minTempF": 66,
+ "avgTempC": 24,
+ "avgTempF": 76,
+ "tempC": null,
+ "tempF": null,
+ "maxFeelslikeC": 29,
+ "maxFeelslikeF": 85,
+ "minFeelslikeC": 19,
+ "minFeelslikeF": 67,
+ "avgFeelslikeC": 24,
+ "avgFeelslikeF": 76,
+ "feelslikeC": 19,
+ "feelslikeF": 67,
+ "maxDewpointC": 15,
+ "maxDewpointF": 60,
+ "minDewpointC": 10,
+ "minDewpointF": 50,
+ "avgDewpointC": 12,
+ "avgDewpointF": 54,
+ "dewpointC": 15,
+ "dewpointF": 60,
+ "maxHumidity": 77,
+ "minHumidity": 30,
+ "humidity": 77,
+ "pop": 0,
+ "precipMM": 0,
+ "precipIN": 0,
+ "iceaccum": null,
+ "iceaccumMM": null,
+ "iceaccumIN": null,
+ "snowCM": 0,
+ "snowIN": 0,
+ "pressureMB": 1014,
+ "pressureIN": 29.95,
+ "windDir": "NW",
+ "windDirDEG": 325,
+ "windSpeedKTS": 1,
+ "windSpeedKPH": 2,
+ "windSpeedMPH": 1,
+ "windGustKTS": 16,
+ "windGustKPH": 29,
+ "windGustMPH": 18,
+ "windDirMax": "WNW",
+ "windDirMaxDEG": 298,
+ "windSpeedMaxKTS": 7,
+ "windSpeedMaxKPH": 13,
+ "windSpeedMaxMPH": 8,
+ "windDirMin": "NW",
+ "windDirMinDEG": 325,
+ "windSpeedMinKTS": 1,
+ "windSpeedMinKPH": 2,
+ "windSpeedMinMPH": 1,
+ "windDir80m": "NNW",
+ "windDir80mDEG": 347,
+ "windSpeed80mKTS": 6,
+ "windSpeed80mKPH": 10,
+ "windSpeed80mMPH": 6,
+ "windGust80mKTS": 20,
+ "windGust80mKPH": 37,
+ "windGust80mMPH": 23,
+ "windDirMax80m": "NW",
+ "windDirMax80mDEG": 316,
+ "windSpeedMax80mKTS": 20,
+ "windSpeedMax80mKPH": 37,
+ "windSpeedMax80mMPH": 23,
+ "windDirMin80m": "NNW",
+ "windDirMin80mDEG": 347,
+ "windSpeedMin80mKTS": 6,
+ "windSpeedMin80mKPH": 10,
+ "windSpeedMin80mMPH": 6,
+ "sky": 30,
+ "cloudsCoded": "FW",
+ "weather": "Mostly Sunny",
+ "weatherCoded": [],
+ "weatherPrimary": "Mostly Sunny",
+ "weatherPrimaryCoded": "::FW",
+ "icon": "fair.png",
+ "visibilityKM": 24.135,
+ "visibilityMI": 15,
+ "uvi": 6,
+ "solradWM2": 5486,
+ "solradMinWM2": 0,
+ "solradMaxWM2": 742,
+ "isDay": true,
+ "maxCoverage": "",
+ "sunrise": 1665114710,
+ "sunset": 1665156831,
+ "sunriseISO": "2022-10-07T05:51:50+02:00",
+ "sunsetISO": "2022-10-07T17:33:51+02:00"
+ },
+ {
+ "timestamp": 1665205200,
+ "validTime": "2022-10-08T07:00:00+02:00",
+ "dateTimeISO": "2022-10-08T07:00:00+02:00",
+ "maxTempC": 30,
+ "maxTempF": 87,
+ "minTempC": 19,
+ "minTempF": 66,
+ "avgTempC": 25,
+ "avgTempF": 76,
+ "tempC": null,
+ "tempF": null,
+ "maxFeelslikeC": 30,
+ "maxFeelslikeF": 86,
+ "minFeelslikeC": 19,
+ "minFeelslikeF": 67,
+ "avgFeelslikeC": 25,
+ "avgFeelslikeF": 76,
+ "feelslikeC": 19,
+ "feelslikeF": 67,
+ "maxDewpointC": 15,
+ "maxDewpointF": 59,
+ "minDewpointC": 11,
+ "minDewpointF": 52,
+ "avgDewpointC": 13,
+ "avgDewpointF": 56,
+ "dewpointC": 15,
+ "dewpointF": 59,
+ "maxHumidity": 76,
+ "minHumidity": 32,
+ "humidity": 76,
+ "pop": 0,
+ "precipMM": 0,
+ "precipIN": 0,
+ "iceaccum": null,
+ "iceaccumMM": null,
+ "iceaccumIN": null,
+ "snowCM": 0,
+ "snowIN": 0,
+ "pressureMB": 1014,
+ "pressureIN": 29.94,
+ "windDir": "NNE",
+ "windDirDEG": 21,
+ "windSpeedKTS": 1,
+ "windSpeedKPH": 2,
+ "windSpeedMPH": 1,
+ "windGustKTS": 17,
+ "windGustKPH": 32,
+ "windGustMPH": 20,
+ "windDirMax": "WNW",
+ "windDirMaxDEG": 301,
+ "windSpeedMaxKTS": 7,
+ "windSpeedMaxKPH": 13,
+ "windSpeedMaxMPH": 8,
+ "windDirMin": "NNE",
+ "windDirMinDEG": 21,
+ "windSpeedMinKTS": 1,
+ "windSpeedMinKPH": 2,
+ "windSpeedMinMPH": 1,
+ "windDir80m": "NW",
+ "windDir80mDEG": 309,
+ "windSpeed80mKTS": 5,
+ "windSpeed80mKPH": 9,
+ "windSpeed80mMPH": 5,
+ "windGust80mKTS": 17,
+ "windGust80mKPH": 31,
+ "windGust80mMPH": 19,
+ "windDirMax80m": "NW",
+ "windDirMax80mDEG": 322,
+ "windSpeedMax80mKTS": 17,
+ "windSpeedMax80mKPH": 31,
+ "windSpeedMax80mMPH": 19,
+ "windDirMin80m": "NW",
+ "windDirMin80mDEG": 309,
+ "windSpeedMin80mKTS": 5,
+ "windSpeedMin80mKPH": 9,
+ "windSpeedMin80mMPH": 5,
+ "sky": 47,
+ "cloudsCoded": "SC",
+ "weather": "Partly Cloudy",
+ "weatherCoded": [],
+ "weatherPrimary": "Partly Cloudy",
+ "weatherPrimaryCoded": "::SC",
+ "icon": "pcloudy.png",
+ "visibilityKM": 24.135,
+ "visibilityMI": 15,
+ "uvi": 7,
+ "solradWM2": 4785,
+ "solradMinWM2": 0,
+ "solradMaxWM2": 682,
+ "isDay": true,
+ "maxCoverage": "",
+ "sunrise": 1665201146,
+ "sunset": 1665243161,
+ "sunriseISO": "2022-10-08T05:52:26+02:00",
+ "sunsetISO": "2022-10-08T17:32:41+02:00"
+ },
+ {
+ "timestamp": 1665291600,
+ "validTime": "2022-10-09T07:00:00+02:00",
+ "dateTimeISO": "2022-10-09T07:00:00+02:00",
+ "maxTempC": 31,
+ "maxTempF": 87,
+ "minTempC": 19,
+ "minTempF": 67,
+ "avgTempC": 25,
+ "avgTempF": 77,
+ "tempC": null,
+ "tempF": null,
+ "maxFeelslikeC": 30,
+ "maxFeelslikeF": 86,
+ "minFeelslikeC": 20,
+ "minFeelslikeF": 67,
+ "avgFeelslikeC": 25,
+ "avgFeelslikeF": 77,
+ "feelslikeC": 20,
+ "feelslikeF": 67,
+ "maxDewpointC": 17,
+ "maxDewpointF": 63,
+ "minDewpointC": 11,
+ "minDewpointF": 52,
+ "avgDewpointC": 14,
+ "avgDewpointF": 57,
+ "dewpointC": 17,
+ "dewpointF": 63,
+ "maxHumidity": 86,
+ "minHumidity": 31,
+ "humidity": 86,
+ "pop": 0,
+ "precipMM": 0,
+ "precipIN": 0,
+ "iceaccum": null,
+ "iceaccumMM": null,
+ "iceaccumIN": null,
+ "snowCM": 0,
+ "snowIN": 0,
+ "pressureMB": 1016,
+ "pressureIN": 29.99,
+ "windDir": "N",
+ "windDirDEG": 356,
+ "windSpeedKTS": 2,
+ "windSpeedKPH": 4,
+ "windSpeedMPH": 2,
+ "windGustKTS": 19,
+ "windGustKPH": 36,
+ "windGustMPH": 22,
+ "windDirMax": "NNW",
+ "windDirMaxDEG": 343,
+ "windSpeedMaxKTS": 8,
+ "windSpeedMaxKPH": 14,
+ "windSpeedMaxMPH": 9,
+ "windDirMin": "N",
+ "windDirMinDEG": 356,
+ "windSpeedMinKTS": 2,
+ "windSpeedMinKPH": 4,
+ "windSpeedMinMPH": 2,
+ "windDir80m": "NW",
+ "windDir80mDEG": 316,
+ "windSpeed80mKTS": 5,
+ "windSpeed80mKPH": 9,
+ "windSpeed80mMPH": 6,
+ "windGust80mKTS": 20,
+ "windGust80mKPH": 36,
+ "windGust80mMPH": 23,
+ "windDirMax80m": "N",
+ "windDirMax80mDEG": 354,
+ "windSpeedMax80mKTS": 20,
+ "windSpeedMax80mKPH": 36,
+ "windSpeedMax80mMPH": 23,
+ "windDirMin80m": "NW",
+ "windDirMin80mDEG": 316,
+ "windSpeedMin80mKTS": 5,
+ "windSpeedMin80mKPH": 9,
+ "windSpeedMin80mMPH": 6,
+ "sky": 47,
+ "cloudsCoded": "SC",
+ "weather": "Partly Cloudy",
+ "weatherCoded": [],
+ "weatherPrimary": "Partly Cloudy",
+ "weatherPrimaryCoded": "::SC",
+ "icon": "pcloudy.png",
+ "visibilityKM": 24.135,
+ "visibilityMI": 15,
+ "uvi": 7,
+ "solradWM2": 4768,
+ "solradMinWM2": 0,
+ "solradMaxWM2": 726,
+ "isDay": true,
+ "maxCoverage": "",
+ "sunrise": 1665287583,
+ "sunset": 1665329491,
+ "sunriseISO": "2022-10-09T05:53:03+02:00",
+ "sunsetISO": "2022-10-09T17:31:31+02:00"
+ },
+ {
+ "timestamp": 1665378000,
+ "validTime": "2022-10-10T07:00:00+02:00",
+ "dateTimeISO": "2022-10-10T07:00:00+02:00",
+ "maxTempC": 31,
+ "maxTempF": 87,
+ "minTempC": 21,
+ "minTempF": 70,
+ "avgTempC": 26,
+ "avgTempF": 78,
+ "tempC": null,
+ "tempF": null,
+ "maxFeelslikeC": 30,
+ "maxFeelslikeF": 86,
+ "minFeelslikeC": 21,
+ "minFeelslikeF": 69,
+ "avgFeelslikeC": 25,
+ "avgFeelslikeF": 78,
+ "feelslikeC": 21,
+ "feelslikeF": 69,
+ "maxDewpointC": 16,
+ "maxDewpointF": 61,
+ "minDewpointC": 13,
+ "minDewpointF": 55,
+ "avgDewpointC": 14,
+ "avgDewpointF": 58,
+ "dewpointC": 16,
+ "dewpointF": 61,
+ "maxHumidity": 75,
+ "minHumidity": 35,
+ "humidity": 75,
+ "pop": 0,
+ "precipMM": 0,
+ "precipIN": 0,
+ "iceaccum": null,
+ "iceaccumMM": null,
+ "iceaccumIN": null,
+ "snowCM": 0,
+ "snowIN": 0,
+ "pressureMB": 1017,
+ "pressureIN": 30.03,
+ "windDir": "N",
+ "windDirDEG": 358,
+ "windSpeedKTS": 2,
+ "windSpeedKPH": 4,
+ "windSpeedMPH": 2,
+ "windGustKTS": 16,
+ "windGustKPH": 30,
+ "windGustMPH": 19,
+ "windDirMax": "N",
+ "windDirMaxDEG": 10,
+ "windSpeedMaxKTS": 8,
+ "windSpeedMaxKPH": 15,
+ "windSpeedMaxMPH": 9,
+ "windDirMin": "N",
+ "windDirMinDEG": 358,
+ "windSpeedMinKTS": 2,
+ "windSpeedMinKPH": 4,
+ "windSpeedMinMPH": 2,
+ "windDir80m": "N",
+ "windDir80mDEG": 8,
+ "windSpeed80mKTS": 7,
+ "windSpeed80mKPH": 13,
+ "windSpeed80mMPH": 8,
+ "windGust80mKTS": 19,
+ "windGust80mKPH": 36,
+ "windGust80mMPH": 22,
+ "windDirMax80m": "N",
+ "windDirMax80mDEG": 10,
+ "windSpeedMax80mKTS": 19,
+ "windSpeedMax80mKPH": 36,
+ "windSpeedMax80mMPH": 22,
+ "windDirMin80m": "E",
+ "windDirMin80mDEG": 91,
+ "windSpeedMin80mKTS": 7,
+ "windSpeedMin80mKPH": 13,
+ "windSpeedMin80mMPH": 8,
+ "sky": 64,
+ "cloudsCoded": "SC",
+ "weather": "Partly Cloudy",
+ "weatherCoded": [],
+ "weatherPrimary": "Partly Cloudy",
+ "weatherPrimaryCoded": "::SC",
+ "icon": "pcloudy.png",
+ "visibilityKM": 24.135,
+ "visibilityMI": 15,
+ "uvi": 6,
+ "solradWM2": 4494,
+ "solradMinWM2": 0,
+ "solradMaxWM2": 597,
+ "isDay": true,
+ "maxCoverage": "",
+ "sunrise": 1665374020,
+ "sunset": 1665415821,
+ "sunriseISO": "2022-10-10T05:53:40+02:00",
+ "sunsetISO": "2022-10-10T17:30:21+02:00"
+ },
+ {
+ "timestamp": 1665464400,
+ "validTime": "2022-10-11T07:00:00+02:00",
+ "dateTimeISO": "2022-10-11T07:00:00+02:00",
+ "maxTempC": 31,
+ "maxTempF": 87,
+ "minTempC": 21,
+ "minTempF": 70,
+ "avgTempC": 26,
+ "avgTempF": 78,
+ "tempC": null,
+ "tempF": null,
+ "maxFeelslikeC": 31,
+ "maxFeelslikeF": 87,
+ "minFeelslikeC": 22,
+ "minFeelslikeF": 72,
+ "avgFeelslikeC": 26,
+ "avgFeelslikeF": 79,
+ "feelslikeC": 22,
+ "feelslikeF": 72,
+ "maxDewpointC": 17,
+ "maxDewpointF": 62,
+ "minDewpointC": 11,
+ "minDewpointF": 51,
+ "avgDewpointC": 13,
+ "avgDewpointF": 55,
+ "dewpointC": 17,
+ "dewpointF": 62,
+ "maxHumidity": 71,
+ "minHumidity": 30,
+ "humidity": 71,
+ "pop": 0,
+ "precipMM": 0,
+ "precipIN": 0,
+ "iceaccum": null,
+ "iceaccumMM": null,
+ "iceaccumIN": null,
+ "snowCM": 0,
+ "snowIN": 0,
+ "pressureMB": 1015,
+ "pressureIN": 29.98,
+ "windDir": "NNE",
+ "windDirDEG": 13,
+ "windSpeedKTS": 8,
+ "windSpeedKPH": 15,
+ "windSpeedMPH": 9,
+ "windGustKTS": 15,
+ "windGustKPH": 28,
+ "windGustMPH": 17,
+ "windDirMax": "NNE",
+ "windDirMaxDEG": 28,
+ "windSpeedMaxKTS": 15,
+ "windSpeedMaxKPH": 28,
+ "windSpeedMaxMPH": 18,
+ "windDirMin": "NNE",
+ "windDirMinDEG": 14,
+ "windSpeedMinKTS": 7,
+ "windSpeedMinKPH": 14,
+ "windSpeedMinMPH": 8,
+ "windDir80m": "NNE",
+ "windDir80mDEG": 16,
+ "windSpeed80mKTS": 10,
+ "windSpeed80mKPH": 19,
+ "windSpeed80mMPH": 12,
+ "windGust80mKTS": 17,
+ "windGust80mKPH": 31,
+ "windGust80mMPH": 19,
+ "windDirMax80m": "NNE",
+ "windDirMax80mDEG": 28,
+ "windSpeedMax80mKTS": 17,
+ "windSpeedMax80mKPH": 31,
+ "windSpeedMax80mMPH": 19,
+ "windDirMin80m": "NNE",
+ "windDirMin80mDEG": 13,
+ "windSpeedMin80mKTS": 9,
+ "windSpeedMin80mKPH": 18,
+ "windSpeedMin80mMPH": 11,
+ "sky": 0,
+ "cloudsCoded": "CL",
+ "weather": "Sunny",
+ "weatherCoded": [],
+ "weatherPrimary": "Sunny",
+ "weatherPrimaryCoded": "::CL",
+ "icon": "sunny.png",
+ "visibilityKM": 24.135,
+ "visibilityMI": 15,
+ "uvi": null,
+ "solradWM2": 5450,
+ "solradMinWM2": 0,
+ "solradMaxWM2": 758,
+ "isDay": true,
+ "maxCoverage": "",
+ "sunrise": 1665460458,
+ "sunset": 1665502153,
+ "sunriseISO": "2022-10-11T05:54:18+02:00",
+ "sunsetISO": "2022-10-11T17:29:13+02:00"
+ },
+ {
+ "timestamp": 1665550800,
+ "validTime": "2022-10-12T07:00:00+02:00",
+ "dateTimeISO": "2022-10-12T07:00:00+02:00",
+ "maxTempC": 31,
+ "maxTempF": 88,
+ "minTempC": 21,
+ "minTempF": 69,
+ "avgTempC": 26,
+ "avgTempF": 79,
+ "tempC": null,
+ "tempF": null,
+ "maxFeelslikeC": 31,
+ "maxFeelslikeF": 88,
+ "minFeelslikeC": 22,
+ "minFeelslikeF": 72,
+ "avgFeelslikeC": 26,
+ "avgFeelslikeF": 80,
+ "feelslikeC": 22,
+ "feelslikeF": 72,
+ "maxDewpointC": 16,
+ "maxDewpointF": 60,
+ "minDewpointC": 11,
+ "minDewpointF": 51,
+ "avgDewpointC": 13,
+ "avgDewpointF": 55,
+ "dewpointC": 16,
+ "dewpointF": 60,
+ "maxHumidity": 68,
+ "minHumidity": 29,
+ "humidity": 68,
+ "pop": 0,
+ "precipMM": 0,
+ "precipIN": 0,
+ "iceaccum": null,
+ "iceaccumMM": null,
+ "iceaccumIN": null,
+ "snowCM": 0,
+ "snowIN": 0,
+ "pressureMB": 1014,
+ "pressureIN": 29.95,
+ "windDir": "NNE",
+ "windDirDEG": 12,
+ "windSpeedKTS": 8,
+ "windSpeedKPH": 15,
+ "windSpeedMPH": 9,
+ "windGustKTS": 15,
+ "windGustKPH": 28,
+ "windGustMPH": 17,
+ "windDirMax": "E",
+ "windDirMaxDEG": 96,
+ "windSpeedMaxKTS": 14,
+ "windSpeedMaxKPH": 26,
+ "windSpeedMaxMPH": 16,
+ "windDirMin": "NNE",
+ "windDirMinDEG": 12,
+ "windSpeedMinKTS": 7,
+ "windSpeedMinKPH": 13,
+ "windSpeedMinMPH": 8,
+ "windDir80m": "NNE",
+ "windDir80mDEG": 15,
+ "windSpeed80mKTS": 10,
+ "windSpeed80mKPH": 19,
+ "windSpeed80mMPH": 12,
+ "windGust80mKTS": 18,
+ "windGust80mKPH": 33,
+ "windGust80mMPH": 21,
+ "windDirMax80m": "E",
+ "windDirMax80mDEG": 96,
+ "windSpeedMax80mKTS": 18,
+ "windSpeedMax80mKPH": 33,
+ "windSpeedMax80mMPH": 21,
+ "windDirMin80m": "NNE",
+ "windDirMin80mDEG": 15,
+ "windSpeedMin80mKTS": 10,
+ "windSpeedMin80mKPH": 18,
+ "windSpeedMin80mMPH": 11,
+ "sky": 27,
+ "cloudsCoded": "FW",
+ "weather": "Mostly Sunny",
+ "weatherCoded": [],
+ "weatherPrimary": "Mostly Sunny",
+ "weatherPrimaryCoded": "::FW",
+ "icon": "fair.png",
+ "visibilityKM": 24.135,
+ "visibilityMI": 15,
+ "uvi": null,
+ "solradWM2": 4740,
+ "solradMinWM2": 0,
+ "solradMaxWM2": 743,
+ "isDay": true,
+ "maxCoverage": "",
+ "sunrise": 1665546895,
+ "sunset": 1665588484,
+ "sunriseISO": "2022-10-12T05:54:55+02:00",
+ "sunsetISO": "2022-10-12T17:28:04+02:00"
+ }
+ ],
+ "profile": {
+ "tz": "Africa/Cairo",
+ "elevM": 23,
+ "elevFT": 75
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/test/resources/Issue593.xml b/src/test/resources/Issue593.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0c6c038b69c70dec24e92af73727ec57a4734f31
--- /dev/null
+++ b/src/test/resources/Issue593.xml
@@ -0,0 +1,691 @@
+true
+
+
+ 31.25
+ 30.063
+
+
+ 23
+ Africa/Cairo
+ 75
+
+
+ 2022-10-06T07:00:00+02:00
+ E
+ 95
+ 21
+ 15
+ 10
+ 353
+ N
+ 2022-10-06T05:51:14+02:00
+ null
+ 9
+ null
+ 66
+ 0
+ Mostly Sunny
+ 2022-10-06T17:35:02+02:00
+ 32
+ 77
+ N
+ 89
+ 0
+ 22
+ 25
+ 25
+ Mostly Sunny
+ 41
+ 58
+ 41
+ 22
+ 14
+ 0
+ 22
+ 353
+ 16
+ 8
+ 70
+ 2022-10-06T07:00:00+02:00
+ 10
+ 778
+ 25
+ 15
+ ::FW
+ 1665028274
+ 78
+ N
+
+ fair.png
+ 21
+ 17
+ FW
+ 70
+ 29
+ 63
+ 12
+ 0
+ 0
+ NNW
+ 13
+ 22
+ 11
+ 32
+ 1015
+ 24.135
+ 1665032400
+ 90
+ null
+ 11
+ 0
+ 1
+ 343
+ 21
+ 2
+ 63
+ 1
+ 26
+ 6
+ NNW
+ 17
+ 29.97
+ 80
+ null
+ true
+ 19
+ 52
+ 5
+ 1665070502
+ 5608
+ 9
+ 25
+ 77
+ 6
+ 40
+ 342
+ null
+
+
+ 2022-10-07T07:00:00+02:00
+ NNW
+ 347
+ 19
+ 15
+ 8
+ 325
+ NW
+ 2022-10-07T05:51:50+02:00
+ null
+ 7
+ null
+ 66
+ 0
+ Mostly Sunny
+ 2022-10-07T17:33:51+02:00
+ 29
+ 77
+ NNW
+ 85
+ 0
+ 30
+ 23
+ 23
+ Mostly Sunny
+ 37
+ 54
+ 37
+ 20
+ 12
+ 0
+ 20
+ 325
+ 13
+ 6
+ 67
+ 2022-10-07T07:00:00+02:00
+ 6
+ 742
+ 24
+ 10
+ ::FW
+ 1665114710
+ 76
+ NW
+
+ fair.png
+ 19
+ 15
+ FW
+ 67
+ 30
+ 60
+ 6
+ 0
+ 0
+ WNW
+ 6
+ 10
+ 347
+ 30
+ 1014
+ 24.135
+ 1665118800
+ 86
+ null
+ 10
+ 0
+ 1
+ 316
+ 16
+ 2
+ 60
+ 1
+ 24
+ 6
+ NW
+ 15
+ 29.95
+ 76
+ null
+ true
+ 19
+ 50
+ 1
+ 1665156831
+ 5486
+ 2
+ 18
+ 77
+ 1
+ 29
+ 298
+ null
+
+
+ 2022-10-08T07:00:00+02:00
+ NW
+ 309
+ 19
+ 15
+ 8
+ 21
+ NNE
+ 2022-10-08T05:52:26+02:00
+ null
+ 7
+ null
+ 66
+ 0
+ Partly Cloudy
+ 2022-10-08T17:32:41+02:00
+ 30
+ 76
+ NW
+ 86
+ 0
+ 47
+ 19
+ 19
+ Partly Cloudy
+ 31
+ 56
+ 31
+ 17
+ 13
+ 0
+ 17
+ 21
+ 13
+ 5
+ 67
+ 2022-10-08T07:00:00+02:00
+ 5
+ 682
+ 25
+ 9
+ ::SC
+ 1665201146
+ 76
+ NNE
+
+ pcloudy.png
+ 19
+ 15
+ SC
+ 67
+ 32
+ 59
+ 5
+ 0
+ 0
+ WNW
+ 5
+ 9
+ 309
+ 30
+ 1014
+ 24.135
+ 1665205200
+ 87
+ null
+ 11
+ 0
+ 1
+ 322
+ 17
+ 2
+ 59
+ 1
+ 25
+ 7
+ NW
+ 15
+ 29.94
+ 76
+ null
+ true
+ 19
+ 52
+ 1
+ 1665243161
+ 4785
+ 2
+ 20
+ 76
+ 1
+ 32
+ 301
+ null
+
+
+ 2022-10-09T07:00:00+02:00
+ NW
+ 316
+ 20
+ 15
+ 9
+ 356
+ N
+ 2022-10-09T05:53:03+02:00
+ null
+ 8
+ null
+ 67
+ 0
+ Partly Cloudy
+ 2022-10-09T17:31:31+02:00
+ 30
+ 86
+ NW
+ 86
+ 0
+ 47
+ 23
+ 23
+ Partly Cloudy
+ 36
+ 57
+ 36
+ 20
+ 14
+ 0
+ 20
+ 356
+ 14
+ 5
+ 67
+ 2022-10-09T07:00:00+02:00
+ 6
+ 726
+ 25
+ 9
+ ::SC
+ 1665287583
+ 77
+ N
+
+ pcloudy.png
+ 20
+ 17
+ SC
+ 67
+ 31
+ 63
+ 5
+ 0
+ 0
+ NNW
+ 6
+ 9
+ 316
+ 31
+ 1016
+ 24.135
+ 1665291600
+ 87
+ null
+ 11
+ 0
+ 2
+ 354
+ 19
+ 4
+ 63
+ 2
+ 25
+ 7
+ N
+ 17
+ 29.99
+ 77
+ null
+ true
+ 19
+ 52
+ 2
+ 1665329491
+ 4768
+ 4
+ 22
+ 86
+ 2
+ 36
+ 343
+ null
+
+
+ 2022-10-10T07:00:00+02:00
+ E
+ 91
+ 21
+ 15
+ 9
+ 358
+ N
+ 2022-10-10T05:53:40+02:00
+ null
+ 8
+ null
+ 70
+ 0
+ Partly Cloudy
+ 2022-10-10T17:30:21+02:00
+ 30
+ 75
+ N
+ 86
+ 0
+ 64
+ 22
+ 22
+ Partly Cloudy
+ 36
+ 58
+ 36
+ 19
+ 14
+ 0
+ 19
+ 358
+ 15
+ 7
+ 69
+ 2022-10-10T07:00:00+02:00
+ 8
+ 597
+ 26
+ 13
+ ::SC
+ 1665374020
+ 78
+ N
+
+ pcloudy.png
+ 21
+ 16
+ SC
+ 69
+ 35
+ 61
+ 7
+ 0
+ 0
+ N
+ 8
+ 13
+ 8
+ 31
+ 1017
+ 24.135
+ 1665378000
+ 87
+ null
+ 13
+ 0
+ 2
+ 10
+ 16
+ 4
+ 61
+ 2
+ 25
+ 6
+ N
+ 16
+ 30.03
+ 78
+ null
+ true
+ 21
+ 55
+ 2
+ 1665415821
+ 4494
+ 4
+ 19
+ 75
+ 2
+ 30
+ 10
+ null
+
+
+ 2022-10-11T07:00:00+02:00
+ NNE
+ 13
+ 22
+ 15
+ 18
+ 13
+ NNE
+ 2022-10-11T05:54:18+02:00
+ null
+ 15
+ null
+ 70
+ 0
+ Sunny
+ 2022-10-11T17:29:13+02:00
+ 31
+ 71
+ NNE
+ 87
+ 0
+ 0
+ 19
+ 19
+ Sunny
+ 31
+ 55
+ 31
+ 17
+ 13
+ 0
+ 17
+ 14
+ 28
+ 9
+ 72
+ 2022-10-11T07:00:00+02:00
+ 11
+ 758
+ 26
+ 18
+ ::CL
+ 1665460458
+ 78
+ NNE
+
+ sunny.png
+ 22
+ 17
+ CL
+ 72
+ 30
+ 62
+ 10
+ 0
+ 0
+ NNE
+ 12
+ 19
+ 16
+ 31
+ 1015
+ 24.135
+ 1665464400
+ 87
+ null
+ 11
+ 0
+ 7
+ 28
+ 15
+ 14
+ 62
+ 8
+ 26
+ null
+ NNE
+ 17
+ 29.98
+ 79
+ null
+ true
+ 21
+ 51
+ 8
+ 1665502153
+ 5450
+ 15
+ 17
+ 71
+ 9
+ 28
+ 28
+ null
+
+
+ 2022-10-12T07:00:00+02:00
+ NNE
+ 15
+ 22
+ 15
+ 16
+ 12
+ NNE
+ 2022-10-12T05:54:55+02:00
+ null
+ 14
+ null
+ 69
+ 0
+ Mostly Sunny
+ 2022-10-12T17:28:04+02:00
+ 31
+ 68
+ NNE
+ 88
+ 0
+ 27
+ 21
+ 21
+ Mostly Sunny
+ 33
+ 55
+ 33
+ 18
+ 13
+ 0
+ 18
+ 12
+ 26
+ 10
+ 72
+ 2022-10-12T07:00:00+02:00
+ 11
+ 743
+ 26
+ 18
+ ::FW
+ 1665546895
+ 79
+ NNE
+
+ fair.png
+ 22
+ 16
+ FW
+ 72
+ 29
+ 60
+ 10
+ 0
+ 0
+ E
+ 12
+ 19
+ 15
+ 31
+ 1014
+ 24.135
+ 1665550800
+ 88
+ null
+ 11
+ 0
+ 7
+ 96
+ 15
+ 13
+ 60
+ 8
+ 26
+ null
+ E
+ 16
+ 29.95
+ 80
+ null
+ true
+ 21
+ 51
+ 8
+ 1665588484
+ 4740
+ 15
+ 17
+ 68
+ 9
+ 28
+ 96
+ null
+
+ day
+
+ eg
+ cairo
+ qh
+
+
+null