jsondiffpatch icon indicating copy to clipboard operation
jsondiffpatch copied to clipboard

Interesting bug/problem with sequential patching and unpatching after sorting

Open milesingrams opened this issue 7 years ago • 0 comments

Hi Benjamine,

firstly jsondiffpatch works almost perfectly for my needs so thank you for developing it! I unfortunately have found one bug that has made me unable to use it unless I can figure it out. Basically I have an array of objects that I am tracking the change history of and I need to be able to reliably undo and redo changes on it. The objects are sorted by a value so when a new object is pushed to the end of the array it will automatically sort. When I add values and then undo and redo the changes I end up with a different object than when I started. I tried to change the diffpatcher settings to no avail. I even looked in depth at the diff objects and they look fine, they just aren't being applied/patched properly. I made a simplified fiddle here that console logs the results: https://jsfiddle.net/0bm76h65/ I've also added the code at the end if the fiddle doesn't work.

Note that after two unpatches followed by two patches you should end up with: [{"val":0},{"val":20},{"val":40},{"val":60}]

but instead you end up with: [{"val":0},{"val":20},{"val":40},{"val":40}]

If you don't sort the objects it works fine. But even when you turn on diff cloning it doesn't work with sorting.

Please help me solve this! Thanks!

Here's the example code:

var currentState = [{val: 0}];

var sortByValue = function () {
  currentState.sort(function(a,b) {
    if (a.val < b.val) {
      return -1;
    } else
    if (a.val > b.val) {
      return 1;
    } else {
      return 0;
    }
  });
};

var addValue = function (newValue) {
  currentState.push({val: newValue})
  sortByValue();
};

// Setup last state to use for diffs
var lastState = diffPatcher.clone(currentState);
console.log(JSON.stringify(currentState));

// Add item, sort, and diff
addValue(60);
var diff1 = diffPatcher.diff(lastState, currentState)
console.log(JSON.stringify(currentState));
lastState = diffPatcher.clone(currentState);

// Add item, sort, and diff
addValue(40);
var diff2 = diffPatcher.diff(lastState, currentState)
console.log(JSON.stringify(currentState));
lastState = diffPatcher.clone(currentState);

// Add item, sort, and diff
addValue(20);
var diff3 = diffPatcher.diff(lastState, currentState)
console.log(JSON.stringify(currentState));

// reverse last diff
diffPatcher.unpatch(currentState, diff3);
console.log(JSON.stringify(currentState));

// reverse last diff
diffPatcher.unpatch(currentState, diff2);
console.log(JSON.stringify(currentState));

// reapply diff
diffPatcher.patch(currentState, diff2);
console.log(JSON.stringify(currentState));

// reapply diff
diffPatcher.patch(currentState, diff3);
console.log(JSON.stringify(currentState));

/* Final output:
[{"val":0}]
[{"val":0},{"val":60}]
[{"val":0},{"val":40},{"val":60}]
[{"val":0},{"val":20},{"val":40},{"val":60}]
[{"val":0},{"val":40},{"val":60}]
[{"val":0},{"val":60}]
[{"val":0},{"val":40},{"val":60}]
[{"val":0},{"val":20},{"val":40},{"val":40}]
*/

milesingrams avatar Mar 24 '17 21:03 milesingrams