mirror of
https://github.com/ethauvin/JSON-java.git
synced 2025-06-17 16:00:51 -07:00
Merge remote-tracking branch 'tests/master' into upstream
This commit is contained in:
commit
1265897f4e
45 changed files with 11062 additions and 1 deletions
300
src/test/java/org/json/junit/CDLTest.java
Normal file
300
src/test/java/org/json/junit/CDLTest.java
Normal file
|
@ -0,0 +1,300 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONArray;
|
||||
import org.json.CDL;
|
||||
|
||||
/**
|
||||
* Tests for CDL.java.
|
||||
* CDL provides an application level API, but it is not used by the
|
||||
* reference app. To test it, strings will be converted to JSON-Java classes
|
||||
* and then converted back.
|
||||
*/
|
||||
public class CDLTest {
|
||||
|
||||
/**
|
||||
* String of lines where the column names are in the first row,
|
||||
* and all subsequent rows are values. All keys and values should be legal.
|
||||
*/
|
||||
String lines = new String(
|
||||
"Col 1, Col 2, \tCol 3, Col 4, Col 5, Col 6, Col 7\n" +
|
||||
"val1, val2, val3, val4, val5, val6, val7\n" +
|
||||
"1, 2, 3, 4\t, 5, 6, 7\n" +
|
||||
"true, false, true, true, false, false, false\n" +
|
||||
"0.23, 57.42, 5e27, -234.879, 2.34e5, 0.0, 9e-3\n" +
|
||||
"\"va\tl1\", \"v\bal2\", \"val3\", \"val\f4\", \"val5\", va\'l6, val7\n"
|
||||
);
|
||||
|
||||
/**
|
||||
* CDL.toJSONArray() adds all values as strings, with no filtering or
|
||||
* conversions. For testing, this means that the expected JSONObject
|
||||
* values all must be quoted in the cases where the JSONObject parsing
|
||||
* might normally convert the value into a non-string.
|
||||
*/
|
||||
String expectedLines = new String(
|
||||
"[{Col 1:val1, Col 2:val2, Col 3:val3, Col 4:val4, Col 5:val5, Col 6:val6, Col 7:val7}, "+
|
||||
"{Col 1:\"1\", Col 2:\"2\", Col 3:\"3\", Col 4:\"4\", Col 5:\"5\", Col 6:\"6\", Col 7:\"7\"}, "+
|
||||
"{Col 1:\"true\", Col 2:\"false\", Col 3:\"true\", Col 4:\"true\", Col 5:\"false\", Col 6:\"false\", Col 7:\"false\"}, "+
|
||||
"{Col 1:\"0.23\", Col 2:\"57.42\", Col 3:\"5e27\", Col 4:\"-234.879\", Col 5:\"2.34e5\", Col 6:\"0.0\", Col 7:\"9e-3\"}, "+
|
||||
"{Col 1:\"va\tl1\", Col 2:\"v\bal2\", Col 3:val3, Col 4:\"val\f4\", Col 5:val5, Col 6:va\'l6, Col 7:val7}]");
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONArray from a null string.
|
||||
* Expect a NullPointerException.
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void exceptionOnNullString() {
|
||||
String nullStr = null;
|
||||
CDL.toJSONArray(nullStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONArray from a string with unbalanced quotes
|
||||
* in column title line. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void unbalancedQuoteInName() {
|
||||
String badLine = "Col1, \"Col2\nVal1, Val2";
|
||||
try {
|
||||
CDL.toJSONArray(badLine);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Missing close quote '\"'. at 12 [character 0 line 2]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONArray from a string with unbalanced quotes
|
||||
* in value line. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void unbalancedQuoteInValue() {
|
||||
String badLine = "Col1, Col2\n\"Val1, Val2";
|
||||
try {
|
||||
CDL.toJSONArray(badLine);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Missing close quote '\"'. at 22 [character 11 line 2]",
|
||||
e.getMessage());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONArray from a string with null char
|
||||
* in column title line. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void nullInName() {
|
||||
String badLine = "C\0ol1, Col2\nVal1, Val2";
|
||||
try {
|
||||
CDL.toJSONArray(badLine);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Bad character 'o' (111). at 2 [character 3 line 1]",
|
||||
e.getMessage());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to create a JSONArray with unbalanced quotes and a properly escaped doubled quote.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void unbalancedEscapedQuote(){
|
||||
String badLine = "Col1, Col2\n\"Val1, \"\"Val2\"\"";
|
||||
try {
|
||||
CDL.toJSONArray(badLine);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Missing close quote '\"'. at 26 [character 15 line 2]",
|
||||
e.getMessage());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that there is no error for a single escaped quote within a properly embedded quote.
|
||||
*/
|
||||
@Test
|
||||
public void singleEscapedQuote(){
|
||||
String singleEscape = "Col1, Col2\nVal1, \"\"\"Val2\"";
|
||||
JSONArray jsonArray = CDL.toJSONArray(singleEscape);
|
||||
|
||||
String cdlStr = CDL.toString(jsonArray);
|
||||
assertTrue(cdlStr.contains("Col1"));
|
||||
assertTrue(cdlStr.contains("Col2"));
|
||||
assertTrue(cdlStr.contains("Val1"));
|
||||
assertTrue(cdlStr.contains("\"Val2"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that there is no error for a single escaped quote within a properly
|
||||
* embedded quote when not the last value.
|
||||
*/
|
||||
@Test
|
||||
public void singleEscapedQuoteMiddleString(){
|
||||
String singleEscape = "Col1, Col2\nVal1, \"\"\"Val2\"\nVal 3,Val 4";
|
||||
JSONArray jsonArray = CDL.toJSONArray(singleEscape);
|
||||
|
||||
String cdlStr = CDL.toString(jsonArray);
|
||||
assertTrue(cdlStr.contains("Col1"));
|
||||
assertTrue(cdlStr.contains("Col2"));
|
||||
assertTrue(cdlStr.contains("Val1"));
|
||||
assertTrue(cdlStr.contains("\"Val2"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to create a JSONArray with an escape quote and no enclosing quotes.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void badEscapedQuote(){
|
||||
String badLine = "Col1, Col2\nVal1, \"\"Val2";
|
||||
|
||||
try {
|
||||
CDL.toJSONArray(badLine);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
System.out.println("Message" + e.getMessage());
|
||||
assertEquals("Expecting an exception message",
|
||||
"Bad character 'V' (86). at 20 [character 9 line 2]",
|
||||
e.getMessage());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* call toString with a null array
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void nullJSONArrayToString() {
|
||||
CDL.toString((JSONArray)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSONArray from an empty string
|
||||
*/
|
||||
@Test
|
||||
public void emptyString() {
|
||||
String emptyStr = "";
|
||||
JSONArray jsonArray = CDL.toJSONArray(emptyStr);
|
||||
assertTrue("CDL should return null when the input string is empty",
|
||||
jsonArray == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSONArray with only 1 row
|
||||
*/
|
||||
@Test
|
||||
public void onlyColumnNames() {
|
||||
String columnNameStr = "col1, col2, col3";
|
||||
JSONArray jsonArray = CDL.toJSONArray(columnNameStr);
|
||||
assertNull("CDL should return null when only 1 row is given",
|
||||
jsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSONArray from string containing only whitespace and commas
|
||||
*/
|
||||
@Test
|
||||
public void emptyLinesToJSONArray() {
|
||||
String str = " , , , \n , , , ";
|
||||
JSONArray jsonArray = CDL.toJSONArray(str);
|
||||
assertNull("JSONArray should be null for no content",
|
||||
jsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* call toString with a null array
|
||||
*/
|
||||
@Test
|
||||
public void emptyJSONArrayToString() {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
String str = CDL.toString(jsonArray);
|
||||
assertNull("CDL should return null for toString(null)",
|
||||
str);
|
||||
}
|
||||
|
||||
/**
|
||||
* call toString with a null arrays for names and values
|
||||
*/
|
||||
@Test
|
||||
public void nullJSONArraysToString() {
|
||||
String str = CDL.toString(null, null);
|
||||
assertNull("CDL should return null for toString(null)",
|
||||
str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a JSONArray that was not built by CDL, some chars may be
|
||||
* found that would otherwise be filtered out by CDL.
|
||||
*/
|
||||
@Test
|
||||
public void checkSpecialChars() {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonArray.put(jsonObject);
|
||||
// \r will be filtered from name
|
||||
jsonObject.put("Col \r1", "V1");
|
||||
// \r will be filtered from value
|
||||
jsonObject.put("Col 2", "V2\r");
|
||||
assertTrue("expected length should be 1",jsonArray.length() == 1);
|
||||
String cdlStr = CDL.toString(jsonArray);
|
||||
jsonObject = jsonArray.getJSONObject(0);
|
||||
assertTrue(cdlStr.contains("\"Col 1\""));
|
||||
assertTrue(cdlStr.contains("Col 2"));
|
||||
assertTrue(cdlStr.contains("V1"));
|
||||
assertTrue(cdlStr.contains("\"V2\""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSONArray from a string of lines
|
||||
*/
|
||||
@Test
|
||||
public void textToJSONArray() {
|
||||
JSONArray jsonArray = CDL.toJSONArray(this.lines);
|
||||
JSONArray expectedJsonArray = new JSONArray(this.expectedLines);
|
||||
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSONArray from a JSONArray of titles and a
|
||||
* string of value lines
|
||||
*/
|
||||
@Test
|
||||
public void jsonArrayToJSONArray() {
|
||||
String nameArrayStr = "[Col1, Col2]";
|
||||
String values = "V1, V2";
|
||||
JSONArray nameJSONArray = new JSONArray(nameArrayStr);
|
||||
JSONArray jsonArray = CDL.toJSONArray(nameJSONArray, values);
|
||||
JSONArray expectedJsonArray = new JSONArray("[{Col1:V1,Col2:V2}]");
|
||||
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSONArray from a string of lines,
|
||||
* then convert to string and then back to JSONArray
|
||||
*/
|
||||
@Test
|
||||
public void textToJSONArrayAndBackToString() {
|
||||
JSONArray jsonArray = CDL.toJSONArray(this.lines);
|
||||
String jsonStr = CDL.toString(jsonArray);
|
||||
JSONArray finalJsonArray = CDL.toJSONArray(jsonStr);
|
||||
JSONArray expectedJsonArray = new JSONArray(this.expectedLines);
|
||||
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
|
||||
}
|
186
src/test/java/org/json/junit/CookieListTest.java
Normal file
186
src/test/java/org/json/junit/CookieListTest.java
Normal file
|
@ -0,0 +1,186 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.json.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.jayway.jsonpath.*;
|
||||
|
||||
/**
|
||||
* HTTP cookie specification RFC6265: http://tools.ietf.org/html/rfc6265
|
||||
* <p>
|
||||
* A cookie list is a JSONObject whose members are presumed to be cookie
|
||||
* name/value pairs. Entries are unescaped while being added, and escaped in
|
||||
* the toString() output.
|
||||
* Unescaping means to convert %hh hex strings to the ascii equivalent
|
||||
* and converting '+' to ' '.
|
||||
* Escaping converts '+', '%', '=', ';' and ascii control chars to %hh hex strings.
|
||||
* <p>
|
||||
* CookieList should not be considered as just a list of Cookie objects:<br>
|
||||
* - CookieList stores a cookie name/value pair as a single entry; Cookie stores
|
||||
* it as 2 entries (key="name" and key="value").<br>
|
||||
* - CookieList requires multiple name/value pairs as input; Cookie allows the
|
||||
* 'secure' name with no associated value<br>
|
||||
* - CookieList has no special handling for attribute name/value pairs.<br>
|
||||
*/
|
||||
public class CookieListTest {
|
||||
|
||||
/**
|
||||
* Attempts to create a CookieList from a null string.
|
||||
* Expects a NullPointerException.
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void nullCookieListException() {
|
||||
String cookieStr = null;
|
||||
CookieList.toJSONObject(cookieStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a CookieList from a malformed string.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void malFormedCookieListException() {
|
||||
String cookieStr = "thisCookieHasNoEqualsChar";
|
||||
try {
|
||||
CookieList.toJSONObject(cookieStr);
|
||||
fail("should throw an exception");
|
||||
} catch (JSONException e) {
|
||||
/**
|
||||
* Not sure of the missing char, but full string compare fails
|
||||
*/
|
||||
assertEquals("Expecting an exception message",
|
||||
"Expected '=' and instead saw '' at 25 [character 26 line 1]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CookieList from an empty string.
|
||||
*/
|
||||
@Test
|
||||
public void emptyStringCookieList() {
|
||||
String cookieStr = "";
|
||||
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
|
||||
assertTrue(jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* CookieList with the simplest cookie - a name/value pair with no delimiter.
|
||||
*/
|
||||
@Test
|
||||
public void simpleCookieList() {
|
||||
String cookieStr = "SID=31d4d96e407aad42";
|
||||
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("Expected 1 top level item", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
|
||||
assertTrue("expected 31d4d96e407aad42", "31d4d96e407aad42".equals(jsonObject.query("/SID")));
|
||||
}
|
||||
|
||||
/**
|
||||
* CookieList with a single a cookie which has a name/value pair and delimiter.
|
||||
*/
|
||||
@Test
|
||||
public void simpleCookieListWithDelimiter() {
|
||||
String cookieStr = "SID=31d4d96e407aad42;";
|
||||
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("Expected 1 top level item", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
|
||||
assertTrue("expected 31d4d96e407aad42", "31d4d96e407aad42".equals(jsonObject.query("/SID")));
|
||||
}
|
||||
|
||||
/**
|
||||
* CookieList with multiple cookies consisting of name/value pairs
|
||||
* with delimiters.
|
||||
*/
|
||||
@Test
|
||||
public void multiPartCookieList() {
|
||||
String cookieStr =
|
||||
"name1=myCookieValue1; "+
|
||||
" name2=myCookieValue2;"+
|
||||
"name3=myCookieValue3;"+
|
||||
" name4=myCookieValue4; "+
|
||||
"name5=myCookieValue5;"+
|
||||
" name6=myCookieValue6;";
|
||||
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("Expected 6 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 6);
|
||||
assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
|
||||
assertTrue("expected myCookieValue2", "myCookieValue2".equals(jsonObject.query("/name2")));
|
||||
assertTrue("expected myCookieValue3", "myCookieValue3".equals(jsonObject.query("/name3")));
|
||||
assertTrue("expected myCookieValue4", "myCookieValue4".equals(jsonObject.query("/name4")));
|
||||
assertTrue("expected myCookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
|
||||
assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
|
||||
}
|
||||
|
||||
/**
|
||||
* CookieList from a JSONObject with valid key and null value
|
||||
*/
|
||||
@Test
|
||||
public void convertCookieListWithNullValueToString() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("key", JSONObject.NULL);
|
||||
String cookieToStr = CookieList.toString(jsonObject);
|
||||
assertTrue("toString() should be empty", "".equals(cookieToStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* CookieList with multiple entries converted to a JSON document.
|
||||
*/
|
||||
@Test
|
||||
public void convertCookieListToString() {
|
||||
String cookieStr =
|
||||
"name1=myCookieValue1; "+
|
||||
" name2=myCookieValue2;"+
|
||||
"name3=myCookieValue3;"+
|
||||
" name4=myCookieValue4; "+
|
||||
"name5=myCookieValue5;"+
|
||||
" name6=myCookieValue6;";
|
||||
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
|
||||
// exercise CookieList.toString()
|
||||
String cookieListString = CookieList.toString(jsonObject);
|
||||
// have to convert it back for validation
|
||||
jsonObject = CookieList.toJSONObject(cookieListString);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("Expected 6 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 6);
|
||||
assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
|
||||
assertTrue("expected myCookieValue2", "myCookieValue2".equals(jsonObject.query("/name2")));
|
||||
assertTrue("expected myCookieValue3", "myCookieValue3".equals(jsonObject.query("/name3")));
|
||||
assertTrue("expected myCookieValue4", "myCookieValue4".equals(jsonObject.query("/name4")));
|
||||
assertTrue("expected myCookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
|
||||
assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
|
||||
}
|
||||
|
||||
/**
|
||||
* CookieList with multiple entries and some '+' chars and URL-encoded
|
||||
* values converted to a JSON document.
|
||||
*/
|
||||
@Test
|
||||
public void convertEncodedCookieListToString() {
|
||||
String cookieStr =
|
||||
"name1=myCookieValue1; "+
|
||||
" name2=my+Cookie+Value+2;"+
|
||||
"name3=my%2BCookie%26Value%3B3%3D;"+
|
||||
" name4=my%25CookieValue4; "+
|
||||
"name5=myCookieValue5;"+
|
||||
" name6=myCookieValue6;";
|
||||
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("Expected 6 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 6);
|
||||
assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
|
||||
assertTrue("expected my Cookie Value 2", "my Cookie Value 2".equals(jsonObject.query("/name2")));
|
||||
assertTrue("expected my+Cookie&Value;3=", "my+Cookie&Value;3=".equals(jsonObject.query("/name3")));
|
||||
assertTrue("expected my%CookieValue4", "my%CookieValue4".equals(jsonObject.query("/name4")));
|
||||
assertTrue("expected my%CookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
|
||||
assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
|
||||
}
|
||||
}
|
226
src/test/java/org/json/junit/CookieTest.java
Normal file
226
src/test/java/org/json/junit/CookieTest.java
Normal file
|
@ -0,0 +1,226 @@
|
|||
package org.json.junit;
|
||||
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.json.*;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* HTTP cookie specification: RFC6265
|
||||
* <p>
|
||||
* At its most basic, a cookie is a name=value pair. The value may be subdivided
|
||||
* into other cookies, but that is not tested here. The cookie may also include
|
||||
* certain named attributes, delimited by semicolons.
|
||||
* <p>
|
||||
* The Cookie.toString() method emits certain attributes if present: expires,
|
||||
* domain, path, secure. All but secure are name-value pairs. Other attributes
|
||||
* are not included in the toString() output.
|
||||
* <p>
|
||||
* A JSON-Java encoded cookie escapes '+', '%', '=', ';' with %hh values.
|
||||
*/
|
||||
public class CookieTest {
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONObject from a null string.
|
||||
* Expects a NullPointerException.
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void nullCookieException() {
|
||||
String cookieStr = null;
|
||||
Cookie.toJSONObject(cookieStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONObject from a cookie string with
|
||||
* no '=' char.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void malFormedNameValueException() {
|
||||
String cookieStr = "thisCookieHasNoEqualsChar";
|
||||
try {
|
||||
Cookie.toJSONObject(cookieStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Expected '=' and instead saw '' at 25 [character 26 line 1]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONObject from a cookie string
|
||||
* with embedded ';' char.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void malFormedAttributeException() {
|
||||
String cookieStr = "this=Cookie;myAttribute";
|
||||
try {
|
||||
Cookie.toJSONObject(cookieStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Missing '=' in cookie parameter. at 23 [character 24 line 1]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a JSONObject from an empty cookie string.<br>
|
||||
* Note: Cookie throws an exception, but CookieList does not.<br>
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void emptyStringCookieException() {
|
||||
String cookieStr = "";
|
||||
try {
|
||||
Cookie.toJSONObject(cookieStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Expected '=' and instead saw '' at 0 [character 1 line 1]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie from a simple name/value pair with no delimiter
|
||||
*/
|
||||
@Test
|
||||
public void simpleCookie() {
|
||||
String cookieStr = "SID=31d4d96e407aad42";
|
||||
String expectedCookieStr = "{\"name\":\"SID\",\"value\":\"31d4d96e407aad42\"}";
|
||||
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a cookie with all of the supported attributes in a
|
||||
* JSONObject. The secure attribute, which has no value, is treated
|
||||
* as a boolean.
|
||||
*/
|
||||
@Test
|
||||
public void multiPartCookie() {
|
||||
String cookieStr =
|
||||
"PH=deleted; "+
|
||||
" expires=Wed, 19-Mar-2014 17:53:53 GMT;"+
|
||||
"path=/; "+
|
||||
" domain=.yahoo.com;"+
|
||||
"secure";
|
||||
String expectedCookieStr =
|
||||
"{"+
|
||||
"\"name\":\"PH\","+
|
||||
"\"value\":\"deleted\","+
|
||||
"\"path\":\"/\","+
|
||||
"\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
|
||||
"\"domain\":\".yahoo.com\","+
|
||||
"\"secure\":true"+
|
||||
"}";
|
||||
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie.toString() will omit the non-standard "thiswont=beIncluded"
|
||||
* attribute, but the attribute is still stored in the JSONObject.
|
||||
* This test confirms both behaviors.
|
||||
*/
|
||||
@Test
|
||||
public void convertCookieToString() {
|
||||
String cookieStr =
|
||||
"PH=deleted; "+
|
||||
" expires=Wed, 19-Mar-2014 17:53:53 GMT;"+
|
||||
"path=/; "+
|
||||
" domain=.yahoo.com;"+
|
||||
"thisWont=beIncluded;"+
|
||||
"secure";
|
||||
String expectedCookieStr =
|
||||
"{\"path\":\"/\","+
|
||||
"\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
|
||||
"\"domain\":\".yahoo.com\","+
|
||||
"\"name\":\"PH\","+
|
||||
"\"secure\":true,"+
|
||||
"\"value\":\"deleted\"}";
|
||||
// Add the nonstandard attribute to the expected cookie string
|
||||
String expectedDirectCompareCookieStr =
|
||||
expectedCookieStr.replaceAll("\\{", "\\{\"thisWont\":\"beIncluded\",");
|
||||
// convert all strings into JSONObjects
|
||||
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
|
||||
JSONObject expectedDirectCompareJsonObject =
|
||||
new JSONObject(expectedDirectCompareCookieStr);
|
||||
// emit the string
|
||||
String cookieToStr = Cookie.toString(jsonObject);
|
||||
// create a final JSONObject from the string
|
||||
JSONObject finalJsonObject = Cookie.toJSONObject(cookieToStr);
|
||||
// JSONObject should contain the nonstandard string
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedDirectCompareJsonObject);
|
||||
// JSONObject -> string -> JSONObject should not contain the nonstandard string
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* A string may be URL-encoded when converting to JSONObject.
|
||||
* If found, '+' is converted to ' ', and %hh hex strings are converted
|
||||
* to their ascii char equivalents. This test confirms the decoding
|
||||
* behavior.
|
||||
*/
|
||||
@Test
|
||||
public void convertEncodedCookieToString() {
|
||||
String cookieStr =
|
||||
"PH=deleted; "+
|
||||
" expires=Wed,+19-Mar-2014+17:53:53+GMT;"+
|
||||
"path=/%2Bthis/is%26/a/spec%3Bsegment%3D; "+
|
||||
" domain=.yahoo.com;"+
|
||||
"secure";
|
||||
String expectedCookieStr =
|
||||
"{\"path\":\"/+this/is&/a/spec;segment=\","+
|
||||
"\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
|
||||
"\"domain\":\".yahoo.com\","+
|
||||
"\"name\":\"PH\","+
|
||||
"\"secure\":true,"+
|
||||
"\"value\":\"deleted\"}";
|
||||
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
|
||||
String cookieToStr = Cookie.toString(jsonObject);
|
||||
JSONObject finalJsonObject = Cookie.toJSONObject(cookieToStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* A public API method performs a URL encoding for selected chars
|
||||
* in a string. Control chars, '+', '%', '=', ';' are all encoded
|
||||
* as %hh hex strings. The string is also trimmed.
|
||||
* This test confirms that behavior.
|
||||
*/
|
||||
@Test
|
||||
public void escapeString() {
|
||||
String str = " +%\r\n\t\b%=;;; ";
|
||||
String expectedStr = "%2b%25%0d%0a%09%08%25%3d%3b%3b%3b";
|
||||
String actualStr = Cookie.escape(str);
|
||||
assertTrue("expect escape() to encode correctly. Actual: " +actualStr+
|
||||
" expected: " +expectedStr, expectedStr.equals(actualStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* A public API method performs URL decoding for strings.
|
||||
* '+' is converted to space and %hh hex strings are converted to
|
||||
* their ascii equivalent values. The string is not trimmed.
|
||||
* This test confirms that behavior.
|
||||
*/
|
||||
@Test
|
||||
public void unescapeString() {
|
||||
String str = " +%2b%25%0d%0a%09%08%25%3d%3b%3b%3b+ ";
|
||||
String expectedStr = " +%\r\n\t\b%=;;; ";
|
||||
String actualStr = Cookie.unescape(str);
|
||||
assertTrue("expect unescape() to decode correctly. Actual: " +actualStr+
|
||||
" expected: " +expectedStr, expectedStr.equals(actualStr));
|
||||
}
|
||||
}
|
429
src/test/java/org/json/junit/EnumTest.java
Normal file
429
src/test/java/org/json/junit/EnumTest.java
Normal file
|
@ -0,0 +1,429 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.json.junit.data.MyEnum;
|
||||
import org.json.junit.data.MyEnumClass;
|
||||
import org.json.junit.data.MyEnumField;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.jayway.jsonpath.Configuration;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
|
||||
/**
|
||||
* Enums are not explicitly supported in JSON-Java. But because enums act like
|
||||
* classes, all required behavior is already be present in some form.
|
||||
* These tests explore how enum serialization works with JSON-Java.
|
||||
*/
|
||||
public class EnumTest {
|
||||
|
||||
/**
|
||||
* To serialize an enum by its getters, use the JSONObject Object constructor.
|
||||
* The JSONObject ctor handles enum like any other bean. A JSONobject
|
||||
* is created whose entries are the getter name/value pairs.
|
||||
*/
|
||||
@Test
|
||||
public void jsonObjectFromEnum() {
|
||||
// If there are no getters then the object is empty.
|
||||
MyEnum myEnum = MyEnum.VAL2;
|
||||
JSONObject jsonObject = new JSONObject(myEnum);
|
||||
assertTrue("simple enum has no getters", jsonObject.isEmpty());
|
||||
|
||||
// enum with a getters should create a non-empty object
|
||||
MyEnumField myEnumField = MyEnumField.VAL2;
|
||||
jsonObject = new JSONObject(myEnumField);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider()
|
||||
.parse(jsonObject.toString());
|
||||
assertTrue("expecting 2 items in top level object", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expecting val 2", "val 2".equals(jsonObject.query("/value")));
|
||||
assertTrue("expecting 2", Integer.valueOf(2).equals(jsonObject.query("/intVal")));
|
||||
|
||||
/**
|
||||
* class which contains enum instances. Each enum should be stored
|
||||
* in its own JSONObject
|
||||
*/
|
||||
MyEnumClass myEnumClass = new MyEnumClass();
|
||||
myEnumClass.setMyEnum(MyEnum.VAL1);
|
||||
myEnumClass.setMyEnumField(MyEnumField.VAL3);
|
||||
jsonObject = new JSONObject(myEnumClass);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected 2 myEnumField items", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
|
||||
assertTrue("expected 0 myEnum items", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
|
||||
|
||||
assertTrue("expecting MyEnumField.VAL3", MyEnumField.VAL3.equals(jsonObject.query("/myEnumField")));
|
||||
assertTrue("expecting MyEnum.VAL1", MyEnum.VAL1.equals(jsonObject.query("/myEnum")));
|
||||
}
|
||||
|
||||
/**
|
||||
* To serialize an enum by its set of allowed values, use getNames()
|
||||
* and the the JSONObject Object with names constructor.
|
||||
*/
|
||||
@Test
|
||||
public void jsonObjectFromEnumWithNames() {
|
||||
String [] names;
|
||||
JSONObject jsonObject;
|
||||
|
||||
MyEnum myEnum = MyEnum.VAL1;
|
||||
names = JSONObject.getNames(myEnum);
|
||||
// The values will be MyEnum fields
|
||||
jsonObject = new JSONObject(myEnum, names);
|
||||
|
||||
// validate JSON object
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
|
||||
assertTrue("expected VAL1", MyEnum.VAL1.equals(jsonObject.query("/VAL1")));
|
||||
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/VAL2")));
|
||||
assertTrue("expected VAL3", MyEnum.VAL3.equals(jsonObject.query("/VAL3")));
|
||||
|
||||
MyEnumField myEnumField = MyEnumField.VAL3;
|
||||
names = JSONObject.getNames(myEnumField);
|
||||
// The values will be MyEnmField fields
|
||||
jsonObject = new JSONObject(myEnumField, names);
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
|
||||
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/VAL1")));
|
||||
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/VAL2")));
|
||||
assertTrue("expected VAL3", MyEnumField.VAL3.equals(jsonObject.query("/VAL3")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that enums are handled consistently between JSONArray and JSONObject
|
||||
*/
|
||||
@Test
|
||||
public void verifyEnumConsistency(){
|
||||
JSONObject jo = new JSONObject();
|
||||
|
||||
jo.put("value", MyEnumField.VAL2);
|
||||
String expected="{\"value\":\"VAL2\"}";
|
||||
String actual = jo.toString();
|
||||
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
|
||||
|
||||
jo.accumulate("value", MyEnumField.VAL1);
|
||||
expected="{\"value\":[\"VAL2\",\"VAL1\"]}";
|
||||
actual = jo.toString();
|
||||
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
|
||||
|
||||
jo.remove("value");
|
||||
jo.append("value", MyEnumField.VAL1);
|
||||
expected="{\"value\":[\"VAL1\"]}";
|
||||
actual = jo.toString();
|
||||
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
|
||||
|
||||
jo.put("value", EnumSet.of(MyEnumField.VAL2));
|
||||
expected="{\"value\":[\"VAL2\"]}";
|
||||
actual = jo.toString();
|
||||
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
|
||||
|
||||
JSONArray ja = new JSONArray();
|
||||
ja.put(MyEnumField.VAL2);
|
||||
jo.put("value", ja);
|
||||
actual = jo.toString();
|
||||
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
|
||||
|
||||
jo.put("value", new MyEnumField[]{MyEnumField.VAL2});
|
||||
actual = jo.toString();
|
||||
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* To serialize by assigned value, use the put() methods. The value
|
||||
* will be stored as a enum type.
|
||||
*/
|
||||
@Test
|
||||
public void enumPut() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
MyEnum myEnum = MyEnum.VAL2;
|
||||
jsonObject.put("myEnum", myEnum);
|
||||
MyEnumField myEnumField = MyEnumField.VAL1;
|
||||
jsonObject.putOnce("myEnumField", myEnumField);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 2 top level objects", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/myEnum")));
|
||||
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/myEnumField")));
|
||||
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.put(myEnum);
|
||||
jsonArray.put(1, myEnumField);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
|
||||
assertTrue("expected 2 top level objects", ((List<?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonArray.query("/0")));
|
||||
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonArray.query("/1")));
|
||||
|
||||
/**
|
||||
* Leaving these tests because they exercise get, opt, and remove
|
||||
*/
|
||||
assertTrue("expecting myEnum value", MyEnum.VAL2.equals(jsonArray.get(0)));
|
||||
assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.opt(1)));
|
||||
assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.remove(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* The default action of valueToString() is to call object.toString().
|
||||
* For enums, this means the assigned value will be returned as a string.
|
||||
*/
|
||||
@Test
|
||||
public void enumValueToString() {
|
||||
String expectedStr1 = "\"VAL1\"";
|
||||
String expectedStr2 = "\"VAL1\"";
|
||||
MyEnum myEnum = MyEnum.VAL1;
|
||||
MyEnumField myEnumField = MyEnumField.VAL1;
|
||||
MyEnumClass myEnumClass = new MyEnumClass();
|
||||
|
||||
String str1 = JSONObject.valueToString(myEnum);
|
||||
assertTrue("actual myEnum: "+str1+" expected: "+expectedStr1,
|
||||
str1.equals(expectedStr1));
|
||||
String str2 = JSONObject.valueToString(myEnumField);
|
||||
assertTrue("actual myEnumField: "+str2+" expected: "+expectedStr2,
|
||||
str2.equals(expectedStr2));
|
||||
|
||||
/**
|
||||
* However, an enum within another class will not be rendered
|
||||
* unless that class overrides default toString()
|
||||
*/
|
||||
String expectedStr3 = "\"org.json.junit.data.MyEnumClass@";
|
||||
myEnumClass.setMyEnum(MyEnum.VAL1);
|
||||
myEnumClass.setMyEnumField(MyEnumField.VAL1);
|
||||
String str3 = JSONObject.valueToString(myEnumClass);
|
||||
assertTrue("actual myEnumClass: "+str3+" expected: "+expectedStr3,
|
||||
str3.startsWith(expectedStr3));
|
||||
}
|
||||
|
||||
/**
|
||||
* In whatever form the enum was added to the JSONObject or JSONArray,
|
||||
* json[Object|Array].toString should serialize it in a reasonable way.
|
||||
*/
|
||||
@Test
|
||||
public void enumToString() {
|
||||
MyEnum myEnum = MyEnum.VAL2;
|
||||
JSONObject jsonObject = new JSONObject(myEnum);
|
||||
String expectedStr = "{}";
|
||||
assertTrue("myEnum toString() should be empty", expectedStr.equals(jsonObject.toString()));
|
||||
|
||||
MyEnumField myEnumField = MyEnumField.VAL2;
|
||||
jsonObject = new JSONObject(myEnumField);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected val 2", "val 2".equals(jsonObject.query("/value")));
|
||||
assertTrue("expected 2", Integer.valueOf(2).equals(jsonObject.query("/intVal")));
|
||||
|
||||
MyEnumClass myEnumClass = new MyEnumClass();
|
||||
myEnumClass.setMyEnum(MyEnum.VAL1);
|
||||
myEnumClass.setMyEnumField(MyEnumField.VAL3);
|
||||
jsonObject = new JSONObject(myEnumClass);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected VAL3", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
|
||||
assertTrue("expected VAL1", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
|
||||
|
||||
String [] names = JSONObject.getNames(myEnum);
|
||||
jsonObject = new JSONObject(myEnum, names);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
|
||||
assertTrue("expected VAL1", MyEnum.VAL1.equals(jsonObject.query("/VAL1")));
|
||||
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/VAL2")));
|
||||
assertTrue("expected VAL3", MyEnum.VAL3.equals(jsonObject.query("/VAL3")));
|
||||
|
||||
names = JSONObject.getNames(myEnumField);
|
||||
jsonObject = new JSONObject(myEnumField, names);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
|
||||
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/VAL1")));
|
||||
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/VAL2")));
|
||||
assertTrue("expected VAL3", MyEnumField.VAL3.equals(jsonObject.query("/VAL3")));
|
||||
|
||||
expectedStr = "{\"myEnum\":\"VAL2\", \"myEnumField\":\"VAL2\"}";
|
||||
jsonObject = new JSONObject();
|
||||
jsonObject.putOpt("myEnum", myEnum);
|
||||
jsonObject.putOnce("myEnumField", myEnumField);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/myEnum")));
|
||||
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/myEnumField")));
|
||||
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.put(myEnum);
|
||||
jsonArray.put(1, myEnumField);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
|
||||
assertTrue("expected 2 top level items", ((List<?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonArray.query("/0")));
|
||||
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonArray.query("/1")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap should handle enums exactly as a value type like Integer, Boolean, or String.
|
||||
*/
|
||||
@Test
|
||||
public void wrap() {
|
||||
assertTrue("simple enum has no getters", JSONObject.wrap(MyEnum.VAL2) instanceof MyEnum);
|
||||
|
||||
MyEnumField myEnumField = MyEnumField.VAL2;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("enum",myEnumField);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 1 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
|
||||
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/enum")));
|
||||
|
||||
MyEnumClass myEnumClass = new MyEnumClass();
|
||||
myEnumClass.setMyEnum(MyEnum.VAL1);
|
||||
myEnumClass.setMyEnumField(MyEnumField.VAL3);
|
||||
jsonObject = (JSONObject)JSONObject.wrap(myEnumClass);
|
||||
|
||||
// validate JSON content
|
||||
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
|
||||
assertTrue("expected VAL3", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
|
||||
assertTrue("expected VAL1", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
|
||||
|
||||
assertTrue("expecting MyEnumField.VAL3", MyEnumField.VAL3.equals(jsonObject.query("/myEnumField")));
|
||||
assertTrue("expecting MyEnum.VAL1", MyEnum.VAL1.equals(jsonObject.query("/myEnum")));
|
||||
}
|
||||
|
||||
/**
|
||||
* It was determined that some API methods should be added to
|
||||
* support enums:<br>
|
||||
* JSONObject.getEnum(class, key)<br>
|
||||
* JSONObject.optEnum(class, key)<br>
|
||||
* JSONObject.optEnum(class, key, default)<br>
|
||||
* JSONArray.getEnum(class, index)<br>
|
||||
* JSONArray.optEnum(class, index)<br>
|
||||
* JSONArray.optEnum(class, index, default)<br>
|
||||
* <p>
|
||||
* Exercise these enum API methods on JSONObject and JSONArray
|
||||
*/
|
||||
@Test
|
||||
public void enumAPI() {
|
||||
MyEnumClass myEnumClass = new MyEnumClass();
|
||||
myEnumClass.setMyEnum(MyEnum.VAL1);
|
||||
MyEnumField myEnumField = MyEnumField.VAL2;
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("strKey", "value");
|
||||
jsonObject.put("strKey2", "VAL1");
|
||||
jsonObject.put("enumKey", myEnumField);
|
||||
jsonObject.put("enumClassKey", myEnumClass);
|
||||
|
||||
// get a plain old enum
|
||||
MyEnumField actualEnum = jsonObject.getEnum(MyEnumField.class, "enumKey");
|
||||
assertTrue("get myEnumField", actualEnum == MyEnumField.VAL2);
|
||||
|
||||
// try to get the wrong value
|
||||
try {
|
||||
actualEnum = jsonObject.getEnum(MyEnumField.class, "strKey");
|
||||
assertTrue("should throw an exception for wrong key", false);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
// get a class that contains an enum
|
||||
MyEnumClass actualEnumClass = (MyEnumClass)jsonObject.get("enumClassKey");
|
||||
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
|
||||
|
||||
// opt a plain old enum
|
||||
actualEnum = jsonObject.optEnum(MyEnumField.class, "enumKey");
|
||||
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
|
||||
|
||||
// opt the wrong value
|
||||
actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey");
|
||||
assertTrue("opt null", actualEnum == null);
|
||||
|
||||
// opt a class that contains an enum
|
||||
actualEnumClass = (MyEnumClass)jsonObject.opt("enumClassKey");
|
||||
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
|
||||
|
||||
// opt with default a plain old enum
|
||||
actualEnum = jsonObject.optEnum(MyEnumField.class, "enumKey", null);
|
||||
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
|
||||
|
||||
// opt with default the wrong value
|
||||
actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey", null);
|
||||
assertNull("opt null", actualEnum);
|
||||
|
||||
// opt with default the string value
|
||||
actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey2", null);
|
||||
assertEquals(MyEnumField.VAL1, actualEnum);
|
||||
|
||||
// opt with default an index that does not exist
|
||||
actualEnum = jsonObject.optEnum(MyEnumField.class, "noKey", null);
|
||||
assertNull("opt null", actualEnum);
|
||||
|
||||
assertNull("Expected Null when the enum class is null",
|
||||
jsonObject.optEnum(null, "enumKey"));
|
||||
|
||||
/**
|
||||
* Exercise the proposed enum API methods on JSONArray
|
||||
*/
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.put("value");
|
||||
jsonArray.put(myEnumField);
|
||||
jsonArray.put(myEnumClass);
|
||||
|
||||
// get a plain old enum
|
||||
actualEnum = jsonArray.getEnum(MyEnumField.class, 1);
|
||||
assertTrue("get myEnumField", actualEnum == MyEnumField.VAL2);
|
||||
|
||||
// try to get the wrong value
|
||||
try {
|
||||
actualEnum = jsonArray.getEnum(MyEnumField.class, 0);
|
||||
assertTrue("should throw an exception for wrong index", false);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
// get a class that contains an enum
|
||||
actualEnumClass = (MyEnumClass)jsonArray.get(2);
|
||||
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
|
||||
|
||||
// opt a plain old enum
|
||||
actualEnum = jsonArray.optEnum(MyEnumField.class, 1);
|
||||
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
|
||||
|
||||
// opt the wrong value
|
||||
actualEnum = jsonArray.optEnum(MyEnumField.class, 0);
|
||||
assertTrue("opt null", actualEnum == null);
|
||||
|
||||
// opt a class that contains an enum
|
||||
actualEnumClass = (MyEnumClass)jsonArray.opt(2);
|
||||
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
|
||||
|
||||
// opt with default a plain old enum
|
||||
actualEnum = jsonArray.optEnum(MyEnumField.class, 1, null);
|
||||
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
|
||||
|
||||
// opt with default the wrong value
|
||||
actualEnum = jsonArray.optEnum(MyEnumField.class, 0, null);
|
||||
assertTrue("opt null", actualEnum == null);
|
||||
|
||||
// opt with default an index that does not exist
|
||||
actualEnum = jsonArray.optEnum(MyEnumField.class, 3, null);
|
||||
assertTrue("opt null", actualEnum == null);
|
||||
|
||||
}
|
||||
}
|
196
src/test/java/org/json/junit/HTTPTest.java
Normal file
196
src/test/java/org/json/junit/HTTPTest.java
Normal file
|
@ -0,0 +1,196 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.json.*;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for JSON-Java HTTP.java. See RFC7230.
|
||||
*/
|
||||
public class HTTPTest {
|
||||
|
||||
/**
|
||||
* Attempt to call HTTP.toJSONObject() with a null string
|
||||
* Expects a NUllPointerException.
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void nullHTTPException() {
|
||||
String httpStr = null;
|
||||
HTTP.toJSONObject(httpStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to call HTTP.toJSONObject() with a string containing
|
||||
* an empty object. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void notEnoughHTTPException() {
|
||||
String httpStr = "{}";
|
||||
JSONObject jsonObject = new JSONObject(httpStr);
|
||||
try {
|
||||
HTTP.toString(jsonObject);
|
||||
assertTrue("Expected to throw exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expecting an exception message",
|
||||
"Not enough material for an HTTP header.".equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling HTTP.toJSONObject() with an empty string will result in a
|
||||
* populated JSONObject with keys but no values for Request-URI, Method,
|
||||
* and HTTP-Version.
|
||||
*/
|
||||
@Test
|
||||
public void emptyStringHTTPRequest() {
|
||||
String httpStr = "";
|
||||
String expectedHTTPStr = "{\"Request-URI\":\"\",\"Method\":\"\",\"HTTP-Version\":\"\"}";
|
||||
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call HTTP.toJSONObject() with a Request-URI, Method,
|
||||
* and HTTP-Version.
|
||||
*/
|
||||
@Test
|
||||
public void simpleHTTPRequest() {
|
||||
String httpStr = "GET /hello.txt HTTP/1.1";
|
||||
String expectedHTTPStr =
|
||||
"{\"Request-URI\":\"/hello.txt\",\"Method\":\"GET\",\"HTTP-Version\":\"HTTP/1.1\"}";
|
||||
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call HTTP.toJSONObject() with a response string containing a
|
||||
* HTTP-Version, Status-Code, and Reason.
|
||||
*/
|
||||
@Test
|
||||
public void simpleHTTPResponse() {
|
||||
String httpStr = "HTTP/1.1 200 OK";
|
||||
String expectedHTTPStr =
|
||||
"{\"HTTP-Version\":\"HTTP/1.1\",\"Status-Code\":\"200\",\"Reason-Phrase\":\"OK\"}";
|
||||
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call HTTP.toJSONObject() with a full request string including
|
||||
* request headers.
|
||||
*/
|
||||
@Test
|
||||
public void extendedHTTPRequest() {
|
||||
String httpStr =
|
||||
"POST /enlighten/calais.asmx HTTP/1.1\n"+
|
||||
"Host: api.opencalais.com\n"+
|
||||
"Content-Type: text/xml; charset=utf-8\n"+
|
||||
"Content-Length: 100\n"+
|
||||
"SOAPAction: \"http://clearforest.com/Enlighten\"";
|
||||
String expectedHTTPStr =
|
||||
"{"+
|
||||
"\"Request-URI\":\"/enlighten/calais.asmx\","+
|
||||
"\"Host\":\"api.opencalais.com\","+
|
||||
"\"Method\":\"POST\","+
|
||||
"\"HTTP-Version\":\"HTTP/1.1\","+
|
||||
"\"Content-Length\":\"100\","+
|
||||
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
|
||||
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
|
||||
/**
|
||||
* Not too easy for JSONObject to parse a string with embedded quotes.
|
||||
* For the sake of the test, add it here.
|
||||
*/
|
||||
expectedJsonObject.put("SOAPAction","\"http://clearforest.com/Enlighten\"");
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call HTTP.toJSONObject() with a full response string including
|
||||
* response headers.
|
||||
*/
|
||||
@Test
|
||||
public void extendedHTTPResponse() {
|
||||
String httpStr =
|
||||
"HTTP/1.1 200 OK\n"+
|
||||
"Content-Type: text/xml; charset=utf-8\n"+
|
||||
"Content-Length: 100\n";
|
||||
String expectedHTTPStr =
|
||||
"{\"HTTP-Version\":\"HTTP/1.1\","+
|
||||
"\"Status-Code\":\"200\","+
|
||||
"\"Content-Length\":\"100\","+
|
||||
"\"Reason-Phrase\":\"OK\","+
|
||||
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
|
||||
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call HTTP.toJSONObject() with a full POST request string including
|
||||
* response headers, then convert it back into an HTTP string.
|
||||
*/
|
||||
@Test
|
||||
public void convertHTTPRequestToString() {
|
||||
String httpStr =
|
||||
"POST /enlighten/calais.asmx HTTP/1.1\n"+
|
||||
"Host: api.opencalais.com\n"+
|
||||
"Content-Type: text/xml; charset=utf-8\n"+
|
||||
"Content-Length: 100";
|
||||
String expectedHTTPStr =
|
||||
"{"+
|
||||
"\"Request-URI\":\"/enlighten/calais.asmx\","+
|
||||
"\"Host\":\"api.opencalais.com\","+
|
||||
"\"Method\":\"POST\","+
|
||||
"\"HTTP-Version\":\"HTTP/1.1\","+
|
||||
"\"Content-Length\":\"100\","+
|
||||
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
|
||||
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
|
||||
String httpToStr = HTTP.toString(jsonObject);
|
||||
/**
|
||||
* JSONObject objects to crlfs and any trailing chars.
|
||||
* For the sake of the test, simplify the resulting string
|
||||
*/
|
||||
httpToStr = httpToStr.replaceAll("("+HTTP.CRLF+HTTP.CRLF+")", "");
|
||||
httpToStr = httpToStr.replaceAll(HTTP.CRLF, "\n");
|
||||
JSONObject finalJsonObject = HTTP.toJSONObject(httpToStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call HTTP.toJSONObject() with a full response string including
|
||||
* response headers, then convert it back into an HTTP string.
|
||||
*/
|
||||
@Test
|
||||
public void convertHTTPResponseToString() {
|
||||
String httpStr =
|
||||
"HTTP/1.1 200 OK\n"+
|
||||
"Content-Type: text/xml; charset=utf-8\n"+
|
||||
"Content-Length: 100\n";
|
||||
String expectedHTTPStr =
|
||||
"{\"HTTP-Version\":\"HTTP/1.1\","+
|
||||
"\"Status-Code\":\"200\","+
|
||||
"\"Content-Length\":\"100\","+
|
||||
"\"Reason-Phrase\":\"OK\","+
|
||||
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
|
||||
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
|
||||
String httpToStr = HTTP.toString(jsonObject);
|
||||
/**
|
||||
* JSONObject objects to crlfs and any trailing chars.
|
||||
* For the sake of the test, simplify the resulting string
|
||||
*/
|
||||
httpToStr = httpToStr.replaceAll("("+HTTP.CRLF+HTTP.CRLF+")", "");
|
||||
httpToStr = httpToStr.replaceAll(HTTP.CRLF, "\n");
|
||||
JSONObject finalJsonObject = HTTP.toJSONObject(httpToStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
}
|
1073
src/test/java/org/json/junit/JSONArrayTest.java
Normal file
1073
src/test/java/org/json/junit/JSONArrayTest.java
Normal file
File diff suppressed because it is too large
Load diff
832
src/test/java/org/json/junit/JSONMLTest.java
Normal file
832
src/test/java/org/json/junit/JSONMLTest.java
Normal file
|
@ -0,0 +1,832 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.json.*;
|
||||
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 a JSONArray or JSONObject into an XML string.
|
||||
* Both fromstring and tostring operations operations should be symmetrical
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Attempts to transform a null XML string to JSON.
|
||||
* Expects a NullPointerException
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void nullXMLException() {
|
||||
String xmlStr = null;
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to transform an empty string to JSON.
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void emptyXMLException() {
|
||||
String xmlStr = "";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Bad XML at 0 [character 1 line 1]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to call JSONML.toString() with a null JSONArray.
|
||||
* Expects a NullPointerException.
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void nullJSONXMLException() {
|
||||
/**
|
||||
* Tries to convert a null JSONArray to XML.
|
||||
*/
|
||||
JSONArray jsonArray= null;
|
||||
JSONML.toString(jsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to call JSONML.toString() with a null JSONArray.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void emptyJSONXMLException() {
|
||||
/**
|
||||
* Tries to convert an empty JSONArray to XML.
|
||||
*/
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
try {
|
||||
JSONML.toString(jsonArray);
|
||||
assertTrue("Expecting an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expecting an exception message",
|
||||
"JSONArray[0] not found.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to transform an non-XML string to JSON.
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void nonXMLException() {
|
||||
/**
|
||||
* Attempts to transform a nonXML string to JSON
|
||||
*/
|
||||
String xmlStr = "{ \"this is\": \"not xml\"}";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Bad XML at 23 [character 24 line 1]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to transform a JSON document with XML content that
|
||||
* does not follow JSONML conventions (element name is not first value
|
||||
* in a nested JSONArray) to a JSONArray then back to string.
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void emptyTagException() {
|
||||
/**
|
||||
* jsonArrayStr is used to build a JSONArray which is then
|
||||
* turned into XML. For this transformation, all arrays represent
|
||||
* elements and the first array entry is the name of the element.
|
||||
* In this case, one of the arrays does not have a name
|
||||
*/
|
||||
String jsonArrayStr =
|
||||
"[\"addresses\","+
|
||||
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
|
||||
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
|
||||
// this array has no name
|
||||
"["+
|
||||
"[\"name\"],"+
|
||||
"[\"nocontent\"],"+
|
||||
"\">\""+
|
||||
"]"+
|
||||
"]";
|
||||
JSONArray jsonArray = new JSONArray(jsonArrayStr);
|
||||
try {
|
||||
JSONML.toString(jsonArray);
|
||||
assertTrue("Expecting an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"JSONArray[0] is not a String.",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to transform a JSON document with XML content that
|
||||
* does not follow JSONML conventions (element tag has an embedded space)
|
||||
* to a JSONArray then back to string. Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void spaceInTagException() {
|
||||
/**
|
||||
* jsonArrayStr is used to build a JSONArray which is then
|
||||
* turned into XML. For this transformation, all arrays represent
|
||||
* elements and the first array entry is the name of the element.
|
||||
* In this case, one of the element names has an embedded space,
|
||||
* which is not allowed.
|
||||
*/
|
||||
String jsonArrayStr =
|
||||
"[\"addresses\","+
|
||||
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
|
||||
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
|
||||
// this array has an invalid name
|
||||
"[\"addr esses\","+
|
||||
"[\"name\"],"+
|
||||
"[\"nocontent\"],"+
|
||||
"\">\""+
|
||||
"]"+
|
||||
"]";
|
||||
JSONArray jsonArray = new JSONArray(jsonArrayStr);
|
||||
try {
|
||||
JSONML.toString(jsonArray);
|
||||
assertTrue("Expecting an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expecting an exception message",
|
||||
"'addr esses' contains a space character.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to transform a malformed XML document
|
||||
* (element tag has a frontslash) to a JSONArray.\
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void invalidSlashInTagException() {
|
||||
/**
|
||||
* xmlStr contains XML text which is transformed into a JSONArray.
|
||||
* In this case, the XML is invalid because the 'name' element
|
||||
* contains an invalid frontslash.
|
||||
*/
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/x>\n"+
|
||||
" <street>abc street</street>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped tag at 176 [character 14 line 4]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Malformed XML text (invalid tagname) is transformed into a JSONArray.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void invalidBangInTagException() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <!>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped meta tag at 215 [character 12 line 7]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Malformed XML text (invalid tagname, no close bracket) is transformed\
|
||||
* into a JSONArray. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void invalidBangNoCloseInTagException() {
|
||||
/**
|
||||
* xmlStr contains XML text which is transformed into a JSONArray.
|
||||
* In this case, the XML is invalid because an element
|
||||
* starts with '!' and has no closing tag
|
||||
*/
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <!\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped meta tag at 214 [character 12 line 7]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Malformed XML text (tagname with no close bracket) is transformed\
|
||||
* into a JSONArray. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void noCloseStartTagException() {
|
||||
/**
|
||||
* xmlStr contains XML text which is transformed into a JSONArray.
|
||||
* In this case, the XML is invalid because an element
|
||||
* has no closing '>'.
|
||||
*/
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <abc\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misplaced '<' at 194 [character 5 line 6]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Malformed XML text (endtag with no name) is transformed\
|
||||
* into a JSONArray. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void noCloseEndTagException() {
|
||||
/**
|
||||
* xmlStr contains XML text which is transformed into a JSONArray.
|
||||
* In this case, the XML is invalid because an element
|
||||
* has no name after the closing tag '</'.
|
||||
*/
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <abc/>\n"+
|
||||
" </>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
assertTrue("Expecting an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expecting an exception message",
|
||||
"Expected a closing name instead of '>'.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Malformed XML text (endtag with no close bracket) is transformed\
|
||||
* into a JSONArray. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void noCloseEndBraceException() {
|
||||
/**
|
||||
* xmlStr contains XML text which is transformed into a JSONArray.
|
||||
* In this case, the XML is invalid because an element
|
||||
* has '>' after the closing tag '</' and name.
|
||||
*/
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation=\"test.xsd\">\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <abc/>\n"+
|
||||
" </address\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misplaced '<' at 206 [character 1 line 7]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Malformed XML text (incomplete CDATA string) is transformed\
|
||||
* into a JSONArray. Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void invalidCDATABangInTagException() {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name>Joe Tester</name>\n"+
|
||||
" <![[]>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
JSONML.toJSONArray(xmlStr);
|
||||
fail("Expecting an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Expected 'CDATA[' at 204 [character 11 line 5]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* confirm the contents.
|
||||
*/
|
||||
@Test
|
||||
public void toJSONArray() {
|
||||
/**
|
||||
* xmlStr contains XML text which is transformed into a JSONArray.
|
||||
* Each element becomes a JSONArray:
|
||||
* 1st entry = elementname
|
||||
* 2nd entry = attributes object (if present)
|
||||
* 3rd entry = content (if present)
|
||||
* 4th entry = child element JSONArrays (if present)
|
||||
* The result is compared against an expected JSONArray.
|
||||
* The transformed JSONArray is then transformed back into a string
|
||||
* which is used to create a final JSONArray, which is also compared
|
||||
* against the expected JSONArray.
|
||||
*/
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
"xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
"<address attr1=\"attrValue1\" attr2=\"attrValue2\" attr3=\"attrValue3\">\n"+
|
||||
"<name nameType=\"mine\">myName</name>\n"+
|
||||
"<nocontent/>>\n"+
|
||||
"</address>\n"+
|
||||
"</addresses>";
|
||||
String expectedStr =
|
||||
"[\"addresses\","+
|
||||
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
|
||||
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
|
||||
"[\"address\","+
|
||||
"{\"attr1\":\"attrValue1\",\"attr2\":\"attrValue2\",\"attr3\":\"attrValue3\"},"+
|
||||
"[\"name\", {\"nameType\":\"mine\"},\"myName\"],"+
|
||||
"[\"nocontent\"],"+
|
||||
"\">\""+
|
||||
"]"+
|
||||
"]";
|
||||
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
|
||||
JSONArray expectedJsonArray = new JSONArray(expectedStr);
|
||||
String xmlToStr = JSONML.toString(jsonArray);
|
||||
JSONArray finalJsonArray = JSONML.toJSONArray(xmlToStr);
|
||||
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* This test gives a comprehensive example of how the JSONML
|
||||
* transformations work.
|
||||
*/
|
||||
@Test
|
||||
public void toJSONObjectToJSONArray() {
|
||||
/**
|
||||
* 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
|
||||
* 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 =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
"xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
"<address addrType=\"my address\">\n"+
|
||||
"<name nameType=\"my name\">Joe Tester</name>\n"+
|
||||
"<street><![CDATA[Baker street 5]]></street>\n"+
|
||||
"<NothingHere except=\"an attribute\"/>\n"+
|
||||
"<TrueValue>true</TrueValue>\n"+
|
||||
"<FalseValue>false</FalseValue>\n"+
|
||||
"<NullValue>null</NullValue>\n"+
|
||||
"<PositiveValue>42</PositiveValue>\n"+
|
||||
"<NegativeValue>-23</NegativeValue>\n"+
|
||||
"<DoubleValue>-23.45</DoubleValue>\n"+
|
||||
"<Nan>-23x.45</Nan>\n"+
|
||||
"<ArrayOfNum>\n"+
|
||||
"<value>1</value>\n"+
|
||||
"<value>2</value>\n"+
|
||||
"<value><subValue svAttr=\"svValue\">abc</subValue></value>\n"+
|
||||
"<value>3</value>\n"+
|
||||
"<value>4.1</value>\n"+
|
||||
"<value>5.2</value>\n"+
|
||||
"</ArrayOfNum>\n"+
|
||||
"</address>\n"+
|
||||
"</addresses>";
|
||||
|
||||
String expectedJSONObjectStr =
|
||||
"{"+
|
||||
"\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
|
||||
"\"childNodes\":["+
|
||||
"{"+
|
||||
"\"childNodes\":["+
|
||||
"{"+
|
||||
"\"childNodes\":[\"Joe Tester\"],"+
|
||||
"\"nameType\":\"my name\","+
|
||||
"\"tagName\":\"name\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[\"Baker street 5\"],"+
|
||||
"\"tagName\":\"street\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"tagName\":\"NothingHere\","+
|
||||
"\"except\":\"an attribute\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[true],"+
|
||||
"\"tagName\":\"TrueValue\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[false],"+
|
||||
"\"tagName\":\"FalseValue\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[null],"+
|
||||
"\"tagName\":\"NullValue\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[42],"+
|
||||
"\"tagName\":\"PositiveValue\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[-23],"+
|
||||
"\"tagName\":\"NegativeValue\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[-23.45],"+
|
||||
"\"tagName\":\"DoubleValue\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[\"-23x.45\"],"+
|
||||
"\"tagName\":\"Nan\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":["+
|
||||
"{"+
|
||||
"\"childNodes\":[1],"+
|
||||
"\"tagName\":\"value\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[2],"+
|
||||
"\"tagName\":\"value\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":["+
|
||||
"{"+
|
||||
"\"childNodes\":[\"abc\"],"+
|
||||
"\"svAttr\":\"svValue\","+
|
||||
"\"tagName\":\"subValue\""+
|
||||
"}"+
|
||||
"],"+
|
||||
"\"tagName\":\"value\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[3],"+
|
||||
"\"tagName\":\"value\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[4.1],"+
|
||||
"\"tagName\":\"value\""+
|
||||
"},"+
|
||||
"{"+
|
||||
"\"childNodes\":[5.2],"+
|
||||
"\"tagName\":\"value\""+
|
||||
"}"+
|
||||
"],"+
|
||||
"\"tagName\":\"ArrayOfNum\""+
|
||||
"}"+
|
||||
"],"+
|
||||
"\"addrType\":\"my address\","+
|
||||
"\"tagName\":\"address\""+
|
||||
"}"+
|
||||
"],"+
|
||||
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\","+
|
||||
"\"tagName\":\"addresses\""+
|
||||
"}";
|
||||
|
||||
String expectedJSONArrayStr =
|
||||
"["+
|
||||
"\"addresses\","+
|
||||
"{"+
|
||||
"\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
|
||||
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
"},"+
|
||||
"["+
|
||||
"\"address\","+
|
||||
"{"+
|
||||
"\"addrType\":\"my address\""+
|
||||
"},"+
|
||||
"["+
|
||||
"\"name\","+
|
||||
"{"+
|
||||
"\"nameType\":\"my name\""+
|
||||
"},"+
|
||||
"\"Joe Tester\""+
|
||||
"],"+
|
||||
"[\"street\",\"Baker street 5\"],"+
|
||||
"["+
|
||||
"\"NothingHere\","+
|
||||
"{\"except\":\"an attribute\"}"+
|
||||
"],"+
|
||||
"[\"TrueValue\",true],"+
|
||||
"[\"FalseValue\",false],"+
|
||||
"[\"NullValue\",null],"+
|
||||
"[\"PositiveValue\",42],"+
|
||||
"[\"NegativeValue\",-23],"+
|
||||
"[\"DoubleValue\",-23.45],"+
|
||||
"[\"Nan\",\"-23x.45\"],"+
|
||||
"["+
|
||||
"\"ArrayOfNum\","+
|
||||
"[\"value\",1],"+
|
||||
"[\"value\",2],"+
|
||||
"[\"value\","+
|
||||
"["+
|
||||
"\"subValue\","+
|
||||
"{\"svAttr\":\"svValue\"},"+
|
||||
"\"abc\""+
|
||||
"],"+
|
||||
"],"+
|
||||
"[\"value\",3],"+
|
||||
"[\"value\",4.1],"+
|
||||
"[\"value\",5.2]"+
|
||||
"]"+
|
||||
"]"+
|
||||
"]";
|
||||
|
||||
// make a JSONObject and make sure it looks as expected
|
||||
JSONObject jsonObject = JSONML.toJSONObject(xmlStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedJSONObjectStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
|
||||
// restore the XML, then make another JSONObject and make sure it
|
||||
// looks as expected
|
||||
String jsonObjectXmlToStr = JSONML.toString(jsonObject);
|
||||
JSONObject finalJsonObject = JSONML.toJSONObject(jsonObjectXmlToStr);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject);
|
||||
|
||||
// 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);
|
||||
JSONArray finalJsonArray = JSONML.toJSONArray(jsonArrayXmlToStr);
|
||||
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
|
||||
|
||||
// lastly, confirm the restored JSONObject XML and JSONArray XML look
|
||||
// reasonably similar
|
||||
JSONObject jsonObjectFromObject = JSONML.toJSONObject(jsonObjectXmlToStr);
|
||||
JSONObject jsonObjectFromArray = JSONML.toJSONObject(jsonArrayXmlToStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObjectFromObject, jsonObjectFromArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
* This test shows how XML comments are handled.
|
||||
*/
|
||||
@Test
|
||||
public void commentsInXML() {
|
||||
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<!-- this is a comment -->\n"+
|
||||
"<addresses>\n"+
|
||||
"<address>\n"+
|
||||
"<!-- <!--[CDATA[ this is -- <another> comment ]] -->\n"+
|
||||
"<name>Joe Tester</name>\n"+
|
||||
"<!-- this is a - multi line \n"+
|
||||
"comment -->\n"+
|
||||
"<street>Baker street 5</street>\n"+
|
||||
"</address>\n"+
|
||||
"</addresses>";
|
||||
String expectedStr =
|
||||
"[\"addresses\","+
|
||||
"[\"address\","+
|
||||
"[\"name\",\"Joe Tester\"],"+
|
||||
"[\"street\",\"Baker street 5\"]"+
|
||||
"]"+
|
||||
"]";
|
||||
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
|
||||
JSONArray expectedJsonArray = new JSONArray(expectedStr);
|
||||
String xmlToStr = JSONML.toString(jsonArray);
|
||||
JSONArray finalJsonArray = JSONML.toJSONArray(xmlToStr);
|
||||
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string with lost leading zero and converted "True" to true. See test
|
||||
* result in comment below.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_jsonOutput() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",1],[\"id\",\"00\"],[\"id\",0],[\"item\",{\"id\":\"01\"}],[\"title\",true]]";
|
||||
final JSONArray actualJsonOutput = JSONML.toJSONArray(originalXml, false);
|
||||
assertEquals(expectedJsonString, actualJsonOutput.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string cannot be reverted to original xml when type guessing is used.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_reversibility() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
final String revertedXml = JSONML.toString(JSONML.toJSONArray(originalXml, false));
|
||||
assertNotEquals(revertedXml, originalXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string cannot be reverted to original xml when type guessing is used.
|
||||
* When we force all the values as string, the original text comes back.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_reversibility2() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON can be reverted to original xml.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_reversibility3() {
|
||||
final String originalXml = "<readResult><errors someAttr=\"arrtValue\"><code>400</code></errors><errors><code>402</code></errors></readResult>";
|
||||
final JSONArray jsonArray = JSONML.toJSONArray(originalXml, false);
|
||||
final String revertedXml = JSONML.toString(jsonArray);
|
||||
assertEquals(revertedXml, originalXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string cannot be reverted to original xml. See test result in
|
||||
* comment below.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONObject_reversibility() {
|
||||
final String originalXml = "<readResult><errors someAttr=\"arrtValue\"><code>400</code></errors><errors><code>402</code></errors></readResult>";
|
||||
final JSONObject originalObject=JSONML.toJSONObject(originalXml,false);
|
||||
final String originalJson = originalObject.toString();
|
||||
final String xml = JSONML.toString(originalObject);
|
||||
final JSONObject revertedObject = JSONML.toJSONObject(xml, false);
|
||||
final String newJson = revertedObject.toString();
|
||||
assertTrue("JSON Objects are not similar",originalObject.similar(revertedObject));
|
||||
assertEquals("original JSON does not equal the new JSON",originalJson, newJson);
|
||||
}
|
||||
|
||||
// these tests do not pass for the following reasons:
|
||||
// 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 <tag attr1="v1" attr2="v2" /> can not be reversed reliably.
|
||||
//
|
||||
// /**
|
||||
// * Test texts taken from jsonml.org. Currently our implementation FAILS this conversion but shouldn't.
|
||||
// * Technically JsonML should be able to transform any valid xhtml document, but ours only supports
|
||||
// * standard XML entities, not HTML entities.
|
||||
// */
|
||||
// @Test
|
||||
// public void testAttributeConversionReversabilityHTML() {
|
||||
// final String originalXml = "<table class=\"MyTable\" style=\"background-color:yellow\"><tr><td class=\"MyTD\" style=\"border:1px solid black\">#5D28D1</td><td class=\"MyTD\" style=\"background-color:red\">Example text here</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AF44EF</td><td class=\"MyTD\" style=\"background-color:green\">127310656</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AAD034</td><td class=\"MyTD\" style=\"background-color:blue\"> <span style=\"background-color:maroon\">©</span> </td></tr></table>";
|
||||
// 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.
|
||||
// */
|
||||
// @Test
|
||||
// public void testAttributeConversionReversabilityXML() {
|
||||
// final String originalXml = "<table class=\"MyTable\" style=\"background-color:yellow\"><tr><td class=\"MyTD\" style=\"border:1px solid black\">#5D28D1</td><td class=\"MyTD\" style=\"background-color:red\">Example text here</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AF44EF</td><td class=\"MyTD\" style=\"background-color:green\">127310656</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AAD034</td><td class=\"MyTD\" style=\"background-color:blue\">&<span style=\"background-color:maroon\">></span><</td></tr></table>";
|
||||
// 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
|
||||
// assertEquals(originalXml, reverseXml);
|
||||
//
|
||||
// assertEquals(expectedJsonString, actualJsonString);
|
||||
// }
|
||||
|
||||
@Test (timeout = 6000)
|
||||
public void testIssue484InfinteLoop1() {
|
||||
try {
|
||||
JSONML.toJSONObject("??*^M??|?CglR^F??`??>?w??PIlr^E??D^X^]?$?-^R?o??O?*??{OD?^FY??`2a????NM?b^Tq?:O?>S$^K?J?^FB.gUK?m^H??zE??^??!v]?^A???^[^A??^U?c??????h???s???g^Z???`?q^Dbi??:^QZl?)?}1^??k?0??:$V?$?Ovs(}J??^V????2;^QgQ?^_^A?^D?^U?Tg?K?`?h%c?hmGA?<!C*^P^Y?^X9?~?t?)??,z^XA???S}?Q??.q?j????]");
|
||||
fail("Exception expected for invalid JSON.");
|
||||
} catch (JSONException ex) {
|
||||
assertEquals("Exception string did not match: ",
|
||||
"Unterminated string at 271 [character 272 line 1]",
|
||||
ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test (timeout = 6000)
|
||||
public void testIssue484InfinteLoop2() {
|
||||
try {
|
||||
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?<!C*?9?~?t?)??,zA???S}?Q??.q?j????]";
|
||||
JSONML.toJSONObject(input);
|
||||
fail("Exception expected for invalid JSON.");
|
||||
} catch (JSONException ex) {
|
||||
assertEquals("Exception string did not match: ",
|
||||
"Unterminated string at 242 [character 238 line 2]",
|
||||
ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
56
src/test/java/org/json/junit/JSONObjectLocaleTest.java
Executable file
56
src/test/java/org/json/junit/JSONObjectLocaleTest.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.json.*;
|
||||
import org.json.junit.data.MyLocaleBean;
|
||||
import org.junit.*;
|
||||
|
||||
/**
|
||||
* Note: This file is saved as UTF-8. Do not save as ASCII or the tests will
|
||||
* fail.
|
||||
*
|
||||
*/
|
||||
public class JSONObjectLocaleTest {
|
||||
/**
|
||||
* JSONObject built from a bean with locale-specific keys.
|
||||
* In the Turkish alphabet, there are 2 versions of the letter "i".
|
||||
* 'eh' I ı (dotless i)
|
||||
* 'ee' İ i (dotted i)
|
||||
* A problem can occur when parsing the public get methods for a bean.
|
||||
* If the method starts with getI... then the key name will be lowercased
|
||||
* to 'i' in English, and 'ı' in Turkish.
|
||||
* We want the keys to be consistent regardless of locale, so JSON-Java
|
||||
* lowercase operations are made to be locale-neutral by specifying
|
||||
* Locale.ROOT. This causes 'I' to be universally lowercased to 'i'
|
||||
* regardless of the locale currently in effect.
|
||||
*/
|
||||
@Test
|
||||
public void jsonObjectByLocaleBean() {
|
||||
|
||||
MyLocaleBean myLocaleBean = new MyLocaleBean();
|
||||
|
||||
/**
|
||||
* This is just the control case which happens when the locale.ROOT
|
||||
* lowercasing behavior is the same as the current locale.
|
||||
*/
|
||||
Locale.setDefault(new Locale("en"));
|
||||
JSONObject jsonen = new JSONObject(myLocaleBean);
|
||||
assertEquals("expected size 2, found: " +jsonen.length(), 2, jsonen.length());
|
||||
assertEquals("expected jsonen[i] == beanI", "beanI", jsonen.getString("i"));
|
||||
assertEquals("expected jsonen[id] == beanId", "beanId", jsonen.getString("id"));
|
||||
|
||||
/**
|
||||
* Without the JSON-Java change, these keys would be stored internally as
|
||||
* starting with the letter, 'ı' (dotless i), since the lowercasing of
|
||||
* the getI and getId keys would be specific to the Turkish locale.
|
||||
*/
|
||||
Locale.setDefault(new Locale("tr"));
|
||||
JSONObject jsontr = new JSONObject(myLocaleBean);
|
||||
assertEquals("expected size 2, found: " +jsontr.length(), 2, jsontr.length());
|
||||
assertEquals("expected jsontr[i] == beanI", "beanI", jsontr.getString("i"));
|
||||
assertEquals("expected jsontr[id] == beanId", "beanId", jsontr.getString("id"));
|
||||
}
|
||||
}
|
3120
src/test/java/org/json/junit/JSONObjectTest.java
Normal file
3120
src/test/java/org/json/junit/JSONObjectTest.java
Normal file
File diff suppressed because it is too large
Load diff
359
src/test/java/org/json/junit/JSONPointerTest.java
Normal file
359
src/test/java/org/json/junit/JSONPointerTest.java
Normal file
|
@ -0,0 +1,359 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONPointer;
|
||||
import org.json.JSONPointerException;
|
||||
import org.json.JSONTokener;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JSONPointerTest {
|
||||
|
||||
private static final JSONObject document;
|
||||
|
||||
static {
|
||||
@SuppressWarnings("resource")
|
||||
InputStream resourceAsStream = JSONPointerTest.class.getClassLoader().getResourceAsStream("jsonpointer-testdoc.json");
|
||||
if(resourceAsStream == null) {
|
||||
throw new ExceptionInInitializerError("Unable to locate test file. Please check your development environment configuration");
|
||||
}
|
||||
document = new JSONObject(new JSONTokener(resourceAsStream));
|
||||
}
|
||||
|
||||
private Object query(String pointer) {
|
||||
return new JSONPointer(pointer).queryFrom(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyPointer() {
|
||||
assertSame(document, query(""));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void nullPointer() {
|
||||
new JSONPointer((String) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void objectPropertyQuery() {
|
||||
assertSame(document.get("foo"), query("/foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayIndexQuery() {
|
||||
assertSame(document.getJSONArray("foo").get(0), query("/foo/0"));
|
||||
}
|
||||
|
||||
@Test(expected = JSONPointerException.class)
|
||||
public void stringPropOfArrayFailure() {
|
||||
query("/foo/bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryByEmptyKey() {
|
||||
assertSame(document.get(""), query("/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryByEmptyKeySubObject() {
|
||||
assertSame(document.getJSONObject("obj").getJSONObject(""), query("/obj/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryByEmptyKeySubObjectSubOject() {
|
||||
assertSame(
|
||||
document.getJSONObject("obj").getJSONObject("").get(""),
|
||||
query("/obj//")
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryByEmptyKeySubObjectValue() {
|
||||
assertSame(
|
||||
document.getJSONObject("obj").getJSONObject("").get("subKey"),
|
||||
query("/obj//subKey")
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void slashEscaping() {
|
||||
assertSame(document.get("a/b"), query("/a~1b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tildeEscaping() {
|
||||
assertSame(document.get("m~n"), query("/m~0n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void backslashEscaping() {
|
||||
assertSame(document.get("i\\j"), query("/i\\\\j"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void quotationEscaping() {
|
||||
assertSame(document.get("k\"l"), query("/k\\\\\\\"l"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whitespaceKey() {
|
||||
assertSame(document.get(" "), query("/ "));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriFragmentNotation() {
|
||||
assertSame(document.get("foo"), query("#/foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriFragmentNotationRoot() {
|
||||
assertSame(document, query("#"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriFragmentPercentHandling() {
|
||||
assertSame(document.get("c%d"), query("#/c%25d"));
|
||||
assertSame(document.get("e^f"), query("#/e%5Ef"));
|
||||
assertSame(document.get("g|h"), query("#/g%7Ch"));
|
||||
assertSame(document.get("m~n"), query("#/m~0n"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void syntaxError() {
|
||||
new JSONPointer("key");
|
||||
}
|
||||
|
||||
@Test(expected = JSONPointerException.class)
|
||||
public void arrayIndexFailure() {
|
||||
query("/foo/2");
|
||||
}
|
||||
|
||||
@Test(expected = JSONPointerException.class)
|
||||
public void primitiveFailure() {
|
||||
query("/obj/key/failure");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builderTest() {
|
||||
JSONPointer pointer = JSONPointer.builder()
|
||||
.append("obj")
|
||||
.append("other~key").append("another/key")
|
||||
.append(0)
|
||||
.build();
|
||||
assertEquals("val", pointer.queryFrom(document));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void nullToken() {
|
||||
JSONPointer.builder().append(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringEscaping() {
|
||||
JSONPointer pointer = JSONPointer.builder()
|
||||
.append("obj")
|
||||
.append("other~key").append("another/key")
|
||||
.append("\"")
|
||||
.append(0)
|
||||
.build();
|
||||
assertEquals("/obj/other~0key/another~1key/\\\"/0", pointer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyPointerToString() {
|
||||
assertEquals("", new JSONPointer("").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toURIFragment() {
|
||||
assertEquals("#/c%25d", new JSONPointer("/c%d").toURIFragment());
|
||||
assertEquals("#/e%5Ef", new JSONPointer("/e^f").toURIFragment());
|
||||
assertEquals("#/g%7Ch", new JSONPointer("/g|h").toURIFragment());
|
||||
assertEquals("#/m%7En", new JSONPointer("/m~n").toURIFragment());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tokenListIsCopiedInConstructor() {
|
||||
JSONPointer.Builder b = JSONPointer.builder().append("key1");
|
||||
JSONPointer jp1 = b.build();
|
||||
b.append("key2");
|
||||
JSONPointer jp2 = b.build();
|
||||
if(jp1.toString().equals(jp2.toString())) {
|
||||
fail("Oops, my pointers are sharing a backing array");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverage for JSONObject query(String)
|
||||
*/
|
||||
@Test
|
||||
public void queryFromJSONObject() {
|
||||
String str = "{"+
|
||||
"\"stringKey\":\"hello world!\","+
|
||||
"\"arrayKey\":[0,1,2],"+
|
||||
"\"objectKey\": {"+
|
||||
"\"a\":\"aVal\","+
|
||||
"\"b\":\"bVal\""+
|
||||
"}"+
|
||||
"}";
|
||||
JSONObject jsonObject = new JSONObject(str);
|
||||
Object obj = jsonObject.query("/stringKey");
|
||||
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
|
||||
obj = jsonObject.query("/arrayKey/1");
|
||||
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
|
||||
obj = jsonObject.query("/objectKey/b");
|
||||
assertTrue("Expected bVal", "bVal".equals(obj));
|
||||
try {
|
||||
obj = jsonObject.query("/a/b/c");
|
||||
assertTrue("Expected JSONPointerException", false);
|
||||
} catch (JSONPointerException e) {
|
||||
assertTrue("Expected bad key/value exception",
|
||||
"value [null] is not an array or object therefore its key b cannot be resolved".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverage for JSONObject query(JSONPointer)
|
||||
*/
|
||||
@Test
|
||||
public void queryFromJSONObjectUsingPointer() {
|
||||
String str = "{"+
|
||||
"\"stringKey\":\"hello world!\","+
|
||||
"\"arrayKey\":[0,1,2],"+
|
||||
"\"objectKey\": {"+
|
||||
"\"a\":\"aVal\","+
|
||||
"\"b\":\"bVal\""+
|
||||
"}"+
|
||||
"}";
|
||||
JSONObject jsonObject = new JSONObject(str);
|
||||
Object obj = jsonObject.query(new JSONPointer("/stringKey"));
|
||||
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
|
||||
obj = jsonObject.query(new JSONPointer("/arrayKey/1"));
|
||||
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
|
||||
obj = jsonObject.query(new JSONPointer("/objectKey/b"));
|
||||
assertTrue("Expected bVal", "bVal".equals(obj));
|
||||
try {
|
||||
obj = jsonObject.query(new JSONPointer("/a/b/c"));
|
||||
assertTrue("Expected JSONPointerException", false);
|
||||
} catch (JSONPointerException e) {
|
||||
assertTrue("Expected bad key/value exception",
|
||||
"value [null] is not an array or object therefore its key b cannot be resolved".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverage for JSONObject optQuery(JSONPointer)
|
||||
*/
|
||||
@Test
|
||||
public void optQueryFromJSONObjectUsingPointer() {
|
||||
String str = "{"+
|
||||
"\"stringKey\":\"hello world!\","+
|
||||
"\"arrayKey\":[0,1,2],"+
|
||||
"\"objectKey\": {"+
|
||||
"\"a\":\"aVal\","+
|
||||
"\"b\":\"bVal\""+
|
||||
"}"+
|
||||
"}";
|
||||
JSONObject jsonObject = new JSONObject(str);
|
||||
Object obj = jsonObject.optQuery(new JSONPointer("/stringKey"));
|
||||
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
|
||||
obj = jsonObject.optQuery(new JSONPointer("/arrayKey/1"));
|
||||
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
|
||||
obj = jsonObject.optQuery(new JSONPointer("/objectKey/b"));
|
||||
assertTrue("Expected bVal", "bVal".equals(obj));
|
||||
obj = jsonObject.optQuery(new JSONPointer("/a/b/c"));
|
||||
assertTrue("Expected null", obj == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverage for JSONArray query(String)
|
||||
*/
|
||||
@Test
|
||||
public void queryFromJSONArray() {
|
||||
String str = "["+
|
||||
"\"hello world!\","+
|
||||
"[0,1,2],"+
|
||||
"{"+
|
||||
"\"a\":\"aVal\","+
|
||||
"\"b\":\"bVal\""+
|
||||
"}"+
|
||||
"]";
|
||||
JSONArray jsonArray = new JSONArray(str);
|
||||
Object obj = jsonArray.query("/0");
|
||||
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
|
||||
obj = jsonArray.query("/1/1");
|
||||
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
|
||||
obj = jsonArray.query("/2/b");
|
||||
assertTrue("Expected bVal", "bVal".equals(obj));
|
||||
try {
|
||||
obj = jsonArray.query("/a/b/c");
|
||||
assertTrue("Expected JSONPointerException", false);
|
||||
} catch (JSONPointerException e) {
|
||||
assertTrue("Expected bad index exception",
|
||||
"a is not an array index".equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverage for JSONArray query(JSONPointer)
|
||||
*/
|
||||
@Test
|
||||
public void queryFromJSONArrayUsingPointer() {
|
||||
String str = "["+
|
||||
"\"hello world!\","+
|
||||
"[0,1,2],"+
|
||||
"{"+
|
||||
"\"a\":\"aVal\","+
|
||||
"\"b\":\"bVal\""+
|
||||
"}"+
|
||||
"]";
|
||||
JSONArray jsonArray = new JSONArray(str);
|
||||
Object obj = jsonArray.query(new JSONPointer("/0"));
|
||||
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
|
||||
obj = jsonArray.query(new JSONPointer("/1/1"));
|
||||
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
|
||||
obj = jsonArray.query(new JSONPointer("/2/b"));
|
||||
assertTrue("Expected bVal", "bVal".equals(obj));
|
||||
try {
|
||||
obj = jsonArray.query(new JSONPointer("/a/b/c"));
|
||||
assertTrue("Expected JSONPointerException", false);
|
||||
} catch (JSONPointerException e) {
|
||||
assertTrue("Expected bad index exception",
|
||||
"a is not an array index".equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverage for JSONArray optQuery(JSONPointer)
|
||||
*/
|
||||
@Test
|
||||
public void optQueryFromJSONArrayUsingPointer() {
|
||||
String str = "["+
|
||||
"\"hello world!\","+
|
||||
"[0,1,2],"+
|
||||
"{"+
|
||||
"\"a\":\"aVal\","+
|
||||
"\"b\":\"bVal\""+
|
||||
"}"+
|
||||
"]";
|
||||
JSONArray jsonArray = new JSONArray(str);
|
||||
Object obj = jsonArray.optQuery(new JSONPointer("/0"));
|
||||
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
|
||||
obj = jsonArray.optQuery(new JSONPointer("/1/1"));
|
||||
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
|
||||
obj = jsonArray.optQuery(new JSONPointer("/2/b"));
|
||||
assertTrue("Expected bVal", "bVal".equals(obj));
|
||||
obj = jsonArray.optQuery(new JSONPointer("/a/b/c"));
|
||||
assertTrue("Expected null", obj == null);
|
||||
}
|
||||
}
|
371
src/test/java/org/json/junit/JSONStringTest.java
Normal file
371
src/test/java/org/json/junit/JSONStringTest.java
Normal file
|
@ -0,0 +1,371 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.*;
|
||||
|
||||
import org.json.*;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for JSONString implementations, and the difference between
|
||||
* {@link JSONObject#valueToString} and {@link JSONObject#writeValue}.
|
||||
*/
|
||||
public class JSONStringTest {
|
||||
|
||||
/**
|
||||
* This tests the JSONObject.writeValue() method. We can't test directly
|
||||
* due to it being a package-protected method. Instead, we can call
|
||||
* JSONArray.write(), which delegates the writing of each entry to
|
||||
* writeValue().
|
||||
*/
|
||||
@Test
|
||||
public void writeValues() throws Exception {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.put((Object)null);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[null]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
jsonArray.put(JSONObject.NULL);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[null]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
jsonArray.put(new JSONObject());
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[{}]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
jsonArray.put(new JSONArray());
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[[]]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
Map<?,?> singleMap = Collections.singletonMap("key1", "value1");
|
||||
jsonArray.put((Object)singleMap);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[{\"key1\":\"value1\"}]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
List<?> singleList = Collections.singletonList("entry1");
|
||||
jsonArray.put((Object)singleList);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[[\"entry1\"]]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
int[] intArray = new int[] { 1, 2, 3 };
|
||||
jsonArray.put(intArray);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[[1,2,3]]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
jsonArray.put(24);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[24]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
jsonArray.put("string value");
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[\"string value\"]".equals(output));
|
||||
|
||||
jsonArray = new JSONArray();
|
||||
jsonArray.put(true);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[true]".equals(output));
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests the JSONObject.valueToString() method. These should be
|
||||
* identical to the values above, except for the enclosing [ and ].
|
||||
*/
|
||||
@SuppressWarnings("boxing")
|
||||
@Test
|
||||
public void valuesToString() throws Exception {
|
||||
|
||||
String output = JSONObject.valueToString(null);
|
||||
assertTrue("String values should be equal", "null".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(JSONObject.NULL);
|
||||
assertTrue("String values should be equal", "null".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(new JSONObject());
|
||||
assertTrue("String values should be equal", "{}".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(new JSONArray());
|
||||
assertTrue("String values should be equal", "[]".equals(output));
|
||||
|
||||
Map<?,?> singleMap = Collections.singletonMap("key1", "value1");
|
||||
output = JSONObject.valueToString(singleMap);
|
||||
assertTrue("String values should be equal", "{\"key1\":\"value1\"}".equals(output));
|
||||
|
||||
List<?> singleList = Collections.singletonList("entry1");
|
||||
output = JSONObject.valueToString(singleList);
|
||||
assertTrue("String values should be equal", "[\"entry1\"]".equals(output));
|
||||
|
||||
int[] intArray = new int[] { 1, 2, 3 };
|
||||
output = JSONObject.valueToString(intArray);
|
||||
assertTrue("String values should be equal", "[1,2,3]".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(24);
|
||||
assertTrue("String values should be equal", "24".equals(output));
|
||||
|
||||
output = JSONObject.valueToString("string value");
|
||||
assertTrue("String values should be equal", "\"string value\"".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(true);
|
||||
assertTrue("String values should be equal", "true".equals(output));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test what happens when toJSONString() returns a well-formed JSON value.
|
||||
* This is the usual case.
|
||||
*/
|
||||
@Test
|
||||
public void testJSONStringValue() throws Exception {
|
||||
JSONStringValue jsonString = new JSONStringValue();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
jsonArray.put(jsonString);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[\"the JSON string value\"]".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(jsonString);
|
||||
assertTrue("String values should be equal", "\"the JSON string value\"".equals(output));
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test what happens when toJSONString() returns null. In one case,
|
||||
* use the object's toString() method. In the other, throw a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void testJSONNullStringValue() throws Exception {
|
||||
JSONNullStringValue jsonString = new JSONNullStringValue();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
jsonArray.put(jsonString);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[\"the toString value\"]".equals(output));
|
||||
|
||||
// The only different between writeValue() and valueToString():
|
||||
// in this case, valueToString throws a JSONException
|
||||
try {
|
||||
output = JSONObject.valueToString(jsonString);
|
||||
fail("Expected an exception, got a String value");
|
||||
} catch (Exception e) {
|
||||
assertTrue("Expected JSONException", e instanceof JSONException);
|
||||
assertTrue("Exception message does not match", "Bad value from toJSONString: null".equals(e.getMessage()));
|
||||
}
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test what happens when toJSONString() returns an exception. In both
|
||||
* cases, a JSONException is thrown, with the cause and message set from
|
||||
* the original exception.
|
||||
*/
|
||||
@Test
|
||||
public void testJSONStringExceptionValue() throws IOException {
|
||||
JSONStringExceptionValue jsonString = new JSONStringExceptionValue();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
jsonArray.put(jsonString);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
try {
|
||||
jsonArray.write(writer).toString();
|
||||
fail("Expected an exception, got a String value");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Unable to write JSONArray value at index: 0", e.getMessage());
|
||||
} catch(Exception e) {
|
||||
fail("Expected JSONException");
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject.valueToString(jsonString);
|
||||
fail("Expected an exception, got a String value");
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Exception message does not match", "the exception value".equals(e.getMessage()));
|
||||
} catch(Exception e) {
|
||||
fail("Expected JSONException");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test what happens when a Java object's toString() returns a String value.
|
||||
* This is the usual case.
|
||||
*/
|
||||
@Test
|
||||
public void testStringValue() throws Exception {
|
||||
StringValue nonJsonString = new StringValue();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
jsonArray.put(nonJsonString);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[\"the toString value for StringValue\"]".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(nonJsonString);
|
||||
assertTrue("String values should be equal", "\"the toString value for StringValue\"".equals(output));
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test what happens when a Java object's toString() returns null.
|
||||
* Defaults to empty string.
|
||||
*/
|
||||
@Test
|
||||
public void testNullStringValue() throws Exception {
|
||||
NullStringValue nonJsonString = new NullStringValue();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
jsonArray.put(nonJsonString);
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
try {
|
||||
String output = jsonArray.write(writer).toString();
|
||||
assertTrue("String values should be equal", "[\"\"]".equals(output));
|
||||
|
||||
output = JSONObject.valueToString(nonJsonString);
|
||||
assertTrue("String values should be equal", "\"\"".equals(output));
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A JSONString that returns a valid JSON string value.
|
||||
*/
|
||||
private static final class JSONStringValue implements JSONString {
|
||||
|
||||
@Override
|
||||
public String toJSONString() {
|
||||
return "\"the JSON string value\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "the toString value for JSONStringValue";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A JSONString that returns null when calling toJSONString().
|
||||
*/
|
||||
private static final class JSONNullStringValue implements JSONString {
|
||||
|
||||
@Override
|
||||
public String toJSONString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "the toString value";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A JSONString that throw an exception when calling toJSONString().
|
||||
*/
|
||||
private static final class JSONStringExceptionValue implements JSONString {
|
||||
|
||||
@Override
|
||||
public String toJSONString() {
|
||||
throw new IllegalStateException("the exception value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "the toString value for JSONStringExceptionValue";
|
||||
}
|
||||
}
|
||||
|
||||
public static final class StringValue {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "the toString value for StringValue";
|
||||
}
|
||||
}
|
||||
|
||||
public static final class NullStringValue {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
352
src/test/java/org/json/junit/JSONStringerTest.java
Normal file
352
src/test/java/org/json/junit/JSONStringerTest.java
Normal file
|
@ -0,0 +1,352 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.json.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.jayway.jsonpath.*;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for JSON-Java JSONStringer and JSONWriter.
|
||||
*/
|
||||
public class JSONStringerTest {
|
||||
|
||||
/**
|
||||
* Object with a null key.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void nullKeyException() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.object();
|
||||
try {
|
||||
jsonStringer.key(null);
|
||||
assertTrue("Expected an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expected an exception message",
|
||||
"Null key.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a key with no object.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void outOfSequenceException() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
try {
|
||||
jsonStringer.key("hi");
|
||||
assertTrue("Expected an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expected an exception message",
|
||||
"Misplaced key.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Missplace an array.
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void missplacedArrayException() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.object().endObject();
|
||||
try {
|
||||
jsonStringer.array();
|
||||
assertTrue("Expected an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expected an exception message",
|
||||
"Misplaced array.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Missplace an endErray.
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void missplacedEndArrayException() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.object();
|
||||
try {
|
||||
jsonStringer.endArray();
|
||||
assertTrue("Expected an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expected an exception message",
|
||||
"Misplaced endArray.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Missplace an endObject.
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void missplacedEndObjectException() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.array();
|
||||
try {
|
||||
jsonStringer.endObject();
|
||||
assertTrue("Expected an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expected an exception message",
|
||||
"Misplaced endObject.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Missplace an object.
|
||||
* Expects a JSONException.
|
||||
*/
|
||||
@Test
|
||||
public void missplacedObjectException() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.object().endObject();
|
||||
try {
|
||||
jsonStringer.object();
|
||||
assertTrue("Expected an exception", false);
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expected an exception message",
|
||||
"Misplaced object.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exceeds implementation max nesting depth.
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void exceedNestDepthException() {
|
||||
try {
|
||||
JSONStringer s = new JSONStringer();
|
||||
s.object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object();
|
||||
s.key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
|
||||
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object();
|
||||
fail("Expected an exception message");
|
||||
} catch (JSONException e) {
|
||||
assertTrue("Expected an exception message",
|
||||
"Nesting too deep.".
|
||||
equals(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JSON doc using JSONString API calls,
|
||||
* then convert to JSONObject
|
||||
*/
|
||||
@Test
|
||||
public void simpleObjectString() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.object();
|
||||
jsonStringer.key("trueValue").value(true);
|
||||
jsonStringer.key("falseValue").value(false);
|
||||
jsonStringer.key("nullValue").value(null);
|
||||
jsonStringer.key("stringValue").value("hello world!");
|
||||
jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!");
|
||||
jsonStringer.key("intValue").value(42);
|
||||
jsonStringer.key("doubleValue").value(-23.45e67);
|
||||
jsonStringer.endObject();
|
||||
String str = jsonStringer.toString();
|
||||
JSONObject jsonObject = new JSONObject(str);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 7 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 7);
|
||||
assertTrue("expected true", Boolean.TRUE.equals(jsonObject.query("/trueValue")));
|
||||
assertTrue("expected false", Boolean.FALSE.equals(jsonObject.query("/falseValue")));
|
||||
assertTrue("expected null", JSONObject.NULL.equals(jsonObject.query("/nullValue")));
|
||||
assertTrue("expected hello world!", "hello world!".equals(jsonObject.query("/stringValue")));
|
||||
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/complexStringValue")));
|
||||
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/intValue")));
|
||||
assertTrue("expected -23.45e67", Double.valueOf(-23.45e67).equals(jsonObject.query("/doubleValue")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JSON doc using JSONString API calls,
|
||||
* then convert to JSONArray
|
||||
*/
|
||||
@Test
|
||||
public void simpleArrayString() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.array();
|
||||
jsonStringer.value(true);
|
||||
jsonStringer.value(false);
|
||||
jsonStringer.value(null);
|
||||
jsonStringer.value("hello world!");
|
||||
jsonStringer.value(42);
|
||||
jsonStringer.value(-23.45e67);
|
||||
jsonStringer.endArray();
|
||||
String str = jsonStringer.toString();
|
||||
JSONArray jsonArray = new JSONArray(str);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
|
||||
assertTrue("expected 6 top level items", ((List<?>)(JsonPath.read(doc, "$"))).size() == 6);
|
||||
assertTrue("expected true", Boolean.TRUE.equals(jsonArray.query("/0")));
|
||||
assertTrue("expected false", Boolean.FALSE.equals(jsonArray.query("/1")));
|
||||
assertTrue("expected null", JSONObject.NULL.equals(jsonArray.query("/2")));
|
||||
assertTrue("expected hello world!", "hello world!".equals(jsonArray.query("/3")));
|
||||
assertTrue("expected 42", Integer.valueOf(42).equals(jsonArray.query("/4")));
|
||||
assertTrue("expected -23.45e67", Double.valueOf(-23.45e67).equals(jsonArray.query("/5")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a nested JSON doc using JSONString API calls, then convert to
|
||||
* JSONObject. Will create a long cascade of output by reusing the
|
||||
* returned values..
|
||||
*/
|
||||
@Test
|
||||
public void complexObjectString() {
|
||||
JSONStringer jsonStringer = new JSONStringer();
|
||||
jsonStringer.object().
|
||||
key("trueValue").value(true).
|
||||
key("falseValue").value(false).
|
||||
key("nullValue").value(null).
|
||||
key("stringValue").value("hello world!").
|
||||
key("object2").object().
|
||||
key("k1").value("v1").
|
||||
key("k2").value("v2").
|
||||
key("k3").value("v3").
|
||||
key("array1").array().
|
||||
value(1).
|
||||
value(2).
|
||||
object().
|
||||
key("k4").value("v4").
|
||||
key("k5").value("v5").
|
||||
key("k6").value("v6").
|
||||
key("array2").array().
|
||||
value(5).
|
||||
value(6).
|
||||
value(7).
|
||||
value(8).
|
||||
endArray().
|
||||
endObject().
|
||||
value(3).
|
||||
value(4).
|
||||
endArray().
|
||||
endObject().
|
||||
key("complexStringValue").value("h\be\tllo w\u1234orld!").
|
||||
key("intValue").value(42).
|
||||
key("doubleValue").value(-23.45e67).
|
||||
endObject();
|
||||
String str = jsonStringer.toString();
|
||||
JSONObject jsonObject = new JSONObject(str);
|
||||
|
||||
// validate JSON content
|
||||
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
|
||||
assertTrue("expected 8 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 8);
|
||||
assertTrue("expected 4 object2 items", ((Map<?,?>)(JsonPath.read(doc, "$.object2"))).size() == 4);
|
||||
assertTrue("expected 5 array1 items", ((List<?>)(JsonPath.read(doc, "$.object2.array1"))).size() == 5);
|
||||
assertTrue("expected 4 array[2] items", ((Map<?,?>)(JsonPath.read(doc, "$.object2.array1[2]"))).size() == 4);
|
||||
assertTrue("expected 4 array1[2].array2 items", ((List<?>)(JsonPath.read(doc, "$.object2.array1[2].array2"))).size() == 4);
|
||||
assertTrue("expected true", Boolean.TRUE.equals(jsonObject.query("/trueValue")));
|
||||
assertTrue("expected false", Boolean.FALSE.equals(jsonObject.query("/falseValue")));
|
||||
assertTrue("expected null", JSONObject.NULL.equals(jsonObject.query("/nullValue")));
|
||||
assertTrue("expected hello world!", "hello world!".equals(jsonObject.query("/stringValue")));
|
||||
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/intValue")));
|
||||
assertTrue("expected -23.45e67", Double.valueOf(-23.45e67).equals(jsonObject.query("/doubleValue")));
|
||||
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/complexStringValue")));
|
||||
assertTrue("expected v1", "v1".equals(jsonObject.query("/object2/k1")));
|
||||
assertTrue("expected v2", "v2".equals(jsonObject.query("/object2/k2")));
|
||||
assertTrue("expected v3", "v3".equals(jsonObject.query("/object2/k3")));
|
||||
assertTrue("expected 1", Integer.valueOf(1).equals(jsonObject.query("/object2/array1/0")));
|
||||
assertTrue("expected 2", Integer.valueOf(2).equals(jsonObject.query("/object2/array1/1")));
|
||||
assertTrue("expected v4", "v4".equals(jsonObject.query("/object2/array1/2/k4")));
|
||||
assertTrue("expected v5", "v5".equals(jsonObject.query("/object2/array1/2/k5")));
|
||||
assertTrue("expected v6", "v6".equals(jsonObject.query("/object2/array1/2/k6")));
|
||||
assertTrue("expected 5", Integer.valueOf(5).equals(jsonObject.query("/object2/array1/2/array2/0")));
|
||||
assertTrue("expected 6", Integer.valueOf(6).equals(jsonObject.query("/object2/array1/2/array2/1")));
|
||||
assertTrue("expected 7", Integer.valueOf(7).equals(jsonObject.query("/object2/array1/2/array2/2")));
|
||||
assertTrue("expected 8", Integer.valueOf(8).equals(jsonObject.query("/object2/array1/2/array2/3")));
|
||||
assertTrue("expected 3", Integer.valueOf(3).equals(jsonObject.query("/object2/array1/3")));
|
||||
assertTrue("expected 4", Integer.valueOf(4).equals(jsonObject.query("/object2/array1/4")));
|
||||
}
|
||||
|
||||
}
|
295
src/test/java/org/json/junit/JSONTokenerTest.java
Normal file
295
src/test/java/org/json/junit/JSONTokenerTest.java
Normal file
|
@ -0,0 +1,295 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test specific to the {@link org.json.JSONTokener} class.
|
||||
* @author John Aylward
|
||||
*
|
||||
*/
|
||||
public class JSONTokenerTest {
|
||||
|
||||
/**
|
||||
* verify that back() fails as expected.
|
||||
* @throws IOException thrown if something unexpected happens.
|
||||
*/
|
||||
@Test
|
||||
public void verifyBackFailureZeroIndex() throws IOException {
|
||||
try(Reader reader = new StringReader("some test string")) {
|
||||
final JSONTokener tokener = new JSONTokener(reader);
|
||||
try {
|
||||
// this should fail since the index is 0;
|
||||
tokener.back();
|
||||
fail("Expected an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Stepping back two steps is not supported", e.getMessage());
|
||||
} catch (Exception e) {
|
||||
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* verify that back() fails as expected.
|
||||
* @throws IOException thrown if something unexpected happens.
|
||||
*/
|
||||
@Test
|
||||
public void verifyBackFailureDoubleBack() throws IOException {
|
||||
try(Reader reader = new StringReader("some test string")) {
|
||||
final JSONTokener tokener = new JSONTokener(reader);
|
||||
tokener.next();
|
||||
tokener.back();
|
||||
try {
|
||||
// this should fail since the index is 0;
|
||||
tokener.back();
|
||||
fail("Expected an exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Stepping back two steps is not supported", e.getMessage());
|
||||
} catch (Exception e) {
|
||||
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValid() {
|
||||
checkValid("0",Number.class);
|
||||
checkValid(" 0 ",Number.class);
|
||||
checkValid("23",Number.class);
|
||||
checkValid("23.5",Number.class);
|
||||
checkValid(" 23.5 ",Number.class);
|
||||
checkValid("null",null);
|
||||
checkValid(" null ",null);
|
||||
checkValid("true",Boolean.class);
|
||||
checkValid(" true\n",Boolean.class);
|
||||
checkValid("false",Boolean.class);
|
||||
checkValid("\nfalse ",Boolean.class);
|
||||
checkValid("{}",JSONObject.class);
|
||||
checkValid(" {} ",JSONObject.class);
|
||||
checkValid("{\"a\":1}",JSONObject.class);
|
||||
checkValid(" {\"a\":1} ",JSONObject.class);
|
||||
checkValid("[]",JSONArray.class);
|
||||
checkValid(" [] ",JSONArray.class);
|
||||
checkValid("[1,2]",JSONArray.class);
|
||||
checkValid("\n\n[1,2]\n\n",JSONArray.class);
|
||||
checkValid("1 2", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrors() {
|
||||
// Check that stream can detect that a value is found after
|
||||
// the first one
|
||||
checkError(" { \"a\":1 } 4 ");
|
||||
checkError("null \"a\"");
|
||||
checkError("{} true");
|
||||
}
|
||||
|
||||
private Object checkValid(String testStr, Class<?> aClass) {
|
||||
Object result = nextValue(testStr);
|
||||
|
||||
// Check class of object returned
|
||||
if( null == aClass ) {
|
||||
if(JSONObject.NULL.equals(result)) {
|
||||
// OK
|
||||
} else {
|
||||
throw new JSONException("Unexpected class: "+result.getClass().getSimpleName());
|
||||
}
|
||||
} else {
|
||||
if( null == result ) {
|
||||
throw new JSONException("Unexpected null result");
|
||||
} else if(!aClass.isAssignableFrom(result.getClass()) ) {
|
||||
throw new JSONException("Unexpected class: "+result.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkError(String testStr) {
|
||||
try {
|
||||
nextValue(testStr);
|
||||
|
||||
fail("Error should be triggered: (\""+testStr+"\")");
|
||||
} catch (JSONException e) {
|
||||
// OK
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that JSONTokener can read a stream that contains a value. After
|
||||
* the reading is done, check that the stream is left in the correct state
|
||||
* by reading the characters after. All valid cases should reach end of stream.
|
||||
* @param testStr
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private Object nextValue(String testStr) throws JSONException {
|
||||
try(StringReader sr = new StringReader(testStr);){
|
||||
JSONTokener tokener = new JSONTokener(sr);
|
||||
|
||||
Object result = tokener.nextValue();
|
||||
|
||||
if( result == null ) {
|
||||
throw new JSONException("Unable to find value token in JSON stream: ("+tokener+"): "+testStr);
|
||||
}
|
||||
|
||||
char c = tokener.nextClean();
|
||||
if( 0 != c ) {
|
||||
throw new JSONException("Unexpected character found at end of JSON stream: "+c+ " ("+tokener+"): "+testStr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the failure of the skipTo method with a buffered reader. Preferably
|
||||
* we'd like this not to fail but at this time we don't have a good recovery.
|
||||
*
|
||||
* @throws IOException thrown if something unexpected happens.
|
||||
*/
|
||||
@Test
|
||||
public void testSkipToFailureWithBufferedReader() throws IOException {
|
||||
final byte[] superLongBuffer = new byte[1000001];
|
||||
// fill our buffer
|
||||
for(int i=0;i<superLongBuffer.length;i++) {
|
||||
superLongBuffer[i] = 'A';
|
||||
}
|
||||
try(Reader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(superLongBuffer)))) {
|
||||
final JSONTokener tokener = new JSONTokener(reader);
|
||||
try {
|
||||
// this should fail since the internal markAhead buffer is only 1,000,000
|
||||
// but 'B' doesn't exist in our buffer that is 1,000,001 in size
|
||||
tokener.skipTo('B');
|
||||
fail("Expected exception");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Mark invalid", e.getMessage());
|
||||
} catch (Exception e) {
|
||||
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the success of the skipTo method with a String reader.
|
||||
*
|
||||
* @throws IOException thrown if something unexpected happens.
|
||||
*/
|
||||
@Test
|
||||
public void testSkipToSuccessWithStringReader() throws IOException {
|
||||
final StringBuilder superLongBuffer = new StringBuilder(1000001);
|
||||
// fill our buffer
|
||||
for(int i=0;i<superLongBuffer.length();i++) {
|
||||
superLongBuffer.append('A');
|
||||
}
|
||||
try(Reader reader = new StringReader(superLongBuffer.toString())) {
|
||||
final JSONTokener tokener = new JSONTokener(reader);
|
||||
try {
|
||||
// this should not fail since the internal markAhead is ignored for StringReaders
|
||||
tokener.skipTo('B');
|
||||
} catch (Exception e) {
|
||||
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that next and back are working properly and tracking the correct positions
|
||||
* with different new line combinations.
|
||||
*/
|
||||
@Test
|
||||
public void testNextBackComboWithNewLines() {
|
||||
final String testString = "this is\nA test\r\nWith some different\rNew Lines";
|
||||
// ^ ^ ^ ^
|
||||
// index positions 0 8 16 36
|
||||
final JSONTokener tokener = new JSONTokener(testString);
|
||||
assertEquals(" at 0 [character 1 line 1]", tokener.toString());
|
||||
assertEquals('t',tokener.next());
|
||||
assertEquals(" at 1 [character 2 line 1]", tokener.toString());
|
||||
tokener.skipTo('\n');
|
||||
assertEquals("skipTo() improperly modifying indexes"," at 7 [character 8 line 1]", tokener.toString());
|
||||
assertEquals('\n',tokener.next());
|
||||
assertEquals(" at 8 [character 0 line 2]", tokener.toString());
|
||||
assertEquals('A',tokener.next());
|
||||
assertEquals(" at 9 [character 1 line 2]", tokener.toString());
|
||||
tokener.back();
|
||||
assertEquals(" at 8 [character 0 line 2]", tokener.toString());
|
||||
tokener.skipTo('\r');
|
||||
assertEquals("skipTo() improperly modifying indexes"," at 14 [character 6 line 2]", tokener.toString());
|
||||
// verify \r\n combo doesn't increment the line twice
|
||||
assertEquals('\r', tokener.next());
|
||||
assertEquals(" at 15 [character 0 line 3]", tokener.toString());
|
||||
assertEquals('\n', tokener.next());
|
||||
assertEquals(" at 16 [character 0 line 3]", tokener.toString());
|
||||
// verify stepping back after reading the \n of an \r\n combo doesn't increment the line incorrectly
|
||||
tokener.back();
|
||||
assertEquals(" at 15 [character 6 line 2]", tokener.toString());
|
||||
assertEquals('\n', tokener.next());
|
||||
assertEquals(" at 16 [character 0 line 3]", tokener.toString());
|
||||
assertEquals('W', tokener.next());
|
||||
assertEquals(" at 17 [character 1 line 3]", tokener.toString());
|
||||
assertEquals('i', tokener.next());
|
||||
assertEquals(" at 18 [character 2 line 3]", tokener.toString());
|
||||
tokener.skipTo('\r');
|
||||
assertEquals("skipTo() improperly modifying indexes"," at 35 [character 19 line 3]", tokener.toString());
|
||||
assertEquals('\r', tokener.next());
|
||||
assertEquals(" at 36 [character 0 line 4]", tokener.toString());
|
||||
tokener.back();
|
||||
assertEquals(" at 35 [character 19 line 3]", tokener.toString());
|
||||
assertEquals('\r', tokener.next());
|
||||
assertEquals(" at 36 [character 0 line 4]", tokener.toString());
|
||||
assertEquals('N', tokener.next());
|
||||
assertEquals(" at 37 [character 1 line 4]", tokener.toString());
|
||||
|
||||
// verify we get the same data just walking though, no calls to back
|
||||
final JSONTokener t2 = new JSONTokener(testString);
|
||||
for(int i=0; i<7; i++) {
|
||||
assertTrue(t2.toString().startsWith(" at " + i + " "));
|
||||
assertEquals(testString.charAt(i), t2.next());
|
||||
}
|
||||
assertEquals(" at 7 [character 8 line 1]", t2.toString());
|
||||
assertEquals(testString.charAt(7), t2.next());
|
||||
assertEquals(" at 8 [character 0 line 2]", t2.toString());
|
||||
for(int i=8; i<14; i++) {
|
||||
assertTrue(t2.toString().startsWith(" at " + i + " "));
|
||||
assertEquals(testString.charAt(i), t2.next());
|
||||
}
|
||||
assertEquals(" at 14 [character 6 line 2]", t2.toString());
|
||||
assertEquals('\r', t2.next());
|
||||
assertEquals(" at 15 [character 0 line 3]", t2.toString());
|
||||
assertEquals('\n', t2.next());
|
||||
assertEquals(" at 16 [character 0 line 3]", t2.toString());
|
||||
assertEquals('W', t2.next());
|
||||
assertEquals(" at 17 [character 1 line 3]", t2.toString());
|
||||
for(int i=17; i<37; i++) {
|
||||
assertTrue(t2.toString().startsWith(" at " + i + " "));
|
||||
assertEquals(testString.charAt(i), t2.next());
|
||||
}
|
||||
assertEquals(" at 37 [character 1 line 4]", t2.toString());
|
||||
for(int i=37; i<testString.length(); i++) {
|
||||
assertTrue(t2.toString().startsWith(" at " + i + " "));
|
||||
assertEquals(testString.charAt(i), t2.next());
|
||||
}
|
||||
assertEquals(" at "+ testString.length() +" [character 9 line 4]", t2.toString());
|
||||
// end of the input
|
||||
assertEquals(0, t2.next());
|
||||
assertFalse(t2.more());
|
||||
}
|
||||
}
|
25
src/test/java/org/json/junit/JunitTestSuite.java
Normal file
25
src/test/java/org/json/junit/JunitTestSuite.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package org.json.junit;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
CDLTest.class,
|
||||
CookieTest.class,
|
||||
CookieListTest.class,
|
||||
PropertyTest.class,
|
||||
XMLTest.class,
|
||||
JSONMLTest.class,
|
||||
HTTPTest.class,
|
||||
JSONStringerTest.class,
|
||||
JSONObjectTest.class,
|
||||
JSONObjectLocaleTest.class,
|
||||
JSONArrayTest.class,
|
||||
EnumTest.class,
|
||||
JSONPointerTest.class,
|
||||
JSONStringTest.class,
|
||||
JSONTokenerTest.class,
|
||||
XMLConfigurationTest.class
|
||||
})
|
||||
public class JunitTestSuite {
|
||||
}
|
98
src/test/java/org/json/junit/PropertyTest.java
Normal file
98
src/test/java/org/json/junit/PropertyTest.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
package org.json.junit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.json.*;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for JSON-Java Property
|
||||
*/
|
||||
public class PropertyTest {
|
||||
|
||||
/**
|
||||
* JSONObject from null properties object should
|
||||
* result in an empty JSONObject.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNullProperties() {
|
||||
Properties properties = null;
|
||||
JSONObject jsonObject = Property.toJSONObject(properties);
|
||||
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* JSONObject from empty properties object should
|
||||
* result in an empty JSONObject.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyProperties() {
|
||||
Properties properties = new Properties();
|
||||
JSONObject jsonObject = Property.toJSONObject(properties);
|
||||
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* JSONObject from simple properties object.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleProperties() {
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.put("Illinois", "Springfield");
|
||||
properties.put("Missouri", "Jefferson City");
|
||||
properties.put("Washington", "Olympia");
|
||||
properties.put("California", "Sacramento");
|
||||
properties.put("Indiana", "Indianapolis");
|
||||
|
||||
JSONObject jsonObject = Property.toJSONObject(properties);
|
||||
|
||||
assertTrue("jsonObject should contain 5 items", jsonObject.length() == 5);
|
||||
assertTrue("jsonObject should contain Illinois property",
|
||||
"Springfield".equals(jsonObject.get("Illinois")));
|
||||
assertTrue("jsonObject should contain Missouri property",
|
||||
"Jefferson City".equals(jsonObject.get("Missouri")));
|
||||
assertTrue("jsonObject should contain Washington property",
|
||||
"Olympia".equals(jsonObject.get("Washington")));
|
||||
assertTrue("jsonObject should contain California property",
|
||||
"Sacramento".equals(jsonObject.get("California")));
|
||||
assertTrue("jsonObject should contain Indiana property",
|
||||
"Indianapolis".equals(jsonObject.get("Indiana")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Null JSONObject toProperties() should result in an empty
|
||||
* Properties object.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNullJSONProperty() {
|
||||
JSONObject jsonObject= null;
|
||||
Properties properties = Property.toProperties(jsonObject);
|
||||
assertTrue("properties should be empty",
|
||||
properties.size() == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties should convert to JSONObject, and back to
|
||||
* Properties without changing.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleJSONProperty() {
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.put("Illinois", "Springfield");
|
||||
properties.put("Missouri", "Jefferson City");
|
||||
properties.put("Washington", "Olympia");
|
||||
properties.put("California", "Sacramento");
|
||||
properties.put("Indiana", "Indianapolis");
|
||||
|
||||
JSONObject jsonObject = Property.toJSONObject(properties);
|
||||
Properties jsonProperties = Property.toProperties(jsonObject);
|
||||
|
||||
assertTrue("property objects should match",
|
||||
properties.equals(jsonProperties));
|
||||
}
|
||||
}
|
19
src/test/java/org/json/junit/TestRunner.java
Normal file
19
src/test/java/org/json/junit/TestRunner.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
package org.json.junit;
|
||||
|
||||
import org.junit.runner.JUnitCore;
|
||||
import org.junit.runner.Result;
|
||||
import org.junit.runner.notification.Failure;
|
||||
|
||||
/**
|
||||
* Invoke this class main method if you want to run unit tests from the
|
||||
* command line. If successful, will print "true" to stdout.
|
||||
*/
|
||||
public class TestRunner {
|
||||
public static void main(String[] args) {
|
||||
Result result = JUnitCore.runClasses(JunitTestSuite.class);
|
||||
for (Failure failure : result.getFailures()) {
|
||||
System.out.println(failure.toString());
|
||||
}
|
||||
System.out.println(result.wasSuccessful());
|
||||
}
|
||||
}
|
98
src/test/java/org/json/junit/Util.java
Normal file
98
src/test/java/org/json/junit/Util.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.json.*;
|
||||
|
||||
/**
|
||||
* These are helpful utility methods that perform basic comparisons
|
||||
* between various objects. In most cases, the comparisons are not
|
||||
* order-dependent, or else the order is known.
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
/**
|
||||
* Compares two JSONArrays for equality.
|
||||
* The arrays need not be in the same order.
|
||||
* @param jsonArray created by the code to be tested
|
||||
* @param expectedJsonArray created specifically for comparing
|
||||
*/
|
||||
public static void compareActualVsExpectedJsonArrays(JSONArray jsonArray,
|
||||
JSONArray expectedJsonArray) {
|
||||
assertTrue("jsonArray lengths should be equal",
|
||||
jsonArray.length() == expectedJsonArray.length());
|
||||
for (int i = 0; i < jsonArray.length(); ++i) {
|
||||
Object value = jsonArray.get(i);
|
||||
Object expectedValue = expectedJsonArray.get(i);
|
||||
compareActualVsExpectedObjects(value, expectedValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two JSONObjects for equality. The objects need not be
|
||||
* in the same order
|
||||
* @param jsonObject created by the code to be tested
|
||||
* @param expectedJsonObject created specifically for comparing
|
||||
*/
|
||||
public static void compareActualVsExpectedJsonObjects(
|
||||
JSONObject jsonObject, JSONObject expectedJsonObject) {
|
||||
assertTrue("jsonObjects should have the same length",
|
||||
jsonObject.length() == expectedJsonObject.length());
|
||||
Iterator<String> keys = jsonObject.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
Object value = jsonObject.get(key);
|
||||
Object expectedValue = expectedJsonObject.get(key);
|
||||
compareActualVsExpectedObjects(value, expectedValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two objects for equality. Might be JSONArray, JSONObject,
|
||||
* 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) {
|
||||
if (value instanceof JSONObject && expectedValue instanceof JSONObject) {
|
||||
// Compare JSONObjects
|
||||
JSONObject jsonObject = (JSONObject)value;
|
||||
JSONObject expectedJsonObject = (JSONObject)expectedValue;
|
||||
compareActualVsExpectedJsonObjects(
|
||||
jsonObject, expectedJsonObject);
|
||||
} else if (value instanceof JSONArray && expectedValue instanceof JSONArray) {
|
||||
// Compare JSONArrays
|
||||
JSONArray jsonArray = (JSONArray)value;
|
||||
JSONArray expectedJsonArray = (JSONArray)expectedValue;
|
||||
compareActualVsExpectedJsonArrays(
|
||||
jsonArray, expectedJsonArray);
|
||||
} else {
|
||||
/**
|
||||
* Compare all other types using toString(). First, the types must
|
||||
* also be equal, unless both are Number type. Certain helper
|
||||
* classes (e.g. XML) may create Long instead of Integer for small
|
||||
* int values.
|
||||
*/
|
||||
if (!(value instanceof Number && expectedValue instanceof Number)) {
|
||||
// Non-Number and non-matching types
|
||||
assertTrue("object types should be equal for actual: "+
|
||||
value.toString()+" ("+
|
||||
value.getClass().toString()+") expected: "+
|
||||
expectedValue.toString()+" ("+
|
||||
expectedValue.getClass().toString()+")",
|
||||
value.getClass().toString().equals(
|
||||
expectedValue.getClass().toString()));
|
||||
}
|
||||
/**
|
||||
* Same types or both Numbers, compare by toString()
|
||||
*/
|
||||
assertTrue("string values should be equal for actual: "+
|
||||
value.toString()+" expected: "+expectedValue.toString(),
|
||||
value.toString().equals(expectedValue.toString()));
|
||||
}
|
||||
}
|
||||
}
|
930
src/test/java/org/json/junit/XMLConfigurationTest.java
Executable file
930
src/test/java/org/json/junit/XMLConfigurationTest.java
Executable file
|
@ -0,0 +1,930 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.XML;
|
||||
import org.json.XMLParserConfiguration;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for JSON-Java XML.java with XMLParserConfiguration.java
|
||||
*/
|
||||
public class XMLConfigurationTest {
|
||||
/**
|
||||
* JUnit supports temporary files and folders that are cleaned up after the test.
|
||||
* https://garygregory.wordpress.com/2010/01/20/junit-tip-use-rules-to-manage-temporary-files-and-folders/
|
||||
*/
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
/**
|
||||
* JSONObject from a null XML string.
|
||||
* Expects a NullPointerException
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void shouldHandleNullXML() {
|
||||
String xmlStr = null;
|
||||
JSONObject jsonObject =
|
||||
XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSONObject from an empty XML string.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyXML() {
|
||||
|
||||
String xmlStr = "";
|
||||
JSONObject jsonObject =
|
||||
XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSONObject from a non-XML string.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNonXML() {
|
||||
String xmlStr = "{ \"this is\": \"not xml\"}";
|
||||
JSONObject jsonObject =
|
||||
XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertTrue("xml string should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string (tag contains a frontslash).
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidSlashInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/x>\n"+
|
||||
" <street>abc street</street>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped tag at 176 [character 14 line 4]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string ('!' char in tag)
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidBangInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <!>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped meta tag at 214 [character 12 line 7]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string ('!' char and no closing tag brace)
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidBangNoCloseInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <!\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped meta tag at 213 [character 12 line 7]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string (no end brace for tag)
|
||||
* Expects JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNoCloseStartTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <abc\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr, XMLParserConfiguration.KEEP_STRINGS);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misplaced '<' at 193 [character 4 line 6]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string (partial CDATA chars in tag name)
|
||||
* Expects JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidCDATABangInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name>Joe Tester</name>\n"+
|
||||
" <![[]>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XMLParserConfiguration config =
|
||||
new XMLParserConfiguration("altContent");
|
||||
XML.toJSONObject(xmlStr, config);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Expected 'CDATA[' at 204 [character 11 line 5]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Null JSONObject in XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNullJSONXML() {
|
||||
JSONObject jsonObject= null;
|
||||
String actualXml = XML.toString(jsonObject, null,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("generated XML does not equal expected XML","\"null\"",actualXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSONObject in XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyJSONXML() {
|
||||
JSONObject jsonObject= new JSONObject();
|
||||
String xmlStr = XML.toString(jsonObject, null,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertTrue("xml string should be empty", xmlStr.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* No SML start tag. The ending tag ends up being treated as content.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNoStartTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <nocontent/>>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+
|
||||
"content\":\">\"},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid XML to JSONObject
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleSimpleXML() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name>Joe Tester</name>\n"+
|
||||
" <street>[CDATA[Baker street 5]</street>\n"+
|
||||
" <NothingHere/>\n"+
|
||||
" <TrueValue>true</TrueValue>\n"+
|
||||
" <FalseValue>false</FalseValue>\n"+
|
||||
" <NullValue>null</NullValue>\n"+
|
||||
" <PositiveValue>42</PositiveValue>\n"+
|
||||
" <NegativeValue>-23</NegativeValue>\n"+
|
||||
" <DoubleValue>-23.45</DoubleValue>\n"+
|
||||
" <Nan>-23x.45</Nan>\n"+
|
||||
" <ArrayOfNum>1, 2, 3, 4.1, 5.2</ArrayOfNum>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"street\":\"[CDATA[Baker street 5]\","+
|
||||
"\"name\":\"Joe Tester\",\"NothingHere\":\"\",TrueValue:true,\n"+
|
||||
"\"FalseValue\":false,\"NullValue\":null,\"PositiveValue\":42,\n"+
|
||||
"\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":-23x.45,\n"+
|
||||
"\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+
|
||||
"},\"xsi:noNamespaceSchemaLocation\":"+
|
||||
"\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+
|
||||
"XMLSchema-instance\"}}";
|
||||
|
||||
XMLParserConfiguration config =
|
||||
new XMLParserConfiguration("altContent");
|
||||
compareStringToJSONObject(xmlStr, expectedStr, config);
|
||||
compareReaderToJSONObject(xmlStr, expectedStr, config);
|
||||
compareFileToJSONObject(xmlStr, expectedStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid XML with comments to JSONObject
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleCommentsInXML() {
|
||||
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<!-- this is a comment -->\n"+
|
||||
"<addresses>\n"+
|
||||
" <address>\n"+
|
||||
" <![CDATA[ this is -- <another> comment ]]>\n"+
|
||||
" <name>Joe Tester</name>\n"+
|
||||
" <!-- this is a - multi line \n"+
|
||||
" comment -->\n"+
|
||||
" <street>Baker street 5</street>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
XMLParserConfiguration config =
|
||||
new XMLParserConfiguration("altContent");
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr, config);
|
||||
String expectedStr = "{\"addresses\":{\"address\":{\"street\":\"Baker "+
|
||||
"street 5\",\"name\":\"Joe Tester\",\"altContent\":\" this is -- "+
|
||||
"<another> comment \"}}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid XML to XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleToString() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name>[CDATA[Joe & T > e < s " t ' er]]</name>\n"+
|
||||
" <street>Baker street 5</street>\n"+
|
||||
" <ArrayOfNum>1, 2, 3, 4.1, 5.2</ArrayOfNum>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"street\":\"Baker street 5\","+
|
||||
"\"name\":\"[CDATA[Joe & T > e < s \\\" t \\\' er]]\","+
|
||||
"\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+
|
||||
"},\"xsi:noNamespaceSchemaLocation\":"+
|
||||
"\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+
|
||||
"XMLSchema-instance\"}}";
|
||||
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
String xmlToStr = XML.toString(jsonObject, null,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
JSONObject finalJsonObject = XML.toJSONObject(xmlToStr,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing '>' content to JSONObject, then
|
||||
* XML.toString() should result in valid XML.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleContentNoArraytoString() {
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+
|
||||
"altContent\":\">\"},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
XMLParserConfiguration config = new XMLParserConfiguration("altContent");
|
||||
String finalStr = XML.toString(expectedJsonObject, null, config);
|
||||
String expectedFinalStr = "<addresses><address><name/><nocontent/>>"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+
|
||||
finalStr+"]", expectedFinalStr.equals(finalStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing a 'content' array to JSONObject, then
|
||||
* XML.toString() should result in valid XML.
|
||||
* TODO: This is probably an error in how the 'content' keyword is used.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleContentArraytoString() {
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+
|
||||
"altContent\":[1, 2, 3]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
XMLParserConfiguration config = new XMLParserConfiguration("altContent");
|
||||
String finalStr = XML.toString(expectedJsonObject, null, config);
|
||||
String expectedFinalStr = "<addresses><address><name/><nocontent/>"+
|
||||
"1\n2\n3"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+
|
||||
finalStr+"]", expectedFinalStr.equals(finalStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing a named array to JSONObject, then
|
||||
* XML.toString() should result in valid XML.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleArraytoString() {
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\","+
|
||||
"\"something\":[1, 2, 3]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
String finalStr = XML.toString(expectedJsonObject, null,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
String expectedFinalStr = "<addresses><address><name/><nocontent/>"+
|
||||
"<something>1</something><something>2</something><something>3</something>"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+
|
||||
finalStr+"]", expectedFinalStr.equals(finalStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for empty arrays is consistent.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("array",new Object[]{});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("array",new JSONArray());
|
||||
|
||||
final String expected = "<jo></jo>";
|
||||
String output1 = XML.toString(jo1, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("Expected an empty root tag", expected, output1);
|
||||
String output2 = XML.toString(jo2, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("Expected an empty root tag", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for arrays is consistent when an internal array is empty.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyMultiArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("arr",new Object[]{"One", new String[]{}, "Four"});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("arr",new JSONArray(new Object[]{"One", new JSONArray(new String[]{}), "Four"}));
|
||||
|
||||
final String expected = "<jo><arr>One</arr><arr></arr><arr>Four</arr></jo>";
|
||||
String output1 = XML.toString(jo1, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("Expected a matching array", expected, output1);
|
||||
String output2 = XML.toString(jo2, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
|
||||
assertEquals("Expected a matching array", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for arrays is consistent when arrays are not empty.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNonEmptyArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("arr",new String[]{"One", "Two", "Three"});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("arr",new JSONArray(new String[]{"One", "Two", "Three"}));
|
||||
|
||||
final String expected = "<jo><arr>One</arr><arr>Two</arr><arr>Three</arr></jo>";
|
||||
String output1 = XML.toString(jo1, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("Expected a non empty root tag", expected, output1);
|
||||
String output2 = XML.toString(jo2, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("Expected a non empty root tag", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for arrays is consistent when arrays are not empty and contain internal arrays.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleMultiArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("arr",new Object[]{"One", new String[]{"Two", "Three"}, "Four"});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("arr",new JSONArray(new Object[]{"One", new JSONArray(new String[]{"Two", "Three"}), "Four"}));
|
||||
|
||||
final String expected = "<jo><arr>One</arr><arr><array>Two</array><array>Three</array></arr><arr>Four</arr></jo>";
|
||||
String output1 = XML.toString(jo1, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("Expected a matching array", expected, output1);
|
||||
String output2 = XML.toString(jo2, "jo",
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals("Expected a matching array", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing a named array of nested arrays to
|
||||
* JSONObject, then XML.toString() should result in valid XML.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNestedArraytoString() {
|
||||
String xmlStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\","+
|
||||
"\"outer\":[[1], [2], [3]]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject jsonObject = new JSONObject(xmlStr);
|
||||
String finalStr = XML.toString(jsonObject, null,
|
||||
XMLParserConfiguration.ORIGINAL);
|
||||
JSONObject finalJsonObject = XML.toJSONObject(finalStr);
|
||||
String expectedStr = "<addresses><address><name/><nocontent/>"+
|
||||
"<outer><array>1</array></outer><outer><array>2</array>"+
|
||||
"</outer><outer><array>3</array></outer>"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
JSONObject expectedJsonObject = XML.toJSONObject(expectedStr,
|
||||
XMLParserConfiguration.ORIGINAL);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Possible bug:
|
||||
* Illegal node-names must be converted to legal XML-node-names.
|
||||
* The given example shows 2 nodes which are valid for JSON, but not for XML.
|
||||
* Therefore illegal arguments should be converted to e.g. an underscore (_).
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleIllegalJSONNodeNames()
|
||||
{
|
||||
JSONObject inputJSON = new JSONObject();
|
||||
inputJSON.append("123IllegalNode", "someValue1");
|
||||
inputJSON.append("Illegal@node", "someValue2");
|
||||
|
||||
String result = XML.toString(inputJSON, null,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
|
||||
/*
|
||||
* This is invalid XML. Names should not begin with digits or contain
|
||||
* certain values, including '@'. One possible solution is to replace
|
||||
* illegal chars with '_', in which case the expected output would be:
|
||||
* <___IllegalNode>someValue1</___IllegalNode><Illegal_node>someValue2</Illegal_node>
|
||||
*/
|
||||
String expected = "<123IllegalNode>someValue1</123IllegalNode><Illegal@node>someValue2</Illegal@node>";
|
||||
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSONObject with NULL value, to XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNullNodeValue()
|
||||
{
|
||||
JSONObject inputJSON = new JSONObject();
|
||||
inputJSON.put("nullValue", JSONObject.NULL);
|
||||
// This is a possible preferred result
|
||||
// String expectedXML = "<nullValue/>";
|
||||
/**
|
||||
* This is the current behavior. JSONObject.NULL is emitted as
|
||||
* the string, "null".
|
||||
*/
|
||||
String actualXML = "<nullValue>null</nullValue>";
|
||||
String resultXML = XML.toString(inputJSON, null,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertEquals(actualXML, resultXML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Investigate exactly how the "content" keyword works
|
||||
*/
|
||||
@Test
|
||||
public void contentOperations() {
|
||||
/*
|
||||
* When a standalone <!CDATA[...]] structure is found while parsing XML into a
|
||||
* JSONObject, the contents are placed in a string value with key="content".
|
||||
*/
|
||||
String xmlStr = "<tag1></tag1><![CDATA[if (a < b && a > 0) then return]]><tag2></tag2>";
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
assertTrue("1. 3 items", 3 == jsonObject.length());
|
||||
assertTrue("1. empty tag1", "".equals(jsonObject.get("tag1")));
|
||||
assertTrue("1. empty tag2", "".equals(jsonObject.get("tag2")));
|
||||
assertTrue("1. content found", "if (a < b && a > 0) then return".equals(jsonObject.get("content")));
|
||||
|
||||
// multiple consecutive standalone cdatas are accumulated into an array
|
||||
xmlStr = "<tag1></tag1><![CDATA[if (a < b && a > 0) then return]]><tag2></tag2><![CDATA[here is another cdata]]>";
|
||||
jsonObject = XML.toJSONObject(xmlStr,
|
||||
new XMLParserConfiguration(true, "altContent"));
|
||||
assertTrue("2. 3 items", 3 == jsonObject.length());
|
||||
assertTrue("2. empty tag1", "".equals(jsonObject.get("tag1")));
|
||||
assertTrue("2. empty tag2", "".equals(jsonObject.get("tag2")));
|
||||
assertTrue("2. content array found", jsonObject.get("altContent") instanceof JSONArray);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("altContent");
|
||||
assertTrue("2. array size", jsonArray.length() == 2);
|
||||
assertTrue("2. content array entry 0", "if (a < b && a > 0) then return".equals(jsonArray.get(0)));
|
||||
assertTrue("2. content array entry 1", "here is another cdata".equals(jsonArray.get(1)));
|
||||
|
||||
/*
|
||||
* text content is accumulated in a "content" inside a local JSONObject.
|
||||
* If there is only one instance, it is saved in the context (a different JSONObject
|
||||
* from the calling code. and the content element is discarded.
|
||||
*/
|
||||
xmlStr = "<tag1>value 1</tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr,
|
||||
new XMLParserConfiguration(true, "altContent"));
|
||||
assertTrue("3. 2 items", 1 == jsonObject.length());
|
||||
assertTrue("3. value tag1", "value 1".equals(jsonObject.get("tag1")));
|
||||
|
||||
/*
|
||||
* array-style text content (multiple tags with the same name) is
|
||||
* accumulated in a local JSONObject with key="content" and value=JSONArray,
|
||||
* saved in the context, and then the local JSONObject is discarded.
|
||||
*/
|
||||
xmlStr = "<tag1>value 1</tag1><tag1>2</tag1><tag1>true</tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr,
|
||||
new XMLParserConfiguration(true, "altContent"));
|
||||
assertTrue("4. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("4. content array found", jsonObject.get("tag1") instanceof JSONArray);
|
||||
jsonArray = jsonObject.getJSONArray("tag1");
|
||||
assertTrue("4. array size", jsonArray.length() == 3);
|
||||
assertTrue("4. content array entry 0", "value 1".equals(jsonArray.get(0)));
|
||||
assertTrue("4. content array entry 1", jsonArray.getInt(1) == 2);
|
||||
assertTrue("4. content array entry 2", jsonArray.getBoolean(2) == true);
|
||||
|
||||
/*
|
||||
* Complex content is accumulated in a "content" field. For example, an element
|
||||
* may contain a mix of child elements and text. Each text segment is
|
||||
* accumulated to content.
|
||||
*/
|
||||
xmlStr = "<tag1>val1<tag2/>val2</tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr,
|
||||
new XMLParserConfiguration(true, "altContent"));
|
||||
assertTrue("5. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("5. jsonObject found", jsonObject.get("tag1")
|
||||
instanceof JSONObject);
|
||||
jsonObject = jsonObject.getJSONObject("tag1");
|
||||
assertTrue("5. 2 contained items", 2 == jsonObject.length());
|
||||
assertTrue("5. contained tag", "".equals(jsonObject.get("tag2")));
|
||||
assertTrue("5. contained content jsonArray found",
|
||||
jsonObject.get("altContent") instanceof JSONArray);
|
||||
jsonArray = jsonObject.getJSONArray("altContent");
|
||||
assertTrue("5. array size", jsonArray.length() == 2);
|
||||
assertTrue("5. content array entry 0", "val1".equals(jsonArray.get(0)));
|
||||
assertTrue("5. content array entry 1", "val2".equals(jsonArray.get(1)));
|
||||
|
||||
/*
|
||||
* If there is only 1 complex text content, then it is accumulated in a
|
||||
* "content" field as a string.
|
||||
*/
|
||||
xmlStr = "<tag1>val1<tag2/></tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr,
|
||||
new XMLParserConfiguration(true, "altContent"));
|
||||
assertTrue("6. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("6. jsonObject found", jsonObject.get("tag1") instanceof JSONObject);
|
||||
jsonObject = jsonObject.getJSONObject("tag1");
|
||||
assertTrue("6. contained content found",
|
||||
"val1".equals(jsonObject.get("altContent")));
|
||||
assertTrue("6. contained tag2", "".equals(jsonObject.get("tag2")));
|
||||
|
||||
/*
|
||||
* In this corner case, the content sibling happens to have key=content
|
||||
* We end up with an array within an array, and no content element.
|
||||
* This is probably a bug.
|
||||
*/
|
||||
xmlStr = "<tag1>val1<altContent/></tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr,
|
||||
new XMLParserConfiguration(true, "altContent"));
|
||||
assertTrue("7. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("7. jsonArray found",
|
||||
jsonObject.get("tag1") instanceof JSONArray);
|
||||
jsonArray = jsonObject.getJSONArray("tag1");
|
||||
assertTrue("array size 1", jsonArray.length() == 1);
|
||||
assertTrue("7. contained array found", jsonArray.get(0)
|
||||
instanceof JSONArray);
|
||||
jsonArray = jsonArray.getJSONArray(0);
|
||||
assertTrue("7. inner array size 2", jsonArray.length() == 2);
|
||||
assertTrue("7. inner array item 0", "val1".equals(jsonArray.get(0)));
|
||||
assertTrue("7. inner array item 1", "".equals(jsonArray.get(1)));
|
||||
|
||||
/*
|
||||
* Confirm behavior of original issue
|
||||
*/
|
||||
String jsonStr =
|
||||
"{"+
|
||||
"\"Profile\": {"+
|
||||
"\"list\": {"+
|
||||
"\"history\": {"+
|
||||
"\"entries\": ["+
|
||||
"{"+
|
||||
"\"deviceId\": \"id\","+
|
||||
"\"altContent\": {"+
|
||||
"\"material\": ["+
|
||||
"{"+
|
||||
"\"stuff\": false"+
|
||||
"}"+
|
||||
"]"+
|
||||
"}"+
|
||||
"}"+
|
||||
"]"+
|
||||
"}"+
|
||||
"}"+
|
||||
"}"+
|
||||
"}";
|
||||
jsonObject = new JSONObject(jsonStr);
|
||||
xmlStr = XML.toString(jsonObject, null,
|
||||
new XMLParserConfiguration(true, "altContent"));
|
||||
/*
|
||||
* This is the created XML. Looks like content was mistaken for
|
||||
* complex (child node + text) XML.
|
||||
* <Profile>
|
||||
* <list>
|
||||
* <history>
|
||||
* <entries>
|
||||
* <deviceId>id</deviceId>
|
||||
* {"material":[{"stuff":false}]}
|
||||
* </entries>
|
||||
* </history>
|
||||
* </list>
|
||||
* </Profile>
|
||||
*/
|
||||
assertTrue("nothing to test here, see comment on created XML, above", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string lost leading zero and converted "True" to true.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_jsonOutput() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}";
|
||||
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml,
|
||||
new XMLParserConfiguration(false));
|
||||
assertEquals(expectedJsonString, actualJsonOutput.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string cannot be reverted to original xml.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_reversibility() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
XMLParserConfiguration config = new XMLParserConfiguration(false);
|
||||
final String revertedXml =
|
||||
XML.toString(XML.toJSONObject(originalXml, config),
|
||||
null, config);
|
||||
assertNotEquals(revertedXml, originalXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* test passes when using the new method toJsonArray.
|
||||
*/
|
||||
@Test
|
||||
public void testToJsonXML() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",\"1\",\"00\",\"0\"],\"title\":\"True\"}}";
|
||||
|
||||
final JSONObject json = XML.toJSONObject(originalXml,
|
||||
new XMLParserConfiguration(true));
|
||||
assertEquals(expectedJsonString, json.toString());
|
||||
|
||||
final String reverseXml = XML.toString(json);
|
||||
// this reversal isn't exactly the same. use JSONML for an exact reversal
|
||||
final String expectedReverseXml = "<root><item><id>01</id></item><id>01</id><id>1</id><id>00</id><id>0</id><title>True</title></root>";
|
||||
|
||||
assertEquals(expectedReverseXml, reverseXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* test to validate certain conditions of XML unescaping.
|
||||
*/
|
||||
@Test
|
||||
public void testUnescape() {
|
||||
assertEquals("{\"xml\":\"Can cope <;\"}",
|
||||
XML.toJSONObject("<xml>Can cope <; </xml>",
|
||||
XMLParserConfiguration.KEEP_STRINGS).toString());
|
||||
assertEquals("Can cope <; ", XML.unescape("Can cope <; "));
|
||||
|
||||
assertEquals("{\"xml\":\"Can cope & ;\"}",
|
||||
XML.toJSONObject("<xml>Can cope & ; </xml>",
|
||||
XMLParserConfiguration.KEEP_STRINGS).toString());
|
||||
assertEquals("Can cope & ; ", XML.unescape("Can cope & ; "));
|
||||
|
||||
assertEquals("{\"xml\":\"Can cope &;\"}",
|
||||
XML.toJSONObject("<xml>Can cope &; </xml>",
|
||||
XMLParserConfiguration.KEEP_STRINGS).toString());
|
||||
assertEquals("Can cope &; ", XML.unescape("Can cope &; "));
|
||||
|
||||
// unicode entity
|
||||
assertEquals("{\"xml\":\"Can cope 4;\"}",
|
||||
XML.toJSONObject("<xml>Can cope 4; </xml>",
|
||||
XMLParserConfiguration.KEEP_STRINGS).toString());
|
||||
assertEquals("Can cope 4; ", XML.unescape("Can cope 4; "));
|
||||
|
||||
// double escaped
|
||||
assertEquals("{\"xml\":\"Can cope <\"}",
|
||||
XML.toJSONObject("<xml>Can cope &lt; </xml>",
|
||||
XMLParserConfiguration.KEEP_STRINGS).toString());
|
||||
assertEquals("Can cope < ", XML.unescape("Can cope &lt; "));
|
||||
|
||||
assertEquals("{\"xml\":\"Can cope 4\"}",
|
||||
XML.toJSONObject("<xml>Can cope &#x34; </xml>",
|
||||
XMLParserConfiguration.KEEP_STRINGS).toString());
|
||||
assertEquals("Can cope 4 ", XML.unescape("Can cope &#x34; "));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm XMLParserConfiguration functionality
|
||||
*/
|
||||
@Test
|
||||
public void testConfig() {
|
||||
/**
|
||||
* 1st param is whether to keep the raw string, or call
|
||||
* XML.stringToValue(), which may convert the token to
|
||||
* boolean, null, or number.
|
||||
* 2nd param is what JSON name to use for strings that are
|
||||
* evaluated as xml content data in complex objects, e.g.
|
||||
* <parent>
|
||||
* <child>value</child>
|
||||
* content data
|
||||
* </tag>
|
||||
*/
|
||||
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" content 1\n"+
|
||||
" <name>Sherlock Holmes</name>\n"+
|
||||
" content 2\n"+
|
||||
" <street>Baker street 5</street>\n"+
|
||||
" content 3\n"+
|
||||
" <num>1</num>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
|
||||
// keep strings, use the altContent tag
|
||||
XMLParserConfiguration config =
|
||||
new XMLParserConfiguration(true, "altContent");
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr, config);
|
||||
// num is parsed as a string
|
||||
assertEquals(jsonObject.getJSONObject("addresses").
|
||||
getJSONObject("address").getString("num"), "1");
|
||||
// complex content is collected in an 'altContent' array
|
||||
JSONArray jsonArray = jsonObject.getJSONObject("addresses").
|
||||
getJSONObject("address").getJSONArray("altContent");
|
||||
String expectedStr = "[\"content 1\", \"content 2\", \"content 3\"]";
|
||||
JSONArray expectedJsonArray = new JSONArray(expectedStr);
|
||||
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
|
||||
// keepstrings only
|
||||
jsonObject = XML.toJSONObject(xmlStr,
|
||||
XMLParserConfiguration.KEEP_STRINGS);
|
||||
// num is parsed as a string
|
||||
assertEquals(jsonObject.getJSONObject("addresses").
|
||||
getJSONObject("address").getString("num"), "1");
|
||||
// complex content is collected in an 'content' array
|
||||
jsonArray = jsonObject.getJSONObject("addresses").
|
||||
getJSONObject("address").getJSONArray("content");
|
||||
expectedJsonArray = new JSONArray(expectedStr);
|
||||
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
|
||||
// use alternate content name
|
||||
config = new XMLParserConfiguration("altContent");
|
||||
jsonObject = XML.toJSONObject(xmlStr, config);
|
||||
// num is parsed as a number
|
||||
assertEquals(jsonObject.getJSONObject("addresses").
|
||||
getJSONObject("address").getInt("num"), 1);
|
||||
// complex content is collected in an 'altContent' array
|
||||
jsonArray = jsonObject.getJSONObject("addresses").
|
||||
getJSONObject("address").getJSONArray("altContent");
|
||||
expectedJsonArray = new JSONArray(expectedStr);
|
||||
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method, given an input string and expected result,
|
||||
* convert to JSONObject and compare actual to expected result.
|
||||
* @param xmlStr the string to parse
|
||||
* @param expectedStr the expected JSON string
|
||||
* @param config provides more flexible XML parsing
|
||||
* flexible XML parsing.
|
||||
*/
|
||||
private void compareStringToJSONObject(String xmlStr, String expectedStr,
|
||||
XMLParserConfiguration config) {
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr, config);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method, given an input string and expected result,
|
||||
* convert to JSONObject via reader and compare actual to expected result.
|
||||
* @param xmlStr the string to parse
|
||||
* @param expectedStr the expected JSON string
|
||||
* @param config provides more flexible XML parsing
|
||||
*/
|
||||
private void compareReaderToJSONObject(String xmlStr, String expectedStr,
|
||||
XMLParserConfiguration config) {
|
||||
/*
|
||||
* Commenting out this method until the JSON-java code is updated
|
||||
* to support XML.toJSONObject(reader)
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Reader reader = new StringReader(xmlStr);
|
||||
JSONObject jsonObject = XML.toJSONObject(reader);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method, given an input string and expected result, convert to
|
||||
* JSONObject via file and compare actual to expected result.
|
||||
*
|
||||
* @param xmlStr
|
||||
* the string to parse
|
||||
* @param expectedStr
|
||||
* the expected JSON string
|
||||
* @throws IOException
|
||||
*/
|
||||
private void compareFileToJSONObject(String xmlStr, String expectedStr) {
|
||||
/*
|
||||
* Commenting out this method until the JSON-java code is updated
|
||||
* to support XML.toJSONObject(reader)
|
||||
try {
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
File tempFile = testFolder.newFile("fileToJSONObject.xml");
|
||||
FileWriter fileWriter = new FileWriter(tempFile);
|
||||
fileWriter.write(xmlStr);
|
||||
fileWriter.close();
|
||||
Reader reader = new FileReader(tempFile);
|
||||
JSONObject jsonObject = XML.toJSONObject(reader);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
} catch (IOException e) {
|
||||
assertTrue("file writer error: " +e.getMessage(), false);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
883
src/test/java/org/json/junit/XMLTest.java
Normal file
883
src/test/java/org/json/junit/XMLTest.java
Normal file
|
@ -0,0 +1,883 @@
|
|||
package org.json.junit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.XML;
|
||||
import org.json.XMLParserConfiguration;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for JSON-Java XML.java
|
||||
* Note: noSpace() will be tested by JSONMLTest
|
||||
*/
|
||||
public class XMLTest {
|
||||
/**
|
||||
* JUnit supports temporary files and folders that are cleaned up after the test.
|
||||
* https://garygregory.wordpress.com/2010/01/20/junit-tip-use-rules-to-manage-temporary-files-and-folders/
|
||||
*/
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
/**
|
||||
* JSONObject from a null XML string.
|
||||
* Expects a NullPointerException
|
||||
*/
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void shouldHandleNullXML() {
|
||||
String xmlStr = null;
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSONObject from an empty XML string.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyXML() {
|
||||
|
||||
String xmlStr = "";
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSONObject from a non-XML string.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNonXML() {
|
||||
String xmlStr = "{ \"this is\": \"not xml\"}";
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("xml string should be empty", jsonObject.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string (tag contains a frontslash).
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidSlashInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/x>\n"+
|
||||
" <street>abc street</street>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped tag at 176 [character 14 line 4]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string ('!' char in tag)
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidBangInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <!>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped meta tag at 214 [character 12 line 7]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string ('!' char and no closing tag brace)
|
||||
* Expects a JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidBangNoCloseInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <!\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misshaped meta tag at 213 [character 12 line 7]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string (no end brace for tag)
|
||||
* Expects JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNoCloseStartTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <abc\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Misplaced '<' at 193 [character 4 line 6]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid XML string (partial CDATA chars in tag name)
|
||||
* Expects JSONException
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleInvalidCDATABangInTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name>Joe Tester</name>\n"+
|
||||
" <![[]>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
try {
|
||||
XML.toJSONObject(xmlStr);
|
||||
fail("Expecting a JSONException");
|
||||
} catch (JSONException e) {
|
||||
assertEquals("Expecting an exception message",
|
||||
"Expected 'CDATA[' at 204 [character 11 line 5]",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Null JSONObject in XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNullJSONXML() {
|
||||
JSONObject jsonObject= null;
|
||||
String actualXml=XML.toString(jsonObject);
|
||||
assertEquals("generated XML does not equal expected XML","\"null\"",actualXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSONObject in XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyJSONXML() {
|
||||
JSONObject jsonObject= new JSONObject();
|
||||
String xmlStr = XML.toString(jsonObject);
|
||||
assertTrue("xml string should be empty", xmlStr.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* No SML start tag. The ending tag ends up being treated as content.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNoStartTag() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name/>\n"+
|
||||
" <nocontent/>>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+
|
||||
"content\":\">\"},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid XML to JSONObject
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleSimpleXML() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name>Joe Tester</name>\n"+
|
||||
" <street>[CDATA[Baker street 5]</street>\n"+
|
||||
" <NothingHere/>\n"+
|
||||
" <TrueValue>true</TrueValue>\n"+
|
||||
" <FalseValue>false</FalseValue>\n"+
|
||||
" <NullValue>null</NullValue>\n"+
|
||||
" <PositiveValue>42</PositiveValue>\n"+
|
||||
" <NegativeValue>-23</NegativeValue>\n"+
|
||||
" <DoubleValue>-23.45</DoubleValue>\n"+
|
||||
" <Nan>-23x.45</Nan>\n"+
|
||||
" <ArrayOfNum>1, 2, 3, 4.1, 5.2</ArrayOfNum>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"street\":\"[CDATA[Baker street 5]\","+
|
||||
"\"name\":\"Joe Tester\",\"NothingHere\":\"\",TrueValue:true,\n"+
|
||||
"\"FalseValue\":false,\"NullValue\":null,\"PositiveValue\":42,\n"+
|
||||
"\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":-23x.45,\n"+
|
||||
"\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+
|
||||
"},\"xsi:noNamespaceSchemaLocation\":"+
|
||||
"\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+
|
||||
"XMLSchema-instance\"}}";
|
||||
|
||||
compareStringToJSONObject(xmlStr, expectedStr);
|
||||
compareReaderToJSONObject(xmlStr, expectedStr);
|
||||
compareFileToJSONObject(xmlStr, expectedStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to verify that supported escapes in XML are converted to actual values.
|
||||
*/
|
||||
@Test
|
||||
public void testXmlEscapeToJson(){
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<root>"+
|
||||
"<rawQuote>\"</rawQuote>"+
|
||||
"<euro>A €33</euro>"+
|
||||
"<euroX>A €22€</euroX>"+
|
||||
"<unknown>some text ©</unknown>"+
|
||||
"<known>" " & ' < ></known>"+
|
||||
"<high>𝄢 𐅥</high>" +
|
||||
"</root>";
|
||||
String expectedStr =
|
||||
"{\"root\":{" +
|
||||
"\"rawQuote\":\"\\\"\"," +
|
||||
"\"euro\":\"A €33\"," +
|
||||
"\"euroX\":\"A €22€\"," +
|
||||
"\"unknown\":\"some text ©\"," +
|
||||
"\"known\":\"\\\" \\\" & ' < >\"," +
|
||||
"\"high\":\"𝄢 𐅥\""+
|
||||
"}}";
|
||||
|
||||
compareStringToJSONObject(xmlStr, expectedStr);
|
||||
compareReaderToJSONObject(xmlStr, expectedStr);
|
||||
compareFileToJSONObject(xmlStr, expectedStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that control characters are escaped.
|
||||
*/
|
||||
@Test
|
||||
public void testJsonToXmlEscape(){
|
||||
final String jsonSrc = "{\"amount\":\"10,00 €\","
|
||||
+ "\"description\":\"Ação Válida\u0085\","
|
||||
+ "\"xmlEntities\":\"\\\" ' & < >\""
|
||||
+ "}";
|
||||
JSONObject json = new JSONObject(jsonSrc);
|
||||
String xml = XML.toString(json);
|
||||
//test control character not existing
|
||||
assertFalse("Escaping \u0085 failed. Found in XML output.", xml.contains("\u0085"));
|
||||
assertTrue("Escaping \u0085 failed. Entity not found in XML output.", xml.contains("…"));
|
||||
// test normal unicode existing
|
||||
assertTrue("Escaping € failed. Not found in XML output.", xml.contains("€"));
|
||||
assertTrue("Escaping ç failed. Not found in XML output.", xml.contains("ç"));
|
||||
assertTrue("Escaping ã failed. Not found in XML output.", xml.contains("ã"));
|
||||
assertTrue("Escaping á failed. Not found in XML output.", xml.contains("á"));
|
||||
// test XML Entities converted
|
||||
assertTrue("Escaping \" failed. Not found in XML output.", xml.contains("""));
|
||||
assertTrue("Escaping ' failed. Not found in XML output.", xml.contains("'"));
|
||||
assertTrue("Escaping & failed. Not found in XML output.", xml.contains("&"));
|
||||
assertTrue("Escaping < failed. Not found in XML output.", xml.contains("<"));
|
||||
assertTrue("Escaping > failed. Not found in XML output.", xml.contains(">"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid XML with comments to JSONObject
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleCommentsInXML() {
|
||||
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<!-- this is a comment -->\n"+
|
||||
"<addresses>\n"+
|
||||
" <address>\n"+
|
||||
" <![CDATA[ this is -- <another> comment ]]>\n"+
|
||||
" <name>Joe Tester</name>\n"+
|
||||
" <!-- this is a - multi line \n"+
|
||||
" comment -->\n"+
|
||||
" <street>Baker street 5</street>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
String expectedStr = "{\"addresses\":{\"address\":{\"street\":\"Baker "+
|
||||
"street 5\",\"name\":\"Joe Tester\",\"content\":\" this is -- "+
|
||||
"<another> comment \"}}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid XML to XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleToString() {
|
||||
String xmlStr =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
|
||||
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
|
||||
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
|
||||
" <address>\n"+
|
||||
" <name>[CDATA[Joe & T > e < s " t ' er]]</name>\n"+
|
||||
" <street>Baker street 5</street>\n"+
|
||||
" <ArrayOfNum>1, 2, 3, 4.1, 5.2</ArrayOfNum>\n"+
|
||||
" </address>\n"+
|
||||
"</addresses>";
|
||||
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"street\":\"Baker street 5\","+
|
||||
"\"name\":\"[CDATA[Joe & T > e < s \\\" t \\\' er]]\","+
|
||||
"\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+
|
||||
"},\"xsi:noNamespaceSchemaLocation\":"+
|
||||
"\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+
|
||||
"XMLSchema-instance\"}}";
|
||||
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
String xmlToStr = XML.toString(jsonObject);
|
||||
JSONObject finalJsonObject = XML.toJSONObject(xmlToStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing '>' content to JSONObject, then
|
||||
* XML.toString() should result in valid XML.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleContentNoArraytoString() {
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+
|
||||
"content\":\">\"},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
String finalStr = XML.toString(expectedJsonObject);
|
||||
String expectedFinalStr = "<addresses><address><name/><nocontent/>>"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+
|
||||
finalStr+"]", expectedFinalStr.equals(finalStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing a 'content' array to JSONObject, then
|
||||
* XML.toString() should result in valid XML.
|
||||
* TODO: This is probably an error in how the 'content' keyword is used.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleContentArraytoString() {
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\",\""+
|
||||
"content\":[1, 2, 3]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
String finalStr = XML.toString(expectedJsonObject);
|
||||
String expectedFinalStr = "<addresses><address><name/><nocontent/>"+
|
||||
"1\n2\n3"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+
|
||||
finalStr+"]", expectedFinalStr.equals(finalStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing a named array to JSONObject, then
|
||||
* XML.toString() should result in valid XML.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleArraytoString() {
|
||||
String expectedStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\","+
|
||||
"\"something\":[1, 2, 3]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
String finalStr = XML.toString(expectedJsonObject);
|
||||
String expectedFinalStr = "<addresses><address><name/><nocontent/>"+
|
||||
"<something>1</something><something>2</something><something>3</something>"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
assertTrue("Should handle expectedFinal: ["+expectedStr+"] final: ["+
|
||||
finalStr+"]", expectedFinalStr.equals(finalStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for empty arrays is consistent.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("array",new Object[]{});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("array",new JSONArray());
|
||||
|
||||
final String expected = "<jo></jo>";
|
||||
String output1 = XML.toString(jo1,"jo");
|
||||
assertEquals("Expected an empty root tag", expected, output1);
|
||||
String output2 = XML.toString(jo2,"jo");
|
||||
assertEquals("Expected an empty root tag", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for arrays is consistent when an internal array is empty.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleEmptyMultiArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("arr",new Object[]{"One", new String[]{}, "Four"});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("arr",new JSONArray(new Object[]{"One", new JSONArray(new String[]{}), "Four"}));
|
||||
|
||||
final String expected = "<jo><arr>One</arr><arr></arr><arr>Four</arr></jo>";
|
||||
String output1 = XML.toString(jo1,"jo");
|
||||
assertEquals("Expected a matching array", expected, output1);
|
||||
String output2 = XML.toString(jo2,"jo");
|
||||
assertEquals("Expected a matching array", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for arrays is consistent when arrays are not empty.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNonEmptyArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("arr",new String[]{"One", "Two", "Three"});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("arr",new JSONArray(new String[]{"One", "Two", "Three"}));
|
||||
|
||||
final String expected = "<jo><arr>One</arr><arr>Two</arr><arr>Three</arr></jo>";
|
||||
String output1 = XML.toString(jo1,"jo");
|
||||
assertEquals("Expected a non empty root tag", expected, output1);
|
||||
String output2 = XML.toString(jo2,"jo");
|
||||
assertEquals("Expected a non empty root tag", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the XML output for arrays is consistent when arrays are not empty and contain internal arrays.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleMultiArray(){
|
||||
final JSONObject jo1 = new JSONObject();
|
||||
jo1.put("arr",new Object[]{"One", new String[]{"Two", "Three"}, "Four"});
|
||||
final JSONObject jo2 = new JSONObject();
|
||||
jo2.put("arr",new JSONArray(new Object[]{"One", new JSONArray(new String[]{"Two", "Three"}), "Four"}));
|
||||
|
||||
final String expected = "<jo><arr>One</arr><arr><array>Two</array><array>Three</array></arr><arr>Four</arr></jo>";
|
||||
String output1 = XML.toString(jo1,"jo");
|
||||
assertEquals("Expected a matching array", expected, output1);
|
||||
String output2 = XML.toString(jo2,"jo");
|
||||
assertEquals("Expected a matching array", expected, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting a JSON doc containing a named array of nested arrays to
|
||||
* JSONObject, then XML.toString() should result in valid XML.
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNestedArraytoString() {
|
||||
String xmlStr =
|
||||
"{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\","+
|
||||
"\"outer\":[[1], [2], [3]]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
|
||||
"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";
|
||||
JSONObject jsonObject = new JSONObject(xmlStr);
|
||||
String finalStr = XML.toString(jsonObject);
|
||||
JSONObject finalJsonObject = XML.toJSONObject(finalStr);
|
||||
String expectedStr = "<addresses><address><name/><nocontent/>"+
|
||||
"<outer><array>1</array></outer><outer><array>2</array>"+
|
||||
"</outer><outer><array>3</array></outer>"+
|
||||
"</address><xsi:noNamespaceSchemaLocation>test.xsd</xsi:noName"+
|
||||
"spaceSchemaLocation><xmlns:xsi>http://www.w3.org/2001/XMLSche"+
|
||||
"ma-instance</xmlns:xsi></addresses>";
|
||||
JSONObject expectedJsonObject = XML.toJSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Possible bug:
|
||||
* Illegal node-names must be converted to legal XML-node-names.
|
||||
* The given example shows 2 nodes which are valid for JSON, but not for XML.
|
||||
* Therefore illegal arguments should be converted to e.g. an underscore (_).
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleIllegalJSONNodeNames()
|
||||
{
|
||||
JSONObject inputJSON = new JSONObject();
|
||||
inputJSON.append("123IllegalNode", "someValue1");
|
||||
inputJSON.append("Illegal@node", "someValue2");
|
||||
|
||||
String result = XML.toString(inputJSON);
|
||||
|
||||
/*
|
||||
* This is invalid XML. Names should not begin with digits or contain
|
||||
* certain values, including '@'. One possible solution is to replace
|
||||
* illegal chars with '_', in which case the expected output would be:
|
||||
* <___IllegalNode>someValue1</___IllegalNode><Illegal_node>someValue2</Illegal_node>
|
||||
*/
|
||||
String expected = "<123IllegalNode>someValue1</123IllegalNode><Illegal@node>someValue2</Illegal@node>";
|
||||
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSONObject with NULL value, to XML.toString()
|
||||
*/
|
||||
@Test
|
||||
public void shouldHandleNullNodeValue()
|
||||
{
|
||||
JSONObject inputJSON = new JSONObject();
|
||||
inputJSON.put("nullValue", JSONObject.NULL);
|
||||
// This is a possible preferred result
|
||||
// String expectedXML = "<nullValue/>";
|
||||
/**
|
||||
* This is the current behavior. JSONObject.NULL is emitted as
|
||||
* the string, "null".
|
||||
*/
|
||||
String actualXML = "<nullValue>null</nullValue>";
|
||||
String resultXML = XML.toString(inputJSON);
|
||||
assertEquals(actualXML, resultXML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Investigate exactly how the "content" keyword works
|
||||
*/
|
||||
@Test
|
||||
public void contentOperations() {
|
||||
/*
|
||||
* When a standalone <!CDATA[...]] structure is found while parsing XML into a
|
||||
* JSONObject, the contents are placed in a string value with key="content".
|
||||
*/
|
||||
String xmlStr = "<tag1></tag1><![CDATA[if (a < b && a > 0) then return]]><tag2></tag2>";
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("1. 3 items", 3 == jsonObject.length());
|
||||
assertTrue("1. empty tag1", "".equals(jsonObject.get("tag1")));
|
||||
assertTrue("1. empty tag2", "".equals(jsonObject.get("tag2")));
|
||||
assertTrue("1. content found", "if (a < b && a > 0) then return".equals(jsonObject.get("content")));
|
||||
|
||||
// multiple consecutive standalone cdatas are accumulated into an array
|
||||
xmlStr = "<tag1></tag1><![CDATA[if (a < b && a > 0) then return]]><tag2></tag2><![CDATA[here is another cdata]]>";
|
||||
jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("2. 3 items", 3 == jsonObject.length());
|
||||
assertTrue("2. empty tag1", "".equals(jsonObject.get("tag1")));
|
||||
assertTrue("2. empty tag2", "".equals(jsonObject.get("tag2")));
|
||||
assertTrue("2. content array found", jsonObject.get("content") instanceof JSONArray);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("content");
|
||||
assertTrue("2. array size", jsonArray.length() == 2);
|
||||
assertTrue("2. content array entry 0", "if (a < b && a > 0) then return".equals(jsonArray.get(0)));
|
||||
assertTrue("2. content array entry 1", "here is another cdata".equals(jsonArray.get(1)));
|
||||
|
||||
/*
|
||||
* text content is accumulated in a "content" inside a local JSONObject.
|
||||
* If there is only one instance, it is saved in the context (a different JSONObject
|
||||
* from the calling code. and the content element is discarded.
|
||||
*/
|
||||
xmlStr = "<tag1>value 1</tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("3. 2 items", 1 == jsonObject.length());
|
||||
assertTrue("3. value tag1", "value 1".equals(jsonObject.get("tag1")));
|
||||
|
||||
/*
|
||||
* array-style text content (multiple tags with the same name) is
|
||||
* accumulated in a local JSONObject with key="content" and value=JSONArray,
|
||||
* saved in the context, and then the local JSONObject is discarded.
|
||||
*/
|
||||
xmlStr = "<tag1>value 1</tag1><tag1>2</tag1><tag1>true</tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("4. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("4. content array found", jsonObject.get("tag1") instanceof JSONArray);
|
||||
jsonArray = jsonObject.getJSONArray("tag1");
|
||||
assertTrue("4. array size", jsonArray.length() == 3);
|
||||
assertTrue("4. content array entry 0", "value 1".equals(jsonArray.get(0)));
|
||||
assertTrue("4. content array entry 1", jsonArray.getInt(1) == 2);
|
||||
assertTrue("4. content array entry 2", jsonArray.getBoolean(2) == true);
|
||||
|
||||
/*
|
||||
* Complex content is accumulated in a "content" field. For example, an element
|
||||
* may contain a mix of child elements and text. Each text segment is
|
||||
* accumulated to content.
|
||||
*/
|
||||
xmlStr = "<tag1>val1<tag2/>val2</tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("5. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("5. jsonObject found", jsonObject.get("tag1") instanceof JSONObject);
|
||||
jsonObject = jsonObject.getJSONObject("tag1");
|
||||
assertTrue("5. 2 contained items", 2 == jsonObject.length());
|
||||
assertTrue("5. contained tag", "".equals(jsonObject.get("tag2")));
|
||||
assertTrue("5. contained content jsonArray found", jsonObject.get("content") instanceof JSONArray);
|
||||
jsonArray = jsonObject.getJSONArray("content");
|
||||
assertTrue("5. array size", jsonArray.length() == 2);
|
||||
assertTrue("5. content array entry 0", "val1".equals(jsonArray.get(0)));
|
||||
assertTrue("5. content array entry 1", "val2".equals(jsonArray.get(1)));
|
||||
|
||||
/*
|
||||
* If there is only 1 complex text content, then it is accumulated in a
|
||||
* "content" field as a string.
|
||||
*/
|
||||
xmlStr = "<tag1>val1<tag2/></tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("6. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("6. jsonObject found", jsonObject.get("tag1") instanceof JSONObject);
|
||||
jsonObject = jsonObject.getJSONObject("tag1");
|
||||
assertTrue("6. contained content found", "val1".equals(jsonObject.get("content")));
|
||||
assertTrue("6. contained tag2", "".equals(jsonObject.get("tag2")));
|
||||
|
||||
/*
|
||||
* In this corner case, the content sibling happens to have key=content
|
||||
* We end up with an array within an array, and no content element.
|
||||
* This is probably a bug.
|
||||
*/
|
||||
xmlStr = "<tag1>val1<content/></tag1>";
|
||||
jsonObject = XML.toJSONObject(xmlStr);
|
||||
assertTrue("7. 1 item", 1 == jsonObject.length());
|
||||
assertTrue("7. jsonArray found", jsonObject.get("tag1") instanceof JSONArray);
|
||||
jsonArray = jsonObject.getJSONArray("tag1");
|
||||
assertTrue("array size 1", jsonArray.length() == 1);
|
||||
assertTrue("7. contained array found", jsonArray.get(0) instanceof JSONArray);
|
||||
jsonArray = jsonArray.getJSONArray(0);
|
||||
assertTrue("7. inner array size 2", jsonArray.length() == 2);
|
||||
assertTrue("7. inner array item 0", "val1".equals(jsonArray.get(0)));
|
||||
assertTrue("7. inner array item 1", "".equals(jsonArray.get(1)));
|
||||
|
||||
/*
|
||||
* Confirm behavior of original issue
|
||||
*/
|
||||
String jsonStr =
|
||||
"{"+
|
||||
"\"Profile\": {"+
|
||||
"\"list\": {"+
|
||||
"\"history\": {"+
|
||||
"\"entries\": ["+
|
||||
"{"+
|
||||
"\"deviceId\": \"id\","+
|
||||
"\"content\": {"+
|
||||
"\"material\": ["+
|
||||
"{"+
|
||||
"\"stuff\": false"+
|
||||
"}"+
|
||||
"]"+
|
||||
"}"+
|
||||
"}"+
|
||||
"]"+
|
||||
"}"+
|
||||
"}"+
|
||||
"}"+
|
||||
"}";
|
||||
jsonObject = new JSONObject(jsonStr);
|
||||
xmlStr = XML.toString(jsonObject);
|
||||
/*
|
||||
* This is the created XML. Looks like content was mistaken for
|
||||
* complex (child node + text) XML.
|
||||
* <Profile>
|
||||
* <list>
|
||||
* <history>
|
||||
* <entries>
|
||||
* <deviceId>id</deviceId>
|
||||
* {"material":[{"stuff":false}]}
|
||||
* </entries>
|
||||
* </history>
|
||||
* </list>
|
||||
* </Profile>
|
||||
*/
|
||||
assertTrue("nothing to test here, see comment on created XML, above", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method, given an input string and expected result,
|
||||
* convert to JSONObject and compare actual to expected result.
|
||||
* @param xmlStr the string to parse
|
||||
* @param expectedStr the expected JSON string
|
||||
*/
|
||||
private void compareStringToJSONObject(String xmlStr, String expectedStr) {
|
||||
JSONObject jsonObject = XML.toJSONObject(xmlStr);
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method, given an input string and expected result,
|
||||
* convert to JSONObject via reader and compare actual to expected result.
|
||||
* @param xmlStr the string to parse
|
||||
* @param expectedStr the expected JSON string
|
||||
*/
|
||||
private void compareReaderToJSONObject(String xmlStr, String expectedStr) {
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
Reader reader = new StringReader(xmlStr);
|
||||
JSONObject jsonObject = XML.toJSONObject(reader);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method, given an input string and expected result, convert to
|
||||
* JSONObject via file and compare actual to expected result.
|
||||
*
|
||||
* @param xmlStr
|
||||
* the string to parse
|
||||
* @param expectedStr
|
||||
* the expected JSON string
|
||||
* @throws IOException
|
||||
*/
|
||||
private void compareFileToJSONObject(String xmlStr, String expectedStr) {
|
||||
try {
|
||||
JSONObject expectedJsonObject = new JSONObject(expectedStr);
|
||||
File tempFile = this.testFolder.newFile("fileToJSONObject.xml");
|
||||
try(FileWriter fileWriter = new FileWriter(tempFile);){
|
||||
fileWriter.write(xmlStr);
|
||||
}
|
||||
try(Reader reader = new FileReader(tempFile);){
|
||||
JSONObject jsonObject = XML.toJSONObject(reader);
|
||||
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
fail("file writer error: " +e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string lost leading zero and converted "True" to true.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_jsonOutput() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}";
|
||||
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml, false);
|
||||
|
||||
assertEquals(expectedJsonString, actualJsonOutput.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON string cannot be reverted to original xml.
|
||||
*/
|
||||
@Test
|
||||
public void testToJSONArray_reversibility() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
final String revertedXml = XML.toString(XML.toJSONObject(originalXml, false));
|
||||
|
||||
assertNotEquals(revertedXml, originalXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* test passes when using the new method toJsonArray.
|
||||
*/
|
||||
@Test
|
||||
public void testToJsonXML() {
|
||||
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",\"1\",\"00\",\"0\"],\"title\":\"True\"}}";
|
||||
|
||||
final JSONObject json = XML.toJSONObject(originalXml,true);
|
||||
assertEquals(expectedJsonString, json.toString());
|
||||
|
||||
final String reverseXml = XML.toString(json);
|
||||
// this reversal isn't exactly the same. use JSONML for an exact reversal
|
||||
final String expectedReverseXml = "<root><item><id>01</id></item><id>01</id><id>1</id><id>00</id><id>0</id><title>True</title></root>";
|
||||
|
||||
assertEquals(expectedReverseXml, reverseXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* test to validate certain conditions of XML unescaping.
|
||||
*/
|
||||
@Test
|
||||
public void testUnescape() {
|
||||
assertEquals("{\"xml\":\"Can cope <;\"}",
|
||||
XML.toJSONObject("<xml>Can cope <; </xml>").toString());
|
||||
assertEquals("Can cope <; ", XML.unescape("Can cope <; "));
|
||||
|
||||
assertEquals("{\"xml\":\"Can cope & ;\"}",
|
||||
XML.toJSONObject("<xml>Can cope & ; </xml>").toString());
|
||||
assertEquals("Can cope & ; ", XML.unescape("Can cope & ; "));
|
||||
|
||||
assertEquals("{\"xml\":\"Can cope &;\"}",
|
||||
XML.toJSONObject("<xml>Can cope &; </xml>").toString());
|
||||
assertEquals("Can cope &; ", XML.unescape("Can cope &; "));
|
||||
|
||||
// unicode entity
|
||||
assertEquals("{\"xml\":\"Can cope 4;\"}",
|
||||
XML.toJSONObject("<xml>Can cope 4; </xml>").toString());
|
||||
assertEquals("Can cope 4; ", XML.unescape("Can cope 4; "));
|
||||
|
||||
// double escaped
|
||||
assertEquals("{\"xml\":\"Can cope <\"}",
|
||||
XML.toJSONObject("<xml>Can cope &lt; </xml>").toString());
|
||||
assertEquals("Can cope < ", XML.unescape("Can cope &lt; "));
|
||||
|
||||
assertEquals("{\"xml\":\"Can cope 4\"}",
|
||||
XML.toJSONObject("<xml>Can cope &#x34; </xml>").toString());
|
||||
assertEquals("Can cope 4 ", XML.unescape("Can cope &#x34; "));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* test passes when xsi:nil="true" converting to null (JSON specification-like nil conversion enabled)
|
||||
*/
|
||||
@Test
|
||||
public void testToJsonWithNullWhenNilConversionEnabled() {
|
||||
final String originalXml = "<root><id xsi:nil=\"true\"/></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"id\":null}}";
|
||||
|
||||
final JSONObject json = XML.toJSONObject(originalXml, new XMLParserConfiguration(false, "content", true));
|
||||
assertEquals(expectedJsonString, json.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* test passes when xsi:nil="true" not converting to null (JSON specification-like nil conversion disabled)
|
||||
*/
|
||||
@Test
|
||||
public void testToJsonWithNullWhenNilConversionDisabled() {
|
||||
final String originalXml = "<root><id xsi:nil=\"true\"/></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"id\":{\"xsi:nil\":true}}}";
|
||||
|
||||
final JSONObject json = XML.toJSONObject(originalXml, new XMLParserConfiguration());
|
||||
assertEquals(expectedJsonString, json.toString());
|
||||
}
|
||||
}
|
13
src/test/java/org/json/junit/data/BrokenToString.java
Normal file
13
src/test/java/org/json/junit/data/BrokenToString.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* test class for verifying write errors.
|
||||
* @author John Aylward
|
||||
*
|
||||
*/
|
||||
public class BrokenToString {
|
||||
@Override
|
||||
public String toString() {
|
||||
throw new IllegalStateException("Something went horribly wrong!");
|
||||
}
|
||||
}
|
69
src/test/java/org/json/junit/data/ExceptionalBean.java
Normal file
69
src/test/java/org/json/junit/data/ExceptionalBean.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.json.junit.data;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Object for testing the exception handling in {@link JSONObject#populateMap}.
|
||||
*
|
||||
* @author John Aylward
|
||||
*/
|
||||
public class ExceptionalBean {
|
||||
/**
|
||||
* @return a closeable.
|
||||
*/
|
||||
public Closeable getCloseable() {
|
||||
// anonymous inner class did not work...
|
||||
return new MyCloseable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Nothing really. Just can't be void.
|
||||
* @throws IllegalAccessException
|
||||
* always thrown
|
||||
*/
|
||||
public int getIllegalAccessException() throws IllegalAccessException {
|
||||
throw new IllegalAccessException("Yup, it's illegal");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Nothing really. Just can't be void.
|
||||
* @throws IllegalArgumentException
|
||||
* always thrown
|
||||
*/
|
||||
public int getIllegalArgumentException() throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException("Yup, it's illegal");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Nothing really. Just can't be void.
|
||||
* @throws InvocationTargetException
|
||||
* always thrown
|
||||
*/
|
||||
public int getInvocationTargetException() throws InvocationTargetException {
|
||||
throw new InvocationTargetException(new Exception("Yup, it's illegal"));
|
||||
}
|
||||
|
||||
/** My closeable class. */
|
||||
public static final class MyCloseable implements Closeable {
|
||||
|
||||
/**
|
||||
* @return a string
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public String getString() {
|
||||
return "Yup, it's closeable";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
throw new IOException("Closing is too hard!");
|
||||
}
|
||||
}
|
||||
}
|
180
src/test/java/org/json/junit/data/Fraction.java
Normal file
180
src/test/java/org/json/junit/data/Fraction.java
Normal file
|
@ -0,0 +1,180 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* basic fraction class, no frills.
|
||||
* @author John Aylward
|
||||
*
|
||||
*/
|
||||
public class Fraction extends Number implements Comparable<Fraction> {
|
||||
/**
|
||||
* serial id.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* value as a big decimal.
|
||||
*/
|
||||
private final BigDecimal bigDecimal;
|
||||
|
||||
/**
|
||||
* value of the denominator.
|
||||
*/
|
||||
private final BigInteger denominator;
|
||||
/**
|
||||
* value of the numerator.
|
||||
*/
|
||||
private final BigInteger numerator;
|
||||
|
||||
/**
|
||||
* @param numerator
|
||||
* numerator
|
||||
* @param denominator
|
||||
* denominator
|
||||
*/
|
||||
public Fraction(final BigInteger numerator, final BigInteger denominator) {
|
||||
super();
|
||||
if (numerator == null || denominator == null) {
|
||||
throw new IllegalArgumentException("All values must be non-null");
|
||||
}
|
||||
if (denominator.compareTo(BigInteger.ZERO)==0) {
|
||||
throw new IllegalArgumentException("Divide by zero");
|
||||
}
|
||||
|
||||
final BigInteger n;
|
||||
final BigInteger d;
|
||||
// normalize fraction
|
||||
if (denominator.signum()<0) {
|
||||
n = numerator.negate();
|
||||
d = denominator.negate();
|
||||
} else {
|
||||
n = numerator;
|
||||
d = denominator;
|
||||
}
|
||||
this.numerator = n;
|
||||
this.denominator = d;
|
||||
if (n.compareTo(BigInteger.ZERO)==0) {
|
||||
this.bigDecimal = BigDecimal.ZERO;
|
||||
} else if (n.compareTo(d)==0) {// i.e. 4/4, 10/10
|
||||
this.bigDecimal = BigDecimal.ONE;
|
||||
} else {
|
||||
this.bigDecimal = new BigDecimal(this.numerator).divide(new BigDecimal(this.denominator),
|
||||
RoundingMode.HALF_EVEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numerator
|
||||
* numerator
|
||||
* @param denominator
|
||||
* denominator
|
||||
*/
|
||||
public Fraction(final long numerator, final long denominator) {
|
||||
this(BigInteger.valueOf(numerator),BigInteger.valueOf(denominator));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the decimal
|
||||
*/
|
||||
public BigDecimal bigDecimalValue() {
|
||||
return this.bigDecimal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Fraction o) {
|
||||
// .equals call this, so no .equals compare allowed
|
||||
|
||||
// if they are the same reference, just return equals
|
||||
if (this == o) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if my denominators are already equal, just compare the numerators
|
||||
if (this.denominator.compareTo(o.denominator)==0) {
|
||||
return this.numerator.compareTo(o.numerator);
|
||||
}
|
||||
|
||||
// get numerators of common denominators
|
||||
// a x ay xb
|
||||
// --- --- = ---- ----
|
||||
// b y by yb
|
||||
final BigInteger thisN = this.numerator.multiply(o.denominator);
|
||||
final BigInteger otherN = o.numerator.multiply(this.denominator);
|
||||
|
||||
return thisN.compareTo(otherN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return this.bigDecimal.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Fraction other = (Fraction) obj;
|
||||
return this.compareTo(other) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return this.bigDecimal.floatValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the denominator
|
||||
*/
|
||||
public BigInteger getDenominator() {
|
||||
return this.denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the numerator
|
||||
*/
|
||||
public BigInteger getNumerator() {
|
||||
return this.numerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (this.bigDecimal == null ? 0 : this.bigDecimal.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return this.bigDecimal.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return this.bigDecimal.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.numerator + "/" + this.denominator;
|
||||
}
|
||||
}
|
79
src/test/java/org/json/junit/data/GenericBean.java
Normal file
79
src/test/java/org/json/junit/data/GenericBean.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Aylward
|
||||
*
|
||||
* @param <T>
|
||||
* generic number value
|
||||
*/
|
||||
public class GenericBean<T extends Number & Comparable<T>> implements MyBean {
|
||||
/**
|
||||
* @param genericValue
|
||||
* value to initiate with
|
||||
*/
|
||||
public GenericBean(T genericValue) {
|
||||
super();
|
||||
this.genericValue = genericValue;
|
||||
}
|
||||
|
||||
/** */
|
||||
protected T genericValue;
|
||||
/** to be used by the calling test to see how often the getter is called */
|
||||
public int genericGetCounter;
|
||||
/** to be used by the calling test to see how often the setter is called */
|
||||
public int genericSetCounter;
|
||||
|
||||
/** @return the genericValue */
|
||||
public T getGenericValue() {
|
||||
this.genericGetCounter++;
|
||||
return this.genericValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param genericValue
|
||||
* generic value to set
|
||||
*/
|
||||
public void setGenericValue(T genericValue) {
|
||||
this.genericSetCounter++;
|
||||
this.genericValue = genericValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIntKey() {
|
||||
return Integer.valueOf(42);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDoubleKey() {
|
||||
return Double.valueOf(4.2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringKey() {
|
||||
return "MyString Key";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEscapeStringKey() {
|
||||
return "\"My String with \"s";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isTrueKey() {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isFalseKey() {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringReader getStringReaderKey() {
|
||||
return new StringReader("Some String Value in a reader");
|
||||
}
|
||||
|
||||
}
|
69
src/test/java/org/json/junit/data/GenericBeanInt.java
Normal file
69
src/test/java/org/json/junit/data/GenericBeanInt.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* @author john
|
||||
*
|
||||
*/
|
||||
public class GenericBeanInt extends GenericBean<Integer> {
|
||||
/** */
|
||||
final char a = 'A';
|
||||
|
||||
/** @return the a */
|
||||
public char getA() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should not be beanable
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean getable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should not be beanable
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean get() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should not be beanable
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean is() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be beanable
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean isB() {
|
||||
return this.genericValue.equals((Integer.valueOf(this.a+1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param genericValue
|
||||
* the value to initiate with.
|
||||
*/
|
||||
public GenericBeanInt(Integer genericValue) {
|
||||
super(genericValue);
|
||||
}
|
||||
|
||||
/** override to generate a bridge method */
|
||||
@Override
|
||||
public Integer getGenericValue() {
|
||||
return super.getGenericValue();
|
||||
}
|
||||
|
||||
}
|
16
src/test/java/org/json/junit/data/MyBean.java
Normal file
16
src/test/java/org/json/junit/data/MyBean.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Used in testing when Bean behavior is needed
|
||||
*/
|
||||
public interface MyBean {
|
||||
public Integer getIntKey();
|
||||
public Double getDoubleKey();
|
||||
public String getStringKey();
|
||||
public String getEscapeStringKey();
|
||||
public Boolean isTrueKey();
|
||||
public Boolean isFalseKey();
|
||||
public StringReader getStringReaderKey();
|
||||
}
|
20
src/test/java/org/json/junit/data/MyBeanCustomName.java
Normal file
20
src/test/java/org/json/junit/data/MyBeanCustomName.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import org.json.JSONPropertyName;
|
||||
|
||||
/**
|
||||
* Test bean for the {@link JSONPropertyName} annotation.
|
||||
*/
|
||||
public class MyBeanCustomName implements MyBeanCustomNameInterface {
|
||||
public int getSomeInt() { return 42; }
|
||||
@JSONPropertyName("")
|
||||
public long getSomeLong() { return 42L; }
|
||||
@JSONPropertyName("myStringField")
|
||||
public String getSomeString() { return "someStringValue"; }
|
||||
@JSONPropertyName("Some Weird NAme that Normally Wouldn't be possible!")
|
||||
public double getMyDouble() { return 0.0d; }
|
||||
@Override
|
||||
public float getSomeFloat() { return 2.0f; }
|
||||
@Override
|
||||
public int getIgnoredInt() { return 40; }
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import org.json.JSONPropertyIgnore;
|
||||
import org.json.JSONPropertyName;
|
||||
|
||||
public interface MyBeanCustomNameInterface {
|
||||
@JSONPropertyName("InterfaceField")
|
||||
float getSomeFloat();
|
||||
@JSONPropertyIgnore
|
||||
int getIgnoredInt();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.json.junit.data;
|
||||
|
||||
import org.json.JSONPropertyIgnore;
|
||||
import org.json.JSONPropertyName;
|
||||
|
||||
/**
|
||||
* Test bean to verify that the {@link org.json.JSONPropertyName} annotation
|
||||
* is inherited.
|
||||
*/
|
||||
public class MyBeanCustomNameSubClass extends MyBeanCustomName {
|
||||
@Override
|
||||
@JSONPropertyName("forcedInt")
|
||||
public int getIgnoredInt() { return 42*42; }
|
||||
@Override
|
||||
@JSONPropertyName("newIntFieldName")
|
||||
public int getSomeInt() { return 43; }
|
||||
@Override
|
||||
public String getSomeString() { return "subClassString"; }
|
||||
@Override
|
||||
@JSONPropertyName("AMoreNormalName")
|
||||
public double getMyDouble() { return 1.0d; }
|
||||
@Override
|
||||
public float getSomeFloat() { return 3.0f; }
|
||||
@JSONPropertyIgnore
|
||||
@JSONPropertyName("ShouldBeIgnored")
|
||||
public boolean getShouldNotBeJSON() { return true; }
|
||||
@JSONPropertyName("Getable")
|
||||
public boolean getable() { return true; }
|
||||
}
|
11
src/test/java/org/json/junit/data/MyBigNumberBean.java
Normal file
11
src/test/java/org/json/junit/data/MyBigNumberBean.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* Used in testing when a Bean containing big numbers is needed
|
||||
*/
|
||||
public interface MyBigNumberBean {
|
||||
public BigInteger getBigInteger();
|
||||
public BigDecimal getBigDecimal();
|
||||
}
|
10
src/test/java/org/json/junit/data/MyEnum.java
Normal file
10
src/test/java/org/json/junit/data/MyEnum.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* An enum with no methods or data
|
||||
*/
|
||||
public enum MyEnum {
|
||||
VAL1,
|
||||
VAL2,
|
||||
VAL3;
|
||||
}
|
22
src/test/java/org/json/junit/data/MyEnumClass.java
Normal file
22
src/test/java/org/json/junit/data/MyEnumClass.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* this is simply a class that contains some enum instances
|
||||
*/
|
||||
public class MyEnumClass {
|
||||
private MyEnum myEnum;
|
||||
private MyEnumField myEnumField;
|
||||
|
||||
public MyEnum getMyEnum() {
|
||||
return myEnum;
|
||||
}
|
||||
public void setMyEnum(MyEnum myEnum) {
|
||||
this.myEnum = myEnum;
|
||||
}
|
||||
public MyEnumField getMyEnumField() {
|
||||
return myEnumField;
|
||||
}
|
||||
public void setMyEnumField(MyEnumField myEnumField) {
|
||||
this.myEnumField = myEnumField;
|
||||
}
|
||||
}
|
28
src/test/java/org/json/junit/data/MyEnumField.java
Normal file
28
src/test/java/org/json/junit/data/MyEnumField.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* An enum that contains getters and some internal fields
|
||||
*/
|
||||
@SuppressWarnings("boxing")
|
||||
public enum MyEnumField {
|
||||
VAL1(1, "val 1"),
|
||||
VAL2(2, "val 2"),
|
||||
VAL3(3, "val 3");
|
||||
|
||||
private String value;
|
||||
private Integer intVal;
|
||||
private MyEnumField(Integer intVal, String value) {
|
||||
this.value = value;
|
||||
this.intVal = intVal;
|
||||
}
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
public Integer getIntVal() {
|
||||
return this.intVal;
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return this.value;
|
||||
}
|
||||
}
|
14
src/test/java/org/json/junit/data/MyJsonString.java
Normal file
14
src/test/java/org/json/junit/data/MyJsonString.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import org.json.*;
|
||||
|
||||
/**
|
||||
* Used in testing when a JSONString is needed
|
||||
*/
|
||||
public class MyJsonString implements JSONString {
|
||||
|
||||
@Override
|
||||
public String toJSONString() {
|
||||
return "my string";
|
||||
}
|
||||
}
|
12
src/test/java/org/json/junit/data/MyLocaleBean.java
Executable file
12
src/test/java/org/json/junit/data/MyLocaleBean.java
Executable file
|
@ -0,0 +1,12 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
public class MyLocaleBean {
|
||||
private final String id = "beanId";
|
||||
private final String i = "beanI";
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public String getI() {
|
||||
return i;
|
||||
}
|
||||
}
|
97
src/test/java/org/json/junit/data/MyNumber.java
Normal file
97
src/test/java/org/json/junit/data/MyNumber.java
Normal file
|
@ -0,0 +1,97 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Number override for testing. Number overrides should always override
|
||||
* toString, hashCode, and Equals.
|
||||
*
|
||||
* @see <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/java/data/numberclasses.html">The
|
||||
* Numbers Classes</a>
|
||||
* @see <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/java/data/numberformat.html">Formatting
|
||||
* Numeric Print Output</a>
|
||||
*
|
||||
* @author John Aylward
|
||||
*/
|
||||
public class MyNumber extends Number {
|
||||
private Number number = BigDecimal.valueOf(42);
|
||||
/**
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* @return number!
|
||||
*/
|
||||
public Number getNumber() {
|
||||
return this.number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return getNumber().intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return getNumber().longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return getNumber().floatValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return getNumber().doubleValue();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*
|
||||
* Number overrides should in general always override the toString method.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return getNumber().toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.number == null) ? 0 : this.number.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof MyNumber)) {
|
||||
return false;
|
||||
}
|
||||
MyNumber other = (MyNumber) obj;
|
||||
if (this.number == null) {
|
||||
if (other.number != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.number.equals(other.number)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
13
src/test/java/org/json/junit/data/MyNumberContainer.java
Normal file
13
src/test/java/org/json/junit/data/MyNumberContainer.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* Class that holds our MyNumber override as a property.
|
||||
* @author John Aylward
|
||||
*/
|
||||
public class MyNumberContainer {
|
||||
private MyNumber myNumber = new MyNumber();
|
||||
/**
|
||||
* @return a MyNumber.
|
||||
*/
|
||||
public Number getMyNumber() {return this.myNumber;}
|
||||
}
|
10
src/test/java/org/json/junit/data/MyPublicClass.java
Normal file
10
src/test/java/org/json/junit/data/MyPublicClass.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* Need a class with some public data members for testing
|
||||
*/
|
||||
@SuppressWarnings("boxing")
|
||||
public class MyPublicClass {
|
||||
public Integer publicInt = 42;
|
||||
public String publicString = "abc";
|
||||
}
|
91
src/test/java/org/json/junit/data/Singleton.java
Normal file
91
src/test/java/org/json/junit/data/Singleton.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* Sample singleton for use with bean testing.
|
||||
*
|
||||
* @author John Aylward
|
||||
*
|
||||
*/
|
||||
public final class Singleton {
|
||||
/** */
|
||||
private int someInt;
|
||||
/** */
|
||||
private String someString;
|
||||
/** single instance. */
|
||||
private static final Singleton INSTANCE = new Singleton();
|
||||
|
||||
/** @return the singleton instance. */
|
||||
public static final Singleton getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/** */
|
||||
private Singleton() {
|
||||
if (INSTANCE != null) {
|
||||
throw new IllegalStateException("Already instantiated");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/** @return someInt */
|
||||
public int getSomeInt() {
|
||||
return someInt;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets someInt.
|
||||
*
|
||||
* @param someInt
|
||||
* the someInt to set
|
||||
*/
|
||||
public void setSomeInt(int someInt) {
|
||||
this.someInt = someInt;
|
||||
}
|
||||
|
||||
/** @return someString */
|
||||
public String getSomeString() {
|
||||
return someString;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets someString.
|
||||
*
|
||||
* @param someString
|
||||
* the someString to set
|
||||
*/
|
||||
public void setSomeString(String someString) {
|
||||
this.someString = someString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + someInt;
|
||||
result = prime * result + ((someString == null) ? 0 : someString.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Singleton other = (Singleton) obj;
|
||||
if (someInt != other.someInt)
|
||||
return false;
|
||||
if (someString == null) {
|
||||
if (other.someString != null)
|
||||
return false;
|
||||
} else if (!someString.equals(other.someString))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
62
src/test/java/org/json/junit/data/SingletonEnum.java
Normal file
62
src/test/java/org/json/junit/data/SingletonEnum.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
/**
|
||||
* Sample singleton done as an Enum for use with bean testing.
|
||||
*
|
||||
* @author John Aylward
|
||||
*
|
||||
*/
|
||||
public enum SingletonEnum {
|
||||
/**
|
||||
* the singleton instance.
|
||||
*/
|
||||
INSTANCE;
|
||||
/** */
|
||||
private int someInt;
|
||||
/** */
|
||||
private String someString;
|
||||
|
||||
/** single instance. */
|
||||
|
||||
/**
|
||||
* @return the singleton instance. I a real application, I'd hope no one did
|
||||
* this to an enum singleton.
|
||||
*/
|
||||
public static final SingletonEnum getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/** */
|
||||
private SingletonEnum() {
|
||||
}
|
||||
|
||||
/** @return someInt */
|
||||
public int getSomeInt() {
|
||||
return someInt;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets someInt.
|
||||
*
|
||||
* @param someInt
|
||||
* the someInt to set
|
||||
*/
|
||||
public void setSomeInt(int someInt) {
|
||||
this.someInt = someInt;
|
||||
}
|
||||
|
||||
/** @return someString */
|
||||
public String getSomeString() {
|
||||
return someString;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets someString.
|
||||
*
|
||||
* @param someString
|
||||
* the someString to set
|
||||
*/
|
||||
public void setSomeString(String someString) {
|
||||
this.someString = someString;
|
||||
}
|
||||
}
|
19
src/test/java/org/json/junit/data/StringsResourceBundle.java
Normal file
19
src/test/java/org/json/junit/data/StringsResourceBundle.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
package org.json.junit.data;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A resource bundle class
|
||||
*/
|
||||
public class StringsResourceBundle extends ListResourceBundle {
|
||||
@Override
|
||||
public Object[][] getContents() {
|
||||
return contents;
|
||||
}
|
||||
static final Object[][] contents = {
|
||||
{"greetings.hello", "Hello, "},
|
||||
{"greetings.world", "World!"},
|
||||
{"farewells.later", "Later, "},
|
||||
{"farewells.gator", "Alligator!"}
|
||||
};
|
||||
}
|
67
src/test/java/org/json/junit/data/WeirdList.java
Normal file
67
src/test/java/org/json/junit/data/WeirdList.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.json.junit.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author John Aylward
|
||||
*/
|
||||
public class WeirdList {
|
||||
/** */
|
||||
private final List<Integer> list = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param vals
|
||||
*/
|
||||
public WeirdList(Integer... vals) {
|
||||
this.list.addAll(Arrays.asList(vals));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a copy of the list
|
||||
*/
|
||||
public List<Integer> get() {
|
||||
return new ArrayList<>(this.list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a copy of the list
|
||||
*/
|
||||
public List<Integer> getALL() {
|
||||
return new ArrayList<>(this.list);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a value at an index.
|
||||
*
|
||||
* @param i
|
||||
* index to get
|
||||
* @return the value at the index
|
||||
*/
|
||||
public Integer get(int i) {
|
||||
return this.list.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a value at an index.
|
||||
*
|
||||
* @param i
|
||||
* index to get
|
||||
* @return the value at the index
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
return this.list.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* new value to add to the end of the list
|
||||
*/
|
||||
public void add(Integer value) {
|
||||
this.list.add(value);
|
||||
}
|
||||
}
|
28
src/test/resources/jsonpointer-testdoc.json
Normal file
28
src/test/resources/jsonpointer-testdoc.json
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"foo":
|
||||
[
|
||||
"bar",
|
||||
"baz"
|
||||
],
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8,
|
||||
"obj" : {
|
||||
"key" : "value",
|
||||
"other~key" : {
|
||||
"another/key" : [
|
||||
"val"
|
||||
]
|
||||
},
|
||||
"" : {
|
||||
"" : "empty key of an object with an empty key",
|
||||
"subKey" : "Some other value"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue