benjamine / jsondiffpatch

Diff & patch JavaScript objects
MIT License
4.83k stars 472 forks source link

Unpatch fails for given scenario #60

Closed krickovicd closed 9 years ago

krickovicd commented 9 years ago

Consider the following example:

    var src = {"parts":[{"id":"1","variation":{"x":"2","y":"0"},"distance":{"x":"3","y":"0"}}],"Id":"4"};
    var dst = {"parts":[{"id":"5","x":10},{"id":"6","variation":{"x":"3","y":"0"},"distance":{"x":"7","y":"0"}},{"id":"1","variation":{"x":"5","y":"0"},"distance":{"x":"3","y":"0"}},{"id":"8","variation":{"x":"2","y":"output0"},"distance":{"x":"5","y":"input0"}}],"Id":"4"};
    var diffpatcher = jsondiffpatch.create({
        objectHash: function (obj) {
            return obj._id || obj.id || obj.Id || JSON.stringify(obj);
        },
        arrays: {
            detectMove: true,
            includeValueOnMove: false
        },
        textDiff: {
            minLength: 60
        }
    });
    var delta = diffpatcher.diff(src, dst);
    diffpatcher.patch(src, delta);
    diffpatcher.unpatch(src, delta);

In this example patch works fine but unpatch fails with the following message: Uncaught TypeError: Cannot read property 'variation' of undefined

enkodellc commented 9 years ago

+1 I am getting these errors as well. Spent the last 3 hours trying to debug my application. I have several nested documents that may move and have updating values.

enkodellc commented 9 years ago

@krickovicd have you attempted to fix the issue in the code? I am exhausted from changing my code thinking it was my fault that the error was happening. I am not sure if I am up to the task of learning this code and fixing the issue. I am fairly new to JS and was planning on using this library to create an audit log and undo for my Mongo objects storing a history of user edits...

@benjamine can you respond to this issue? Just curious if this is something to expect a fix on or I should look for another library or a work around. Thanks for the hard work in the library already. Much appreciated.

benjamine commented 9 years ago

Hi, thanks a lot for the failing example, that helped me to create a new failing test case and fixing it. the problem is delta reversing (used to unpatch) was making a dumb mistake, using the same index for items with changes in the reversed delta (But you can notice in your example, index 0 in src becomes index 2 in dest).

fixed and published as jsondiffpatch@0.1.24

enkodellc commented 9 years ago

Thanks @benjamine though I am still getting this error. I will supply a test scenario after I do a bit more testing and clean up the data I am using for the test case.

@krickovicd did this patch work for you?

enkodellc commented 9 years ago

This has arrays within arrays which you may not be handling. I tested against the latest code.

Here is my left:

