diff --git a/src/SystemTextJson.JsonDiffPatch/Diffs/JsonDiffPatcher.Array.cs b/src/SystemTextJson.JsonDiffPatch/Diffs/JsonDiffPatcher.Array.cs index 6773ad3..3256548 100644 --- a/src/SystemTextJson.JsonDiffPatch/Diffs/JsonDiffPatcher.Array.cs +++ b/src/SystemTextJson.JsonDiffPatch/Diffs/JsonDiffPatcher.Array.cs @@ -121,7 +121,7 @@ private static void DiffArray( // We have two objects equal by position or other criteria var itemDiff = new JsonDiffDelta(); - DiffInternal(ref itemDiff, left[entry.LeftIndex], right[entry.RightIndex], options); + DiffInternal(ref itemDiff, left[commonHead + entry.LeftIndex], right[commonHead + entry.RightIndex], options); if (itemDiff.Document is not null) { delta.ArrayChange(i, false, itemDiff); diff --git a/test/SystemTextJson.JsonDiffPatch.UnitTests/NodeTests/DiffTests.cs b/test/SystemTextJson.JsonDiffPatch.UnitTests/NodeTests/DiffTests.cs index 6675866..b1a583e 100644 --- a/test/SystemTextJson.JsonDiffPatch.UnitTests/NodeTests/DiffTests.cs +++ b/test/SystemTextJson.JsonDiffPatch.UnitTests/NodeTests/DiffTests.cs @@ -1,4 +1,5 @@ -using System.Text.Json.JsonDiffPatch; +using System; +using System.Text.Json.JsonDiffPatch; using System.Text.Json.Nodes; using Xunit; @@ -50,6 +51,47 @@ public void Diff_ArrayMove() Assert.Equal("{\"_t\":\"a\",\"_0\":[\"\",1,3]}", diff!.ToJsonString()); } + [Fact] + public void Diff_Array_WithArrayObjectItemkeyFinder() + { + var source = "{ \"id\": \"1\", \"myArray\": [ { \"id\": \"2\", \"comment\": \"bogus\" }, { \"id\": \"3\", \"comment\": \"willberemoved\" }, { \"id\": \"4\", \"comment\": \"foobar\" }, { \"id\": \"5\", \"comment\": \"example\" }, { \"id\": \"6\", \"comment\": \"ok\" } ] }"; + var modified = "{ \"id\": \"1\", \"myArray\": [ { \"id\": \"2\", \"comment\": \"bogus\" }, { \"id\": \"4\", \"comment\": \"foobar\" }, { \"id\": \"5\", \"comment\": \"example adapted\" }, { \"id\": \"6\", \"comment\": \"ok\" }, { \"id\": \"myid\", \"comment\": \"isadded\" }, { \"id\": \"myid2\", \"comment\": \"isadded2\" }]}"; + + var left = JsonNode.Parse(source); + var right = JsonNode.Parse(modified); + + var options = new JsonDiffOptions + { + ArrayObjectItemKeyFinder = (node, index) => + { + if (node is JsonObject obj) + { + if (obj.TryGetPropertyValue("id", out var value)) + { + try + { + return value?.GetValue() ?? ""; + } + catch (InvalidOperationException) + { + return value?.GetValue() ?? 0; + } + + } + else if (obj.TryGetPropertyValue("name", out value)) + { + return value?.GetValue() ?? ""; + } + } + return index; //fallback + } + }; + + var diff = left.Diff(right, options); + + Assert.Equal("{\"myArray\":{\"_t\":\"a\",\"_1\":[{\"id\":\"3\",\"comment\":\"willberemoved\"},0,0],\"2\":{\"comment\":[\"example\",\"example adapted\"]},\"4\":[{\"id\":\"myid\",\"comment\":\"isadded\"}],\"5\":[{\"id\":\"myid2\",\"comment\":\"isadded2\"}]}}", diff!.ToJsonString()); + } + [Fact] public void Diff_NullProperty() {