diff --git a/lib/index.js b/lib/index.js index c952d80..63c2e9d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -18,18 +18,6 @@ class JsonDiff { let score = 0 let equal = true - for (const [key, value] of Object.entries(obj1)) { - if (!this.options.outputNewOnly) { - const postfix = '__deleted' - - if (!(key in obj2) && !(this.options.excludeKeys.includes(key))) { - result[`${key}${postfix}`] = value - score -= 30 - equal = false - } - } - } - for (const [key, value] of Object.entries(obj2)) { const postfix = !this.options.outputNewOnly ? '__added' : '' @@ -41,21 +29,36 @@ class JsonDiff { } for (const [key, value1] of Object.entries(obj1)) { + let keyChanged = false; if (key in obj2) { - if (this.options.excludeKeys.includes(key)) { - continue - } - score += 20 - const value2 = obj2[key] - const change = this.diff(value1, value2) - if (!change.equal) { - result[key] = change.result - equal = false - } else if (this.options.full || this.options.outputKeys.includes(key)) { - result[key] = value1 + if (!this.options.excludeKeys.includes(key)) { + score += 20; + const value2 = obj2[key]; + const change = this.diff(value1, value2); + if (!change.equal) { + result[key] = change.result; + equal = false; + keyChanged = true; + } + score += Math.min(20, Math.max(-10, change.score / 5)); // BATMAN! } - // console.log(`key ${key} change.score=${change.score} ${change.result}`) - score += Math.min(20, Math.max(-10, change.score / 5)) // BATMAN! + } else if ( + !this.options.outputNewOnly && + !(key in obj2) && + !this.options.excludeKeys.includes(key) + ) { + const postfix = "__deleted"; + result[`${key}${postfix}`] = value1; + score -= 30; + equal = false; + keyChanged = true; + } + + if ( + !keyChanged && + (this.options.full || this.options.outputKeys.includes(key)) + ) { + result[key] = value1; } } diff --git a/test/diff_test.coffee b/test/diff_test.coffee index 07885a1..10780a4 100644 --- a/test/diff_test.coffee +++ b/test/diff_test.coffee @@ -241,6 +241,20 @@ describe 'diff({ excludeKeys: foo,bar }', -> it "shouldn't return keys foo and bar (with addition) ", -> assert.deepEqual undefined, diff({ bbar: 5 }, { foo: 42, bar: 10, bbar: 5 }, {excludeKeys: ["foo", "bar"]}) +describe 'diff({ excludeKeys: foo, bar outputKeys: foo }', -> + + it "Should return foo even though it is in excludeKeys", -> + assert.deepEqual { bbar__added: 5, foo: 42 }, diff({ foo: 42 }, { bar: 10, bbar: 5 }, {excludeKeys: ["foo", "bar"], outputKeys: ["foo"]}) + + it "Should return foo even though it has not changed", -> + assert.deepEqual { bbar__added: 5, foo: 42 }, diff({ foo: 42 }, { foo: 42, bar: 10, bbar: 5 }, {excludeKeys: ["foo", "bar"], outputKeys: ["foo"]}) + + it "shouldn't return keys foo because it doesn't exist in value 1", -> + assert.deepEqual { bbar__added: 5 }, diff({ bar: 10 }, { foo: 42, bar: 10, bbar: 5 }, {excludeKeys: ["foo", "bar"], outputKeys: ["foo"]}) + + it "should return foo of value 1 event though it has changed", -> + assert.deepEqual { bbar: { __new: 6, __old: 5 }, foo: 42 }, diff({ bbar: 5, foo: 42 }, { foo: 43, bar: 10, bbar: 6 }, {excludeKeys: ["foo", "bar"], outputKeys: ["foo"]}) + describe 'diff({keysOnly: true})', -> describe 'with simple scalar values', ->