Repository: johnzon Updated Branches: refs/heads/master 2940f6e13 -> ce46007e6
JOHNZON-103 added tests for JsonPatchDiff ADD and REMOVE Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/ce46007e Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/ce46007e Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/ce46007e Branch: refs/heads/master Commit: ce46007e6beaa0ef2a30bf931408d7ab665ace2e Parents: 2940f6e Author: Reinhard Sandtner <[email protected]> Authored: Mon Feb 27 22:31:35 2017 +0100 Committer: Reinhard Sandtner <[email protected]> Committed: Mon Feb 27 22:31:35 2017 +0100 ---------------------------------------------------------------------- .../org/apache/johnzon/core/JsonPatchDiff.java | 21 ++- .../apache/johnzon/core/JsonPatchDiffTest.java | 164 +++++++++++++++++-- 2 files changed, 163 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/johnzon/blob/ce46007e/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java index 81a7bf2..2d0f05c 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java @@ -29,17 +29,17 @@ import javax.json.JsonValue; /** * Create a diff from a source and target JsonStructure */ -public class JsonPatchDiff { +class JsonPatchDiff { private final JsonStructure source; private final JsonStructure target; - public JsonPatchDiff(JsonStructure source, JsonStructure target) { + JsonPatchDiff(JsonStructure source, JsonStructure target) { this.source = source; this.target = target; } - public JsonPatch calculateDiff() { + JsonPatch calculateDiff() { JsonPatchBuilder patchBuilder = new JsonPatchBuilderImpl(); diff(patchBuilder, "/", source, target); @@ -48,9 +48,10 @@ public class JsonPatchDiff { } private void diff(JsonPatchBuilder patchBuilder, String basePath, JsonStructure source, JsonStructure target) { - if (source instanceof JsonObject && target instanceof JsonObject) { + if (isJsonObject(source) && isJsonObject(target)) { // handle JsonObjects diffJsonObjects(patchBuilder, basePath, (JsonObject) source, (JsonObject) target); + } else if (source instanceof JsonArray && target instanceof JsonArray) { // handle JsonArray //X TODO @@ -66,8 +67,11 @@ public class JsonPatchDiff { for (Map.Entry<String, JsonValue> sourceEntry : sourceEntries) { String attributeName = sourceEntry.getKey(); if (target.containsKey(attributeName)) { - JsonValue targetValue = ((JsonObject) target).get(attributeName); - if (!sourceEntry.getValue().equals(targetValue)) { + JsonValue targetValue = target.get(attributeName); + + if (isJsonObject(targetValue) && isJsonObject(targetValue)) { + diffJsonObjects(patchBuilder, basePath + attributeName + "/", (JsonObject) sourceEntry.getValue(), (JsonObject) targetValue); + } else if (!sourceEntry.getValue().equals(targetValue)) { // replace the original value patchBuilder.replace(basePath + attributeName, targetValue); } @@ -85,4 +89,9 @@ public class JsonPatchDiff { } } + + + private static boolean isJsonObject(JsonValue jsonValue) { + return jsonValue instanceof JsonObject; + } } http://git-wip-us.apache.org/repos/asf/johnzon/blob/ce46007e/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java index 3462a19..48ff05a 100644 --- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java +++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java @@ -16,6 +16,9 @@ */ package org.apache.johnzon.core; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.io.StringReader; import javax.json.Json; @@ -42,14 +45,133 @@ public class JsonPatchDiffTest { // adding "b" JsonPatch jsonPatch = Json.createDiff(Json.createReader(new StringReader(jsonA)).readObject(), Json.createReader(new StringReader(jsonB)).readObject()); - Assert.assertNotNull(jsonPatch); + assertNotNull(jsonPatch); JsonArray patchOperations = jsonPatch.toJsonArray(); - Assert.assertNotNull(patchOperations); - Assert.assertEquals(1, patchOperations.size()); - containsOperation(patchOperations, JsonPatch.Operation.ADD, "/b", "xb"); + assertNotNull(patchOperations); + assertEquals(1, patchOperations.size()); + containsOperation(patchOperations, JsonPatch.Operation.ADD, "/b", Json.createValue("xb")); + } + + @Test + public void testAddDiffNewObject() { + + JsonObject target = Json.createObjectBuilder() + .add("a", Json.createObjectBuilder() + .add("aa", "value") + .add("ab", "another")) + .build(); + + JsonPatch patch = Json.createDiff(JsonValue.EMPTY_JSON_OBJECT, target); + assertNotNull(patch); + + JsonArray operations = patch.toJsonArray(); + assertEquals(1, operations.size()); + + containsOperation(operations, JsonPatch.Operation.ADD, "/a", target.get("a")); + } + + @Test + public void testAddDiffInNestedObject() { + + JsonObject source = Json.createObjectBuilder() + .add("a", Json.createObjectBuilder() + .add("aa", "value")) + .build(); + + JsonObject target = Json.createObjectBuilder() + .add("a", Json.createObjectBuilder() + .add("aa", "value") + .add("bb", "another value")) + .build(); + + JsonPatch patch = Json.createDiff(source, target); + assertNotNull(patch); + + JsonArray operations = patch.toJsonArray(); + assertEquals(1, operations.size()); + + containsOperation(operations, JsonPatch.Operation.ADD, "/a/bb", Json.createValue("another value")); + } + + @Test + public void testRemoveDiffObject() { + + JsonObject source = Json.createObjectBuilder() + .add("a", "value") + .build(); + + JsonPatch patch = Json.createDiff(source, JsonValue.EMPTY_JSON_OBJECT); + assertNotNull(patch); + + JsonArray operations = patch.toJsonArray(); + assertEquals(1, operations.size()); + + containsOperation(operations, JsonPatch.Operation.REMOVE, "/a"); + } + + @Test + public void testRemoveDiffNestedObject() { + + JsonObject source = Json.createObjectBuilder() + .add("a", "value") + .add("nested", Json.createObjectBuilder() + .add("1", 1) + .add("2", 2)) + .build(); + + { + JsonPatch patch = Json.createDiff(source, JsonValue.EMPTY_JSON_OBJECT); + assertNotNull(patch); + + JsonArray operations = patch.toJsonArray(); + assertEquals(2, operations.size()); + + containsOperation(operations, JsonPatch.Operation.REMOVE, "/a"); + containsOperation(operations, JsonPatch.Operation.REMOVE, "/nested"); + } + + { + JsonObject target = Json.createObjectBuilder() + .add("a", "value") + .add("nested", Json.createObjectBuilder() + .add("1", 1)) + .build(); + + JsonPatch patch = Json.createDiff(source, target); + assertNotNull(patch); + + JsonArray operations = patch.toJsonArray(); + assertEquals(1, operations.size()); + + containsOperation(operations, JsonPatch.Operation.REMOVE, "/nested/2"); + } } @Test + public void testDiffEqualObjects() { + + JsonObject source = Json.createObjectBuilder() + .add("a", "value") + .build(); + + JsonObject target = Json.createObjectBuilder() + .add("a", "value") + .build(); + + JsonPatch patch = Json.createDiff(source, target); + assertNotNull(patch); + assertEquals(0, patch.toJsonArray().size()); + } + + + //X TODO arrays... + //X TODO test add/remove JsonArray + //X TODO test add object to JsonArray + //X TODO test remove object to JsonArray + + + + @Test @Ignore //X TODO reinhard take over ;) public void testComplexDiff() { // {"a":"xa","b":2,"c":{"d":"xd"},"e":[1,2,3]} @@ -62,25 +184,35 @@ public class JsonPatchDiffTest { // removing b, adding d2, removing 2 from e, adding f JsonPatch jsonPatch = Json.createDiff(Json.createReader(new StringReader(jsonA)).readObject(), Json.createReader(new StringReader(jsonB)).readObject()); - Assert.assertNotNull(jsonPatch); + assertNotNull(jsonPatch); JsonArray patchOperations = jsonPatch.toJsonArray(); - Assert.assertNotNull(patchOperations); - Assert.assertEquals(4, patchOperations.size()); - containsOperation(patchOperations, JsonPatch.Operation.REMOVE, "/b", null); - containsOperation(patchOperations, JsonPatch.Operation.ADD, "/c/d2", "xd2"); - containsOperation(patchOperations, JsonPatch.Operation.REMOVE, "/e/2", null); - containsOperation(patchOperations, JsonPatch.Operation.ADD, "/f", "xe"); + assertNotNull(patchOperations); + assertEquals(4, patchOperations.size()); + containsOperation(patchOperations, JsonPatch.Operation.REMOVE, "/b"); + containsOperation(patchOperations, JsonPatch.Operation.ADD, "/c/d2", Json.createValue("xd2")); + containsOperation(patchOperations, JsonPatch.Operation.REMOVE, "/e/2"); + containsOperation(patchOperations, JsonPatch.Operation.ADD, "/f", Json.createValue("xe")); + } + + private void containsOperation(JsonArray patchOperations, + JsonPatch.Operation patchOperation, + String jsonPointer) { + + containsOperation(patchOperations, patchOperation, jsonPointer, null); } - private void containsOperation(JsonArray patchOperations, JsonPatch.Operation patchOperation, - String jsonPointer, String value) { + private void containsOperation(JsonArray patchOperations, + JsonPatch.Operation patchOperation, + String jsonPointer, + JsonValue value) { + for (JsonValue operation : patchOperations) { if (operation instanceof JsonObject && - patchOperation.operationName().equalsIgnoreCase(((JsonObject) operation).getString("op"))) { - Assert.assertEquals(jsonPointer, ((JsonObject) operation).getString("path")); + patchOperation.operationName().equalsIgnoreCase(((JsonObject) operation).getString("op")) && + ((JsonObject) operation).getString("path").equals(jsonPointer)) { if (value != null) { - Assert.assertEquals(value, ((JsonObject) operation).getString("value")); + assertEquals(value, ((JsonObject) operation).get("value")); } return;
