weichch / system-text-json-jsondiffpatch

High-performance, low-allocating JSON object diff and patch extension for System.Text.Json. Support generating patch document in RFC 6902 JSON Patch format.
MIT License
104 stars 13 forks source link

DefaultDeltaFormatter.FormatArray throws System.FormatException: 'Invalid patch document.' #49

Open stefarv opened 4 months ago

stefarv commented 4 months ago

When using ArrayObjectItemKeyFinder with test data like below, System.FormatException: 'Invalid patch document.' is thrown

json1 { "id": 1, "name": "Some name", "projects": [{"id": 88, "name": "bar"}] }

json2 { "id": 1, "name": "Some name", "projects": [{"id": 77, "name": "foo"}, {"id": 88, "name": "bar z"}] }

Code to reproduce:

using System.Text.Json.JsonDiffPatch.Diffs.Formatters;
using System.Text.Json.JsonDiffPatch;
using System.Text.Json.Nodes;

string json1 = "{ \"id\": 1, \"name\": \"Some name\", \"projects\": [{\"id\": 88, \"name\": \"bar\"}] }";
string json2 = "{ \"id\": 1, \"name\": \"Some name\", \"projects\": [{\"id\": 77, \"name\": \"foo\"}, {\"id\": 88, \"name\": \"bar z\"}] }";

// project with id 77 inserted first in the array, name for project with id 88 changed from "bar" to "bar z"

object? IdKeyFinder(JsonNode? n, int i)
{
    if (n is JsonObject obj
           && obj.TryGetPropertyValue("id", out var value))
    {
        return value?.ToString();
    }

    return null;
}

var diff = JsonDiffPatcher.Diff(
    json1,
    json2,
    new JsonPatchDeltaFormatter(),
    new JsonDiffOptions
    {
        JsonElementComparison = JsonElementComparison.RawText,
        ArrayObjectItemMatchByPosition = false,
        ArrayObjectItemKeyFinder = IdKeyFinder
    });