/* * 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.metadata; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; public class JsonMutationTests { private static final double EPSILON = 1E-12; private JSONObject getBaseTestObject () throws JSONException { return new JSONObject( "{" +"'s1':'abc'," +"'i1':3," +"'d1':4.4," +"'b1':true," +"'b2':false," +"'a1':['def', -3, -4.4, false]," +"'o1':{'s1':'ghi','i1':2,'d1':3.14159,'b1':false,'a1':[],'o1':{}}" +"}"); } private void testBaseObject (JSONObject base) throws JSONException { String[] baseProps = JSONObject.getNames(base); Assert.assertEquals(7, baseProps.length); Set<String> expectedProps = new HashSet<>(Arrays.asList("s1", "i1", "d1", "b1", "b2", "a1", "o1")); for (String prop: baseProps) expectedProps.remove(prop); Assert.assertTrue(expectedProps.isEmpty()); Assert.assertEquals("abc", base.get("s1")); Assert.assertEquals(3, base.getInt("i1")); Assert.assertEquals(4.4, base.getDouble("d1"), EPSILON); Assert.assertEquals(true, base.getBoolean("b1")); Assert.assertEquals(false, base.getBoolean("b2")); JSONArray a1 = base.getJSONArray("a1"); Assert.assertEquals(4, a1.length()); Assert.assertEquals("def", a1.get(0)); Assert.assertEquals(-3, a1.getInt(1)); Assert.assertEquals(-4.4, a1.getDouble(2), EPSILON); Assert.assertEquals(false, a1.getBoolean(3)); JSONObject o1 = base.getJSONObject("o1"); baseProps = JSONObject.getNames(base); Assert.assertEquals(7, baseProps.length); expectedProps = new HashSet<>(Arrays.asList("s1", "i1", "d1", "b1", "a1", "o1")); for (String prop: baseProps) expectedProps.remove(prop); Assert.assertTrue(expectedProps.isEmpty()); Assert.assertEquals("ghi", o1.get("s1")); Assert.assertEquals(2, o1.getInt("i1")); Assert.assertEquals(3.14159, o1.getDouble("d1"), EPSILON); JSONArray o1a1 = o1.getJSONArray("a1"); Assert.assertEquals(0, o1a1.length()); JSONObject o1o1 = o1.getJSONObject("o1"); Assert.assertEquals(0, o1o1.length()); } @Test public void baseTest () throws JSONException { JSONObject base = getBaseTestObject(); testBaseObject(base); } @Test public void addRemoveLevel1Test () throws JSONException { JSONObject base = getBaseTestObject(); JsonMutator add = new AddPropertyMutator("jkl", "s2"); JsonMutator remove = new RemovePropertyMutator("s2"); // Make sure simple add/remove works add.mutateJson(base); Assert.assertEquals("jkl", base.get("s2")); remove.mutateJson(base); Assert.assertFalse(base.has("s2")); testBaseObject(base); // Make sure add doesn't overwrite existing entry base.put("s2", "lmn"); add.mutateJson(base); Assert.assertEquals("lmn", base.get("s2")); // Remove won't be able to distinguish original from added; don't bother // testing that. } @Test public void addRemoveLevel2Test () throws JSONException { JSONObject base = getBaseTestObject(); JsonMutator add = new AddPropertyMutator("1", "o1", "i2"); JsonMutator remove = new RemovePropertyMutator("o1", "i2"); // Make sure add/remove works add.mutateJson(base); Assert.assertEquals(1, base.getJSONObject("o1").getInt("i2")); remove.mutateJson(base); Assert.assertFalse(base.getJSONObject("o1").has("i2")); testBaseObject(base); // Make sure add doesn't overwrite existing entry base.getJSONObject("o1").put("i2", 3); add.mutateJson(base); Assert.assertEquals(3, base.getJSONObject("o1").getInt("i2")); // Remove won't be able to distinguish original from added; don't bother // testing that. } @Test public void testAddRemoveNewNode () throws JSONException { JSONObject base = getBaseTestObject(); JsonMutator add = new AddPropertyMutator("2.718", "o2", "d1"); JsonMutator remove = new RemovePropertyMutator("o2", "d1"); // Make sure add/remove works add.mutateJson(base); Assert.assertEquals(2.718, base.getJSONObject("o2").getDouble("d1"), EPSILON); remove.mutateJson(base); Assert.assertFalse(base.has("o2")); testBaseObject(base); } @Test(expected=JSONException.class) public void testNonNodeLeafAddition () throws JSONException { JSONObject base; try { base = getBaseTestObject(); } catch (JSONException e) { throw new RuntimeException(e); } JsonMutator add = new AddPropertyMutator("abc", "s1", "s1"); add.mutateJson(base); } @Test public void testMoveNode () throws JSONException { JSONObject base = getBaseTestObject(); // Create branch to move (note misspelling) new AddPropertyMutator("leaf", "o2", "branche", "twig").mutateJson(base); Assert.assertEquals(1, base.getJSONObject("o2").length()); Assert.assertEquals(1, base.getJSONObject("o2").getJSONObject("branche").length()); Assert.assertEquals("leaf", base.getJSONObject("o2").getJSONObject("branche").get("twig")); // Move branch new PropertyRelocationMutator("spelling correction", new String[] {"o2", "branche"}, new String[] {"o3", "branch"}, true).mutateJson(base); Assert.assertFalse(base.has("o2")); Assert.assertEquals(1, base.getJSONObject("o3").length()); Assert.assertEquals(1, base.getJSONObject("o3").getJSONObject("branch").length()); Assert.assertEquals("leaf", base.getJSONObject("o3").getJSONObject("branch").get("twig")); } @Test public void testKeyToArray () throws JSONException { JSONObject base = getBaseTestObject(); new PropertyIndexToArrayMutator<String>(new String[] {"o1", "(\\p{Alpha})\\d"}, new String[] {"a2"}, "\\1.1") { @Override protected String mutateValue (String value) { return value; } @Override protected void sort (List<String> values) { Collections.sort(values); } }.mutateJson(base); Assert.assertEquals(6, base.getJSONArray("a2").length()); Set<String> values = new HashSet<>(); for (int i=0; i<6; ++i) { values.add(base.getJSONArray("a2").optString(i)); } Assert.assertTrue(values.contains("s")); Assert.assertTrue(values.contains("i")); Assert.assertTrue(values.contains("d")); Assert.assertTrue(values.contains("b")); Assert.assertTrue(values.contains("a")); Assert.assertTrue(values.contains("o")); } }