mirror of
https://github.com/ethauvin/JSON-java.git
synced 2025-06-17 07:50:52 -07:00
completed 94.8% coverage
This commit is contained in:
parent
2876b27ec5
commit
964cb540fb
1 changed files with 82 additions and 187 deletions
269
CDLTest.java
269
CDLTest.java
|
@ -1,30 +1,24 @@
|
|||
package org.json.junit;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
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 {@link 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. Since each row is an unordered JSONObject,
|
||||
* can't use a simple string compare to check for equality.
|
||||
* @author JSON.org
|
||||
* @version 2015-03-18
|
||||
* @version 2015-03-22
|
||||
*
|
||||
*/
|
||||
public class CDLTest {
|
||||
|
@ -42,6 +36,20 @@ public class CDLTest {
|
|||
"\"va\tl1\", \"v\bal2\", \"val3\", \"val\f4\", \"val5\", va\'l6, val7\n"
|
||||
);
|
||||
|
||||
/**
|
||||
* Something I did not expect is that CDL.toJSONArray() adds all values as
|
||||
* strings, with no filtering or conversions. I suppose this makes it
|
||||
* easier to emit it as CDL later. For testing, it 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}]");
|
||||
|
||||
@Test(expected=NullPointerException.class)
|
||||
public void shouldThrowExceptionOnNullString() {
|
||||
String nullStr = null;
|
||||
|
@ -72,32 +80,6 @@ public class CDLTest {
|
|||
jsonArray == null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringShouldCheckSpecialChars() {
|
||||
/**
|
||||
* Given a JSONArray that was not built by CDL, some chars may be
|
||||
* found that would otherwise be filtered out by CDL.
|
||||
*/
|
||||
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");
|
||||
boolean normalize = true;
|
||||
List<List<String>> expectedLines =
|
||||
sortColumnsInLines("Col 1, Col 2,\nV1, V2", normalize);
|
||||
List<List<String>> jsonArrayLines =
|
||||
sortColumnsInLines(CDL.toString(jsonArray), normalize);
|
||||
if (!expectedLines.equals(jsonArrayLines)) {
|
||||
System.out.println("expected: " +expectedLines);
|
||||
System.out.println("jsonArray: " +jsonArrayLines);
|
||||
assertTrue("Should filter out certain chars",
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=JSONException.class)
|
||||
public void shouldHandleUnbalancedQuoteInName() {
|
||||
String badLine = "Col1, \"Col2\nVal1, Val2";
|
||||
|
@ -116,29 +98,46 @@ public class CDLTest {
|
|||
CDL.toJSONArray(badLine);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void toStringShouldCheckSpecialChars() {
|
||||
/**
|
||||
* Given a JSONArray that was not built by CDL, some chars may be
|
||||
* found that would otherwise be filtered out by CDL.
|
||||
*/
|
||||
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\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConvertCDLToJSONArray() {
|
||||
// this array is built by CDL
|
||||
JSONArray jsonArray = CDL.toJSONArray(lines);
|
||||
String resultStr = compareJSONArrayToString(jsonArray, lines);
|
||||
if (resultStr != null) {
|
||||
assertTrue("CDL should convert string to JSONArray: " +
|
||||
resultStr, false);
|
||||
}
|
||||
// This array is built from JSON parsing
|
||||
JSONArray expectedJsonArray = new JSONArray(expectedLines);
|
||||
compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateJSONArrayUsingJSONArray() {
|
||||
String names = "Col1, Col2";
|
||||
String nameArrayStr = "[" +names+ "]";
|
||||
String nameArrayStr = "[Col1, Col2]";
|
||||
String values = "V1, V2";
|
||||
JSONArray nameJSONArray = new JSONArray(nameArrayStr);
|
||||
JSONArray jsonArray = CDL.toJSONArray(nameJSONArray, values);
|
||||
String combinedStr = names+ "\n" +values;
|
||||
String resultStr = compareJSONArrayToString(jsonArray, combinedStr);
|
||||
if (resultStr != null) {
|
||||
assertTrue("CDL should convert JSONArray and string to JSONArray: " +
|
||||
resultStr, false);
|
||||
}
|
||||
JSONArray expectedJsonArray = new JSONArray("[{Col1:V1,Col2:V2}]");
|
||||
compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -148,147 +147,43 @@ public class CDLTest {
|
|||
* The string contains a typical variety of values
|
||||
* that might be found in a real CDL.
|
||||
*/
|
||||
final boolean normalize = true;
|
||||
final boolean doNotNormalize = false;
|
||||
JSONArray jsonArray = CDL.toJSONArray(lines);
|
||||
String jsonStr = CDL.toString(jsonArray);
|
||||
// normal sorted
|
||||
List<List<String>> sortedLines = sortColumnsInLines(lines, normalize);
|
||||
// sorted, should already be normalized
|
||||
List<List<String>> sortedJsonStr = sortColumnsInLines(jsonStr, doNotNormalize);
|
||||
boolean result = sortedLines.equals(sortedJsonStr);
|
||||
if (!result) {
|
||||
System.out.println("lines: " +sortedLines);
|
||||
System.out.println("jsonStr: " +sortedJsonStr);
|
||||
assertTrue("CDL should convert JSONArray back to original string: " +
|
||||
lines.equals(jsonStr), false);
|
||||
JSONArray finalJsonArray = CDL.toJSONArray(jsonStr);
|
||||
JSONArray expectedJsonArray = new JSONArray(expectedLines);
|
||||
compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////// UTILITY METHODS /////////////////////////
|
||||
|
||||
/**
|
||||
* Compares two json arrays for equality
|
||||
* @param jsonArray created by the code to be tested
|
||||
* @param expectedJsonArray created specifically for compar
|
||||
*/
|
||||
private void compareActualVsExpectedJsonArrays(JSONArray jsonArray,
|
||||
JSONArray expectedJsonArray) {
|
||||
assertTrue("jsonArray lengths should be equal",
|
||||
jsonArray.length() == expectedJsonArray.length());
|
||||
for (int i = 0; i < jsonArray.length(); ++i) {
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||
JSONObject expectedJsonObject = expectedJsonArray.getJSONObject(i);
|
||||
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);
|
||||
String testStr = "row: "+i+" key: "+key+" val: "+value.toString();
|
||||
String actualStr = expectedJsonObject .get(key).toString();
|
||||
assertTrue("values should be equal for actual: "+testStr+
|
||||
" expected: "+actualStr,
|
||||
value.equals(expectedJsonArray.getJSONObject(i).
|
||||
get(key).toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************\
|
||||
* SUPPORT AND UTILITY
|
||||
\******************************************************************/
|
||||
|
||||
/**
|
||||
* Compares a JSON array to the original string. The top row of the
|
||||
* string contains the JSONObject keys and the remaining rows contain
|
||||
* the values. The JSONObject in each JSONArray row is expected to have
|
||||
* an entry corresponding to each key/value pair in the string.
|
||||
* Each JSONObject row is unordered in its own way.
|
||||
* @param jsonArray the JSONArray which was created from the string
|
||||
* @param str the string which was used to create the JSONArray
|
||||
* @return null if equal, otherwise error description
|
||||
*/
|
||||
private String compareJSONArrayToString(JSONArray jsonArray, String str) {
|
||||
int rows = jsonArray.length();
|
||||
StringReader sr = new StringReader(str);
|
||||
BufferedReader reader = new BufferedReader(sr);
|
||||
try {
|
||||
// first line contains the keys to the JSONObject array entries
|
||||
String columnNames = reader.readLine();
|
||||
columnNames = normalizeString(columnNames);
|
||||
String[] keys = columnNames.split(",");
|
||||
/**
|
||||
* Each line contains the values for the corresponding
|
||||
* JSONObject array entry
|
||||
*/
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
String line = reader.readLine();
|
||||
line = normalizeString(line);
|
||||
String[] values = line.split(",");
|
||||
// need a value for every key to proceed
|
||||
if (keys.length != values.length) {
|
||||
System.out.println("keys: " + Arrays.toString(keys));
|
||||
System.out.println("values: " + Arrays.toString(values));
|
||||
return("row: " +i+ " key and value counts do not match");
|
||||
}
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||
// need a key for every JSONObject entry to proceed
|
||||
if (keys.length != jsonObject.length()) {
|
||||
System.out.println("keys: " + Arrays.toString(keys));
|
||||
System.out.println("jsonObject: " + jsonObject.toString());
|
||||
return("row: " +i+ " key and jsonObject counts do not match");
|
||||
}
|
||||
// convert string entries into a natural order map.
|
||||
Map<String, String> strMap = new TreeMap<String, String>();
|
||||
for (int j = 0; j < keys.length; ++j) {
|
||||
strMap.put(keys[j], values[j]);
|
||||
}
|
||||
// put the JSONObjet key/value pairs in natural key order
|
||||
Iterator<String> keyIt = jsonObject.keys();
|
||||
Map<String, String> jsonObjectMap = new TreeMap<String, String>();
|
||||
while (keyIt.hasNext()) {
|
||||
String key = keyIt.next();
|
||||
jsonObjectMap.put(key, jsonObject.get(key).toString());
|
||||
}
|
||||
if (!strMap.equals(jsonObjectMap)) {
|
||||
System.out.println("strMap: " +strMap.toString());
|
||||
System.out.println("jsonObjectMap: " +jsonObjectMap.toString());
|
||||
return("row: " +i+ "string does not match jsonObject");
|
||||
}
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
} catch (JSONException ignore) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to trim and remove internal quotes from comma delimited strings.
|
||||
* Need to do this because JSONObject does the same thing
|
||||
* @param line the line to be normalized
|
||||
* @return the normalized line
|
||||
*/
|
||||
private String normalizeString(String line) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean comma = false;
|
||||
String[] values = line.split(",");
|
||||
for (int i = 0; i < values.length; ++i) {
|
||||
if (comma) {
|
||||
builder.append(",");
|
||||
}
|
||||
comma = true;
|
||||
values[i] = values[i].trim();
|
||||
// strip optional surrounding quotes
|
||||
values[i] = values[i].replaceAll("^\"|\"$", "");
|
||||
builder.append(values[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to sort the columns in a (possibly) multi-lined string.
|
||||
* The columns are column separated. Need to do this because
|
||||
* JSONObects are not ordered
|
||||
* @param string the string to be sorted
|
||||
* @param normalize flag, true if line should be normalized
|
||||
* @return a list of sorted lines, where each line is a list sorted
|
||||
* in natural key order
|
||||
*/
|
||||
private List<List<String>> sortColumnsInLines(String string,
|
||||
boolean normalizeFlag) {
|
||||
List<List<String>> lineList = new ArrayList<List<String>>();
|
||||
StringReader sr = new StringReader(string);
|
||||
BufferedReader reader = new BufferedReader(sr);
|
||||
try {
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
if (normalizeFlag) {
|
||||
line = normalizeString(line);
|
||||
}
|
||||
List<String> columnList = new ArrayList<String>();
|
||||
String[] values = line.split(",");
|
||||
for (int i = 0; i < values.length; ++i) {
|
||||
columnList.add(values[i]);
|
||||
}
|
||||
Collections.sort(columnList);
|
||||
lineList.add(columnList);
|
||||
}
|
||||
} catch (IOException ignore) {}
|
||||
return lineList;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue