diff --git a/test/index.test.js b/test/index.test.js index 04b6221..462c427 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -89,12 +89,7 @@ describe("Jsondiff", function() { ] } ]; - tests.forEach(test => { - it(test.name, function() { - let output = jsondiff(test.start, test.end); - expect(output).to.deep.have.same.members(test.expectedCommand); - }); - }); + runTests(tests); }); describe("List Replace (oi + od)", function() { let tests = [ @@ -103,15 +98,9 @@ describe("Jsondiff", function() { start: ["one", "two"], end: ["one", "three", "two"], expectedCommand: [ - { - p: [1], - ld: "two", - li: "three" - }, - { - p: [2], - li: "two" - } + { sd: 'wo', p: [ 1, 1 ] }, + { si: 'hree', p: [ 1, 1 ] }, + { p: [ 2 ], li: 'two' } ] }, { @@ -147,12 +136,7 @@ describe("Jsondiff", function() { ] } ]; - tests.forEach(test => { - it(test.name, function() { - let output = jsondiff(test.start, test.end); - expect(output).to.deep.have.same.members(test.expectedCommand); - }); - }); + runTests(tests); }); describe("Object Insert (oi)", function() { let tests = [ @@ -190,12 +174,7 @@ describe("Jsondiff", function() { ] } ]; - tests.forEach(test => { - it(test.name, function() { - let output = jsondiff(test.start, test.end); - expect(output).to.deep.equal(test.expectedCommand); - }); - }); + runTests(tests); }); describe("Object Replace (oi + od)", function() { let tests = [ @@ -204,11 +183,8 @@ describe("Jsondiff", function() { start: { one: "one" }, end: { one: "two" }, expectedCommand: [ - { - p: ["one"], - oi: "two", - od: "one" - } + { sd: 'one', p: [ 'one', 0 ] }, + { si: 'two', p: [ 'one', 0 ] } ] }, { @@ -236,12 +212,7 @@ describe("Jsondiff", function() { ] } ]; - tests.forEach(test => { - it(test.name, function() { - let output = jsondiff(test.start, test.end); - expect(output).to.deep.equal(test.expectedCommand); - }); - }); + runTests(tests); }); describe("String Mutation (si + sd)", function() { // These test cases come from diff-match-patch tests. @@ -298,6 +269,15 @@ describe("Jsondiff", function() { { si: 'xyz', p: [ 'one', 0 ] } ] }, + { + name: "Strings suffix/prefix overlap, overlap case", + start: { one: "123456xxx" }, + end: { one: "xxxabcd" }, + expectedCommand: [ + { "p": [ "one", 0 ], "sd": "123456xxx" }, + { "p": [ "one", 0 ], "si": "xxxabcd" } + ] + }, { name: "Example from README", start: ["foo", "The only change here is at the end.", 1, 2, 3], @@ -308,39 +288,49 @@ describe("Jsondiff", function() { ] } ]; - tests.forEach(test => { - it(test.name, function() { + runTests(tests); + }); + }); +}); + +function runTests(tests) { + tests.forEach(test => { + it(test.name, function() { + + ////////////////// + // Verify JSON0 // + ////////////////// + let json0Op = jsondiff(test.start, test.end, diffMatchPatch); + expect(json0Op).to.deep.equal(test.expectedCommand); - ////////////////// - // Verify JSON0 // - ////////////////// - let json0Op = jsondiff(test.start, test.end, diffMatchPatch); - expect(json0Op).to.deep.equal(test.expectedCommand); + // Test actual application of the expected ops. + // Clone the input, because json0 mutates the input to `apply`. + let json0Start = clone(test.start); + let json0End = json0.type.apply(json0Start, json0Op); + expect(json0End).to.deep.equal(test.end); - // Test actual application of the expected ops. - // Clone the input, because json0 mutates the input to `apply`. - let json0Start = clone(test.start); - let json0End = json0.type.apply(json0Start, json0Op); - expect(json0End).to.deep.equal(test.end); + // Test application of ops generated _without_ diffMatchPatch. + let json0SimpleOp = jsondiff(test.start, test.end); + let json0SimpleStart = clone(test.start); + let json0SimpleEnd = json0.type.apply(json0SimpleStart, json0SimpleOp); + expect(json0SimpleEnd).to.deep.equal(test.end); - ////////////////// - // Verify JSON1 // - ////////////////// - let json1Op = jsondiff( - test.start, - test.end, - diffMatchPatch, - json1, - textUnicode - ); + ////////////////// + // Verify JSON1 // + ////////////////// + let json1Op = jsondiff( + test.start, + test.end, + diffMatchPatch, + json1, + textUnicode + ); - // Test actual application of the expected ops. - // No need to clone the input, json1 does _not_ mutate the input to `apply`. - let json1End = json1.type.apply(test.start, json1Op); - expect(json1End).to.deep.equal(test.end); - }); - }); + // Test actual application of the expected ops. + // No need to clone the input, json1 does _not_ mutate the input to `apply`. + let json1End = json1.type.apply(test.start, json1Op); + expect(json1End).to.deep.equal(test.end); }); }); -}); +} diff --git a/tests.js b/tests.js index f580a0a..804d520 100644 --- a/tests.js +++ b/tests.js @@ -10,7 +10,28 @@ let textUnicode = require("ot-text-unicode"); var jsondiff = require("./index.js"); var tests = [ - //tests of li/ld + // Tests of equality + [ + 5, + 5, + ], + [ + "foo", + "foo", + ], + [ + ["foo"], + ["foo"], + ], + [ + [], + [], + ], + [ + {}, + {}, + ], + // Tests of li/ld [ [], ["foo"] @@ -43,7 +64,7 @@ var tests = [ ["foo", "bar", "quux"], ["bar", "quux"] ], - // tests for object/array + // Tests for object/array [ {}, [] @@ -52,7 +73,7 @@ var tests = [ [], {} ], - // tests for oi/od + // Tests for oi/od [ {}, {"foo":"bar"} @@ -65,7 +86,44 @@ var tests = [ [ { foo: 'bar' } ], [ {} ] ], - // big tests + // String tests + // Inspired by https://github.com/google/diff-match-patch/blob/master/javascript/tests/diff_match_patch_test.js + ["abc", "xyz"], + ["1234abcdef", "1234xyz"], + ["1234", "1234xyz"], + ["abc", "xyz"], + ["abcdef1234", "xyz1234"], + ["1234", "xyz1234"], + ["", "abcd"], + ["abc", "abcd"], + ["123456", "abcd"], + ["123456xxx", "xxxabcd"], + ["fi", "\ufb01i"], + ["1234567890", "abcdef"], + ["12345", "23"], + ["1234567890", "a345678z"], + ["a345678z", "1234567890"], + ["abc56789z", "1234567890"], + ["a23456xyz", "1234567890"], + ["121231234123451234123121", "a1234123451234z"], + ["x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-="], + ["-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy"], + ["qHilloHelloHew", "xHelloHeHulloy"], + ["abcdefghijk", "fgh"], + ["abcdefghijk", "efxhi"], + ["abcdefghijk", "cdefxyhijk"], + ["abcdefghijk", "bxy"], + ["123456789xx0", "3456789x0"], + ["abcdefghijk", "efxyhi"], + ["abcdefghijk", "bcdef"], + ["abcdexyzabcde", "abccde"], + ["abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0"], + ["abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz", "abcdefuvwxyz"], + ["1234567890123456789012345678901234567890123456789012345678901234567890", "abc"], + ["XY", "XtestY"], + ["XXXXYYYY", "XXXXtestYYYY"], + ["The quick brown fox jumps over the lazy dog.", "Woof"], + // Big tests [ [], ["the", {"quick":"brown", "fox":"jumped"}, "over", {"the": ["lazy", "dog"]}] @@ -78,7 +136,7 @@ var tests = [ [["the", {"quick":"black", "fox":"jumped"}, "over", {"the": ["lazy", "dog"]}]], ["the", {"quick":"brown", "fox":"leapt"}, "over", {"the": ["stupid", "dog"]}] ], - // real-life jsonml tests + // Real-life jsonml tests [ [ 'html', {}, [ 'body', {}, '\n\n', '\n\n', [ 'p', {}, 'Quux!' ] ], '\n' ], [ 'html', {}, [ 'body', {}, '\n\n', '\n\n\n\n', [ 'p', {}, 'Quux!' ] ], '\n' ] @@ -140,6 +198,10 @@ tests.forEach(function([input, output]) { // Actual tests for json0 tests.forEach(function([input, output]) { var ops = jsondiff(input, output); + + // Don't let json0 mutate the input, + // so we can use it in later tests. + input = clone(input); ops.forEach(function(op) { assert.doesNotThrow(function() { input = json0.type.apply(input, [op]); @@ -157,7 +219,7 @@ tests.forEach(function([input, output]) { json1, textUnicode ); - assert(equal(input, json1.type.apply(input, ops))); + assert(equal(json1.type.apply(input, ops), output)); }); console.log("No errors!");