From 964cb540fb4af3905e60199fc7ec8329cec923bf Mon Sep 17 00:00:00 2001 From: stleary Date: Sun, 22 Mar 2015 17:59:43 -0500 Subject: [PATCH] completed 94.8% coverage --- CDLTest.java | 269 ++++++++++++++++----------------------------------- 1 file changed, 82 insertions(+), 187 deletions(-) diff --git a/CDLTest.java b/CDLTest.java index d5ead3c..4ff9c38 100644 --- a/CDLTest.java +++ b/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> expectedLines = - sortColumnsInLines("Col 1, Col 2,\nV1, V2", normalize); - List> 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> sortedLines = sortColumnsInLines(lines, normalize); - // sorted, should already be normalized - List> 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 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 strMap = new TreeMap(); - 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 keyIt = jsonObject.keys(); - Map jsonObjectMap = new TreeMap(); - 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> sortColumnsInLines(String string, - boolean normalizeFlag) { - List> lineList = new ArrayList>(); - 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 columnList = new ArrayList(); - 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; - } } \ No newline at end of file