/* * Copyright (c) 2014 Oculus Info Inc. * http://www.oculusinfo.com/ * * Released under the MIT License. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.oculusinfo.binning.util; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; public class JSONUtilitiesTests { @Test public void testObjectCloning () throws JSONException { JSONObject source = new JSONObject("{name: 'abc', int: 3, double: 3.3, object: {a: 'a', b: 'b'}, array: [1, 2, 3]}"); JSONObject clone = JsonUtilities.deepClone(source); Assert.assertFalse(source == clone); Assert.assertEquals(source.toString(), clone.toString()); Assert.assertEquals("abc", source.getString("name")); Assert.assertEquals(3, source.getInt("int")); Assert.assertEquals(3.3, source.getDouble("double"), 1E-12); Assert.assertTrue(source.getJSONObject("object") == source.getJSONObject("object")); Assert.assertFalse(source.getJSONObject("object") == clone.getJSONObject("object")); Assert.assertEquals(source.getJSONObject("object").toString(), clone.getJSONObject("object").toString()); Assert.assertTrue(source.getJSONArray("array") == source.getJSONArray("array")); Assert.assertFalse(source.getJSONArray("array") == clone.getJSONArray("array")); Assert.assertEquals(source.getJSONArray("array").toString(), clone.getJSONArray("array").toString()); } @Test public void testArrayCloning () throws JSONException { JSONArray source = new JSONArray("['abc', 3, 3.3, {a: 'a', b: 'b'}, [1, 2, 3]]"); JSONArray clone = JsonUtilities.deepClone(source); Assert.assertFalse(source == clone); Assert.assertEquals(source.toString(), clone.toString()); Assert.assertEquals("abc", source.getString(0)); Assert.assertEquals(3, source.getInt(1)); Assert.assertEquals(3.3, source.getDouble(2), 1E-12); Assert.assertTrue(source.getJSONObject(3) == source.getJSONObject(3)); Assert.assertFalse(source.getJSONObject(3) == clone.getJSONObject(3)); Assert.assertEquals(source.getJSONObject(3).toString(), clone.getJSONObject(3).toString()); Assert.assertTrue(source.getJSONArray(4) == source.getJSONArray(4)); Assert.assertFalse(source.getJSONArray(4) == clone.getJSONArray(4)); Assert.assertEquals(source.getJSONArray(4).toString(), clone.getJSONArray(4).toString()); } @Test public void testOverlaying () throws JSONException { JSONObject base = new JSONObject("{a: 'a', a1: 'a1', b: 1, b1: 2, c: 1.1, c1: 2.2, d: {a: 'aa', a1: 'aa1'}, e: ['a', 'a1', 1, 2, 1.1, 2.2, {b: 'bb', b1: 'bb1'}]}"); JSONObject overlay = new JSONObject("{a1: 'a3', b1: 3, c1: 3.3, d: {a1: 'aa3'}, e:[null, 'a3', null, 3, null, 3.3, {b1: 'bb3'}]}"); JSONObject result = JsonUtilities.overlayInPlace(base, overlay); Assert.assertTrue(base == result); // Make sure overlay is unchanged Assert.assertEquals(5, overlay.length()); // Make sure unchanged entries remain unchanged Assert.assertEquals("a", result.getString("a")); Assert.assertEquals(1, result.getInt("b")); Assert.assertEquals(1.1, result.getDouble("c"), 1E-12); Assert.assertEquals("aa", result.getJSONObject("d").getString("a")); Assert.assertEquals("a", result.getJSONArray("e").getString(0)); Assert.assertEquals(1, result.getJSONArray("e").getInt(2)); Assert.assertEquals(1.1, result.getJSONArray("e").getDouble(4), 1E-12); Assert.assertEquals("bb", result.getJSONArray("e").getJSONObject(6).getString("b")); // Make sure changed entries have changed Assert.assertEquals("a3", result.getString("a1")); Assert.assertEquals(3, result.getInt("b1")); Assert.assertEquals(3.3, result.getDouble("c1"), 1E-12); Assert.assertEquals("aa3", result.getJSONObject("d").getString("a1")); Assert.assertEquals("a3", result.getJSONArray("e").getString(1)); Assert.assertEquals(3, result.getJSONArray("e").getInt(3)); Assert.assertEquals(3.3, result.getJSONArray("e").getDouble(5), 1E-12); Assert.assertEquals("bb3", result.getJSONArray("e").getJSONObject(6).getString("b1")); } @Test public void testArrayOverlayTruncation () throws Exception { JSONArray base = new JSONArray("['a', 'b', 'c', 'd', 'e', 'f']"); JSONArray overlay = new JSONArray("[1, 2, null, 4]"); JSONArray result = JsonUtilities.overlay(base, overlay); Assert.assertEquals(4, result.length()); Assert.assertEquals(1, result.getInt(0)); Assert.assertEquals(2, result.getInt(1)); Assert.assertEquals("c", result.getString(2)); Assert.assertEquals(4, result.getInt(3)); } @Test public void testPropertyClass () throws Exception { JSONObject base = new JSONObject("{a: 'a', b: {c: 'c', d:['a', 'a1', 1, 2, 1.1, 2.2]}}"); Properties props = JsonUtilities.jsonObjToProperties(base); Assert.assertEquals("a", props.getProperty("a")); Assert.assertEquals("c", props.getProperty("b.c")); Assert.assertEquals("a", props.getProperty("b.d.0")); Assert.assertEquals("a1", props.getProperty("b.d.1")); Assert.assertEquals("1", props.getProperty("b.d.2")); Assert.assertEquals("2", props.getProperty("b.d.3")); Assert.assertEquals("1.1", props.getProperty("b.d.4")); Assert.assertEquals("2.2", props.getProperty("b.d.5")); Assert.assertEquals(Properties.class, props.getClass()); } @Test public void testPropertyToJSONConversion () throws Exception { Properties p = new Properties(); p.setProperty("a", "aval"); p.setProperty("b.0", "bval0"); p.setProperty("b.2", "bval2"); p.setProperty("c.1", "cval1"); p.setProperty("c.a", "cvala"); p.setProperty("c.b.a", "cbaval"); p.setProperty("c.b.b", "cbbval"); p.setProperty("d", "{\"x\":\"xval\", \"y\": 10}"); JSONObject expected = new JSONObject("{\"a\": \"aval\", \"b\": [\"bval0\", null, \"bval2\"], " + "\"c\": {\"1\": \"cval1\", \"a\": \"cvala\", \"b\": {\"a\": \"cbaval\", \"b\": \"cbbval\"}}, " + "\"d\" : { \"x\" : \"xval\", \"y\" : 10 }}"); JSONObject actual = JsonUtilities.propertiesObjToJSON(p); assertJsonEqual(expected, actual); } @Test public void testStringMapToJSONConversion () throws Exception { Map<String, String> p = new HashMap<>(); p.put("a", "aval"); p.put("b.0", "bval0"); p.put("b.2", "bval2"); p.put("c.1", "cval1"); p.put("c.a", "cvala"); p.put("c.b.a", "cbaval"); p.put("c.b.b", "cbbval"); JSONObject expected = new JSONObject("{\"a\": \"aval\", \"b\": [\"bval0\", null, \"bval2\"], \"c\": {\"1\": \"cval1\", \"a\": \"cvala\", \"b\": {\"a\": \"cbaval\", \"b\": \"cbbval\"}}}"); JSONObject actual = JsonUtilities.mapToJSON(p); assertJsonEqual(expected, actual); } @Test public void testJSONObjectKeyExpansion () throws Exception { JSONObject source = new JSONObject("{\n"+ " \"person.name.first\": \"Alice\",\n"+ " \"person.name.middle\": \"Barbara\",\n"+ " \"person.name.last\": \"Cavendish\",\n"+ " \"person.school.location.state\": \"Delaware\",\n"+ " \"person\": {\n"+ " \"school.location.country\": \"US\",\n"+ " \"school.grades\": [\n"+ " {\"year\": \"freshman\",\n"+ " \"bySemester.semester1\": \"A\",\n"+ " \"bySemester.semester2\": \"B\"},\n"+ " {\"year\":\"sophomore\",\n"+ " \"bySemester.semester1\": \"C\",\n"+ " \"bySemester\": {\"semester2\": \"D\", \"semester3\": \"E\"}}\n"+ " ]\n"+ " }\n"+ "}"); JSONObject target = new JSONObject("{\n"+ " \"person\": {\n"+ " \"name\": { \"first\": \"Alice\",\n"+ " \"middle\": \"Barbara\",\n"+ " \"last\": \"Cavendish\" },\n"+ " \"school\": {\n"+ " \"location\": { \"state\": \"Delaware\",\n"+ " \"country\": \"US\" },\n"+ " \"grades\": [\n"+ " { \"year\": \"freshman\",\n"+ " \"bySemester\": { \"semester1\": \"A\",\n"+ " \"semester2\": \"B\" } },\n"+ " { \"year\": \"sophomore\",\n"+ " \"bySemester\": { \"semester1\": \"C\",\n"+ " \"semester2\": \"D\",\n"+ " \"semester3\": \"E\" } }\n"+ " ]\n"+ " }\n"+ " }\n"+ "}"); assertJsonEqual(target, JsonUtilities.expandKeysInPlace(source)); } @Test public void testIsJson() throws Exception { Assert.assertFalse(JsonUtilities.isJSON("{343493043 }")); Assert.assertTrue(JsonUtilities.isJSON("{\"a\": { \"b\": [{\"c\":1},{\"d\":2}] } }")); } public static void assertJsonEqual (JSONObject expected, JSONObject actual) { Map<String, Object> mapE = JsonUtilities.jsonObjToMap(expected); Map<String, Object> mapA = JsonUtilities.jsonObjToMap(actual); assertEquals(mapE, mapA); } public static void assertJsonEqual (JSONArray expected, JSONArray actual) { List<Object> listE = JsonUtilities.jsonArrayToList(expected); List<Object> listA = JsonUtilities.jsonArrayToList(actual); assertEquals(listE, listA); } private static void assertEquals (Object expected, Object actual) { if (expected instanceof List) { Assert.assertTrue("Expected a list, but didn't get one", actual instanceof List); List<?> eList = (List<?>) expected; List<?> aList = (List<?>) actual; Assert.assertEquals(eList.size(), aList.size()); for (int i=0; i<eList.size(); ++i) { assertEquals(eList.get(i), aList.get(i)); } } else if (expected instanceof Map) { Assert.assertTrue("Expected a map, but didn't get one", actual instanceof Map); Map<?, ?> eMap = (Map<?, ?>) expected; Map<?, ?> aMap = (Map<?, ?>) actual; Assert.assertEquals(eMap.size(), aMap.size()); for (Object key: eMap.keySet()) { Assert.assertTrue(aMap.containsKey(key)); assertEquals(eMap.get(key), aMap.get(key)); } } else { Assert.assertEquals(expected, actual); } } }