{
  "_id" : "548b4f14462e2c102629e011",
  "docSections" : [
    {
      "section" : "53a6778b7192aa7831aca40b",
      "_id" : "548b4f14462e2c102629e027",
      "showTitle" : false,
      "docContents" : [
        {
          "content" : "5385011f6c0882c424b89159",
          "title" : "Title",
          "body" : "<div style=\"text-align: center;\">Catchy Title</div>",
          "_id" : "548b4f14462e2c102629e029",
          "docContents" : [],
          "comments" : [],
          "tocLabel" : "1.1",
          "pageBreak" : false,
          "showTitle" : false
        }
      ],
      "tocLabel" : "1",
      "isOpen" : false,
      "title" : "Cover Page"
    },
    {
      "section" : "53a6798ab0ea78f02f311e03",
      "_id" : "548b4f14462e2c102629e024",
      "showTitle" : true,
      "docContents" : [
        {
          "content" : "53961edaeff90574291f17dc",
          "title" : "Table of Contents",
          "body" : "<p><span>[[Table of Contents]]</span></p>",
          "_id" : "548b4f14462e2c102629e026",
          "docContents" : [],
          "comments" : [],
          "tocLabel" : "2.1",
          "pageBreak" : false,
          "showTitle" : false
        }
      ],
      "tocLabel" : "2",
      "isOpen" : true,
      "title" : "Table of Contents"
    },
    {
      "section" : "53a684f2dea5d3ec318ac670",
      "_id" : "548b4f14462e2c102629e01a",
      "showTitle" : true,
      "docContents" : [
        {
          "content" : "5385129a516a7dd82a764102",
          "title" : "Other Considerations",
          "body" : "<p><span>Consider this content</span><br/></p>&#10;",
          "_id" : "548b4f14462e2c102629e01d",
          "docContents" : [
            {
              "content" : "53851216516a7dd82a764101",
              "title" : "Contents of Document",
              "body" : "<p>Document Contents</p>",
              "_id" : "548b4f14462e2c102629e01c",
              "docContents" : [],
              "comments" : [],
              "tocLabel" : "3.1.1",
              "pageBreak" : false,
              "showTitle" : true
            }
          ],
          "comments" : [],
          "tocLabel" : "3.1",
          "pageBreak" : false,
          "showTitle" : true
        }
      ],
      "tocLabel" : "3",
      "isOpen" : true,
      "title" : "Body"
    },
    {
      "section" : "53a679eab0ea78f02f311e04",
      "_id" : "548b4f14462e2c102629e01e",
      "showTitle" : true,
      "docContents" : [
        {
          "content" : "53851110516a7dd82a7640ff",
          "title" : "Introduction part",
          "body" : "<p>Break it down</p>",
          "_id" : "548b4f14462e2c102629e023",
          "docContents" : [],
          "comments" : [],
          "tocLabel" : "4.1",
          "pageBreak" : false,
          "showTitle" : true
        },
        {
          "content" : "53850c8921b0605c244fa0bd",
          "title" : "Contact Information",
          "body" : "<p>Contact Information</p>",
          "_id" : "548b4f14462e2c102629e022",
          "docContents" : [
            {
              "content" : "53850bbecf996bc81309d5ed",
              "title" : "Who, What, Why, When and How",
              "body" : "<p>The five questions</p>",
              "_id" : "548b4f14462e2c102629e021",
              "docContents" : [],
              "comments" : [],
              "tocLabel" : "4.2.1",
              "pageBreak" : false,
              "showTitle" : true
            },
            {
              "showTitle" : true,
              "pageBreak" : false,
              "tocLabel" : "4.2.2",
              "comments" : [],
              "docContents" : [],
              "_id" : "548b4f14462e2c102629e020",
              "body" : "<p>Hello</p>&#10;",
              "title" : "Introduction Statement",
              "content" : "53850b03cf996bc81309d5ec"
            }
          ],
          "comments" : [],
          "tocLabel" : "4.2",
          "pageBreak" : false,
          "showTitle" : true
        }
      ],
      "tocLabel" : "4",
      "isOpen" : true,
      "title" : "Introduction"
    },
    {
      "section" : "53a68502dea5d3ec318ac671",
      "_id" : "548b4f14462e2c102629e017",
      "showTitle" : true,
      "docContents" : [
        {
          "content" : "539b597e22a7fa94178653f4",
          "title" : "Appendix",
          "body" : "Appendix",
          "_id" : "548b4f14462e2c102629e019",
          "docContents" : [],
          "comments" : [],
          "tocLabel" : "5.1",
          "pageBreak" : true,
          "showTitle" : true
        }
      ],
      "tocLabel" : "5",
      "isOpen" : false,
      "title" : "Appendix"
    }
  ],
  "description" : "test",
  "title" : "test"
}

Here is my right:


{
"_id" : "548b4f14462e2c102629e011",
"docSections" : [
{
"section" : "53a6778b7192aa7831aca40b",
"_id" : "548b4f14462e2c102629e027",
"showTitle" : false,
"docContents" : [
{
"content" : "5385011f6c0882c424b89159",
"title" : "Title",
"body" : "<div style=\"text-align: center;\">Catchy Title</div>",
"_id" : "548b4f14462e2c102629e029",
"docContents" : [],
"comments" : [],
"tocLabel" : "1.1",
"pageBreak" : false,
"showTitle" : false
}
],
"tocLabel" : "1",
"isOpen" : false,
"title" : "Cover Page"
},
{
"section" : "53a6798ab0ea78f02f311e03",
"_id" : "548b4f14462e2c102629e024",
"showTitle" : true,
"docContents" : [
{
"content" : "53961edaeff90574291f17dc",
"title" : "Table of Contents",
"body" : "<p><span>[[Table of Contents]]</span></p>",
"_id" : "548b4f14462e2c102629e026",
"docContents" : [],
"comments" : [],
"tocLabel" : "2.1",
"pageBreak" : false,
"showTitle" : false
}
],
"tocLabel" : "2",
"isOpen" : true,
"title" : "Table of Contents"
},
{
"section" : "53a68502dea5d3ec318ac671",
"_id" : "548b4f14462e2c102629e017",
"showTitle" : true,
"docContents" : [
{
"content" : "539b597e22a7fa94178653f4",
"title" : "Appendix",
"body" : "Appendix",
"_id" : "548b4f14462e2c102629e019",
"docContents" : [],
"comments" : [],
"tocLabel" : "3.1",
"pageBreak" : true,
"showTitle" : true
}
],
"tocLabel" : "3",
"isOpen" : false,
"title" : "Appendix"
},
{
"section" : "53a684f2dea5d3ec318ac670",
"_id" : "548b4f14462e2c102629e01a",
"showTitle" : true,
"docContents" : [
{
"content" : "5385129a516a7dd82a764102",
"title" : "Other Considerations",
"body" : "<p><span>Consider this content</span><br/></p>&#10;",
"_id" : "548b4f14462e2c102629e01d",
"docContents" : [
{
"content" : "53851216516a7dd82a764101",
"title" : "Contents of Document",
"body" : "<p>Document Contents</p>",
"_id" : "548b4f14462e2c102629e01c",
"docContents" : [],
"comments" : [],
"tocLabel" : "4.1.1",
"pageBreak" : false,
"showTitle" : true
}
],
"comments" : [],
"tocLabel" : "4.1",
"pageBreak" : false,
"showTitle" : true
}
],
"tocLabel" : "4",
"isOpen" : true,
"title" : "Body"
},
{
"section" : "53a679eab0ea78f02f311e04",
"_id" : "548b4f14462e2c102629e01e",
"showTitle" : true,
"docContents" : [
{
"content" : "53851110516a7dd82a7640ff",
"title" : "Introduction part",
"body" : "<p>Break it down</p>",
"_id" : "548b4f14462e2c102629e023",
"docContents" : [],
"comments" : [],
"tocLabel" : "5.1",
"pageBreak" : false,
"showTitle" : true
},
{
"content" : "53850c8921b0605c244fa0bd",
"title" : "Contact Information",
"body" : "<p>Contact Information</p>",
"_id" : "548b4f14462e2c102629e022",
"docContents" : [
{
"content" : "53850bbecf996bc81309d5ed",
"title" : "Who, What, Why, When and How",
"body" : "<p>The five questions</p>",
"_id" : "548b4f14462e2c102629e021",
"docContents" : [],
"comments" : [],
"tocLabel" : "5.2.1",
"pageBreak" : false,
"showTitle" : true
},
{
"showTitle" : true,
"pageBreak" : false,
"tocLabel" : "5.2.2",
"comments" : [],
"docContents" : [],
"_id" : "548b4f14462e2c102629e020",
"body" : "<p>Hello GoodBye</p>&#10;",
"title" : "Introduction Statement",
"content" : "53850b03cf996bc81309d5ec"
}
],
"comments" : [],
"tocLabel" : "5.2",
"pageBreak" : false,
"showTitle" : true
}
],
"tocLabel" : "5",
"isOpen" : true,
"title" : "Appendix"
}
],
"description" : "test",
"title" : "test"
}

Here is the diff that is created and when trying to unpatch I get the error:

{
"docSections": {
"2": {
"docContents": {
"0": {
"tocLabel": [
"5.1",
"3.1"
]
},
"_t": "a"
},
"tocLabel": [
"5",
"3"
]
},
"3": {
"docContents": {
"0": {
"docContents": {
"0": {
"tocLabel": [
"3.1.1",
"4.1.1"
]
},
"_t": "a"
},
"tocLabel": [
"3.1",
"4.1"
]
},
"_t": "a"
},
"tocLabel": [
"3",
"4"
]
},
"4": {
"docContents": {
"0": {
"tocLabel": [
"4.1",
"5.1"
]
},
"1": {
"docContents": {
"0": {
"tocLabel": [
"4.2.1",
"5.2.1"
]
},
"1": {
"tocLabel": [
"4.2.2",
"5.2.2"
],
"body": [
"<p>Hello</p>&#10;",
"<p>Hello GoodBye</p>&#10;"
]
},
"_t": "a"
},
"tocLabel": [
"4.2",
"5.2"
]
},
"_t": "a"
},
"tocLabel": [
"4",
"5"
],
"title": [
"Introduction",
"Appendix"
]
},
"_t": "a",
"_4": [
"",
2,
3
]
}
}

Thanks for taking the time to help debug.

krickovicd commented 9 years ago

Hi, thanks for the fix. It's a nice library and easy to use. @enkodellc: Yes, the patch works in my case.

krickovicd commented 9 years ago

@enkodellc as an alternative to unpatch you can calculate delta for both ways (left to right and right to lef) and use patch with corresponding delta. Since this issue is marked as closed maybe you should create new one with your example?