benjamine / jsondiffpatch

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

Invalid comparison result when the value contains more than 60 characters #248

Closed kiichi closed 4 years ago

kiichi commented 6 years ago

If comparing value's string size exceed the more than textdiff limit, the diff result will spill out patch syntax.

Reproducible Steps

  1. Go to live demo (https://benjamine.github.io/jsondiffpatch/demo/index.html)
  2. Paste the following json string
    {
    "hello": "X one two three four five six seven eight nine ten eleven (ABC)"
    }
  3. Change first few characters
  4. You will see wrong comparison result such as
    {
    "hello": [
    "@@ -1,5 +1,5 @@\n-X\n+Y\n  one\n",
    0,
    2
    ]
    }

Please note that the live demo has default textDiff limit which is 60.

Note

To avoid this, I simply set textDiff option very large so that it wouldn't spill out.

textDiff: {
    minLength:1000 
},
benjamine commented 4 years ago

@kiichi / @philnova trying to understand the expected behavior here (sorry for the delay, I'm catching up with open issues), what you describe is by design. the reason is that when a text is too large, it starts to be more efficient to include a patch than the full string values. are you looking for a way to completely disable these text diffs? are you having trouble patching with them?

kiichi commented 4 years ago

Hi @benjamine

Thank you for this clarification, and I think this is my confusion of the default behavior of text-diff feature. If you can consider to implement explicit option to turn off this parameter

e.g.

textDiff: {
        minLength: -1 // disable
},

That'll be great. Let me close the issue since this is documented default behavior.

The reason that I got confused is the text-diff does not kick-in until the string reaches 60 characters. I was writing SQL Generator based on two JSON, and I was directly looking into the jsondiffpatch object structure.

I noticed that my output is not consistent in some dataset because if one of string value contains more than 60 chars, my logic worked differently. I was trying to generate whole UPDATE statement in SQL, and I didn't need string based patch, just needed replace the whole string regardless of the size.