benjamine / jsondiffpatch

Diff & patch JavaScript objects
MIT License
4.78k stars 466 forks source link

Incorrect index in delta when removing objects to different parent? #158

Open androidkencai opened 8 years ago

androidkencai commented 8 years ago

Here is the test case

var jsondiffpatch = require('jsondiffpatch').create({
  objectHash: function(obj, index) {
    if (typeof obj.blockid !== 'undefined') {
      return obj.blockid;
    }
    return '$$index:' + index;
  },
  arrays: {
    detectMove: true,
    includeValueOnMove: true
  }
});

left.json

[
  {
    "blockid": 1,
    "name": "Initialize",
    "blocks": []
  },
  {
    "blockid": 2,
    "name": "Self Service",
    "blocks": [
      {
        "name": "Play Message D 2",
        "blockid": 30
      },
      {
        "name": "Menu_root_12_6",
        "blocks": [
          {
            "name": "Menu_12_6",
            "blocks": [
              {
                "name": "Play Message A 14",
                "blockid": 28
              }
            ],
            "blockid": 10
          },
          {
            "name": "Menu_22_6",
            "blocks": [
              {
                "name": "Play Message B 14",
                "blockid": 26
              }
            ],
            "blockid": 11
          }
        ],
        "blockid": 9
      },
      {
        "name": "Menu_root",
        "blocks": [
          {
            "name": "Menu Option 1",
            "blocks": [
              {
                "name": "Play Message y 3",
                "blockid": 47
              }
            ],
            "blockid": 34
          },
          {
            "name": "Menu Option 2",
            "blocks": [
              {
                "name": "Play Message x 3",
                "blockid": 46
              }
            ],
            "blockid": 35
          }
        ],        
        "blockid": 33
      }
    ]
  }
]

right.json

[
  {
    "blockid": 1,
    "name": "Initialize",
    "blocks": []
  },
  {
    "blockid": 2,    
    "name": "Self Service",
    "blocks": [
      {
        "name": "Play Message D 2",
        "blockid": 30
      },
      {
        "name": "Play Message y 3",
        "blockid": 47
      },
      {
        "name": "Menu_root_12_6",
        "blocks": [
          {
            "name": "Menu_12_6",
            "blocks": [
              {
                "name": "Play Message A 14",
                "blockid": 28
              }
            ],
            "blockid": 10
          },
          {
            "name": "Menu_22_6",
            "blocks": [
              {
                "name": "Play Message B 14",
                "blockid": 26
              }
            ],
            "blockid": 11
          }
        ],
        "blockid": 9
      },
      {
        "name": "Menu_root",
        "blocks": [
          {
            "name": "Menu Option 1",
            "blocks": [],
            "blockid": 34
          },
          {
            "name": "Menu Option 2",
            "blocks": [
              {
                "name": "Play Message x 3",
                "blockid": 46
              }
            ],
            "blockid": 35
          }
        ],        
        "blockid": 33
      }
    ]
  }
]

delta

{
  "1": {
    "blocks": {
      "1": [
        {
          "name": "Play Message y 3",
          "blockid": 47
        }
      ],
      "3": {
        "blocks": {
          "0": {
            "blocks": {
              "_t": "a",
              "_0": [
                {
                  "name": "Play Message y 3",
                  "blockid": 47
                },
                0,
                0
              ]
            }
          },
          "_t": "a"
        }
      },
      "_t": "a"
    }
  },
  "_t": "a"
}

In the delta, the path, "1" - "blocks" - "3" - ... doesn't exist in left.json or right.json. I think it's expected to be "1" - "blocks" - "2" - ...

Liodene commented 7 years ago

I've also encountered this issue 4 months ago.

A simpler test case is this one : left.json: [0, 1]

right.json: [1, 3]

delta: { "1": [ 3 ], "_t": "a", "_0": [ 0, 0, 0 ] }

The "1" totally disappear from the delta. If you try it on the demo page, you select the "Visual" with "Show unchanged values", the "1" doesn't show.

The workaround is to resort the right.json putting the old values in the same index as they were before.