From 221c11e1f1a57524c3f5d2ab75de1aa991871bd8 Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Wed, 12 Jul 2017 12:49:57 +0100 Subject: [PATCH] Compare complex item values when preparing diff The diffing algorithm should only recurse when the values are (shallow) equal. Fixes #32. --- lib/metaDescriptors/item.js | 3 +- test/diff.js | 20 +++++++++++++ test/snapshots/diff.js.md | 54 ++++++++++++++++++++++++++++++++++++ test/snapshots/diff.js.snap | Bin 4471 -> 4658 bytes 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/lib/metaDescriptors/item.js b/lib/metaDescriptors/item.js index be1d8ef..1539b62 100644 --- a/lib/metaDescriptors/item.js +++ b/lib/metaDescriptors/item.js @@ -132,7 +132,8 @@ class ComplexItem { } } - const mustRecurse = this.tag === complexTag && initialExpected.tag === complexTag + const mustRecurse = this.tag === complexTag && initialExpected.tag === complexTag && + this.value.compare(initialExpected.value) !== UNEQUAL return { mustRecurse, isUnequal: !mustRecurse, diff --git a/test/diff.js b/test/diff.js index 1006710..395d429 100644 --- a/test/diff.js +++ b/test/diff.js @@ -105,6 +105,26 @@ test('diffs diverging complex types', t => { map([1, {foo: 'bar'}, 2]), map([1, {baz: 'qux'}, 2])) t.snapshot(actual2) + + class Foo { + constructor () { + this.foo = 'foo' + } + } + class Bar { + constructor () { + this.bar = 'bar' + } + } + const actual3 = diff( + map([new Foo()]), + map([new Bar()])) + t.snapshot(actual3) + + const actual4 = diff( + map([Buffer.alloc(0)]), + map([new Uint8Array()])) + t.snapshot(actual4) } test('diffs arrays', equalLength, mapArray) test('diffs arguments', equalLength, mapArguments) diff --git a/test/snapshots/diff.js.md b/test/snapshots/diff.js.md index 2fb5de8..0c71b35 100644 --- a/test/snapshots/diff.js.md +++ b/test/snapshots/diff.js.md @@ -465,6 +465,24 @@ Generated by [AVA](https://ava.li). %diffGutters.padding# % %number.open%2%number.close%%item.after#,%␊ %diffGutters.padding# %%list.closeBracket#]%` +> Snapshot 3 + + `%diffGutters.padding# %%object.ctor.open%Arguments%object.ctor.close% %list.openBracket#[%␊ + %diffGutters.actual#- % %object.ctor.open%Foo%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.actual#- % foo%property.separator#: %%string.line.open#'%%string.open%foo%string.close%%string.line.close#'%%property.after#,%␊ + %diffGutters.actual#- % %object.closeBracket#}%%item.after#,%␊ + %diffGutters.expected#+ % %object.ctor.open%Bar%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.expected#+ % bar%property.separator#: %%string.line.open#'%%string.open%bar%string.close%%string.line.close#'%%property.after#,%␊ + %diffGutters.expected#+ % %object.closeBracket#}%%item.after#,%␊ + %diffGutters.padding# %%list.closeBracket#]%` + +> Snapshot 4 + + `%diffGutters.padding# %%object.ctor.open%Arguments%object.ctor.close% %list.openBracket#[%␊ + %diffGutters.actual#- % %object.ctor.open%Buffer%object.ctor.close% %object.secondaryStringTag.open#@%Uint8Array%object.secondaryStringTag.close% %list.openBracket#[%%list.closeBracket#]%%item.after#,%␊ + %diffGutters.expected#+ % %object.ctor.open%Uint8Array%object.ctor.close% %list.openBracket#[%%list.closeBracket#]%%item.after#,%␊ + %diffGutters.padding# %%list.closeBracket#]%` + ## diffs arrays > Snapshot 1 @@ -487,6 +505,24 @@ Generated by [AVA](https://ava.li). %diffGutters.padding# % %number.open%2%number.close%%item.after#,%␊ %diffGutters.padding# %%list.closeBracket#]%` +> Snapshot 3 + + `%diffGutters.padding# %%list.openBracket#[%␊ + %diffGutters.actual#- % %object.ctor.open%Foo%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.actual#- % foo%property.separator#: %%string.line.open#'%%string.open%foo%string.close%%string.line.close#'%%property.after#,%␊ + %diffGutters.actual#- % %object.closeBracket#}%%item.after#,%␊ + %diffGutters.expected#+ % %object.ctor.open%Bar%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.expected#+ % bar%property.separator#: %%string.line.open#'%%string.open%bar%string.close%%string.line.close#'%%property.after#,%␊ + %diffGutters.expected#+ % %object.closeBracket#}%%item.after#,%␊ + %diffGutters.padding# %%list.closeBracket#]%` + +> Snapshot 4 + + `%diffGutters.padding# %%list.openBracket#[%␊ + %diffGutters.actual#- % %object.ctor.open%Buffer%object.ctor.close% %object.secondaryStringTag.open#@%Uint8Array%object.secondaryStringTag.close% %list.openBracket#[%%list.closeBracket#]%%item.after#,%␊ + %diffGutters.expected#+ % %object.ctor.open%Uint8Array%object.ctor.close% %list.openBracket#[%%list.closeBracket#]%%item.after#,%␊ + %diffGutters.padding# %%list.closeBracket#]%` + ## diffs boxed primitives with extra properties > Snapshot 1 @@ -1007,6 +1043,24 @@ Generated by [AVA](https://ava.li). %diffGutters.padding# % %number.open%2%number.close%%item.after#,%␊ %diffGutters.padding# %%object.closeBracket#}%` +> Snapshot 3 + + `%diffGutters.padding# %%object.ctor.open%Set%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.actual#- % %object.ctor.open%Foo%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.actual#- % foo%property.separator#: %%string.line.open#'%%string.open%foo%string.close%%string.line.close#'%%property.after#,%␊ + %diffGutters.actual#- % %object.closeBracket#}%%item.after#,%␊ + %diffGutters.expected#+ % %object.ctor.open%Bar%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.expected#+ % bar%property.separator#: %%string.line.open#'%%string.open%bar%string.close%%string.line.close#'%%property.after#,%␊ + %diffGutters.expected#+ % %object.closeBracket#}%%item.after#,%␊ + %diffGutters.padding# %%object.closeBracket#}%` + +> Snapshot 4 + + `%diffGutters.padding# %%object.ctor.open%Set%object.ctor.close% %object.openBracket#{%␊ + %diffGutters.actual#- % %object.ctor.open%Buffer%object.ctor.close% %object.secondaryStringTag.open#@%Uint8Array%object.secondaryStringTag.close% %list.openBracket#[%%list.closeBracket#]%%item.after#,%␊ + %diffGutters.expected#+ % %object.ctor.open%Uint8Array%object.ctor.close% %list.openBracket#[%%list.closeBracket#]%%item.after#,%␊ + %diffGutters.padding# %%object.closeBracket#}%` + ## diffs single line strings > Snapshot 1 diff --git a/test/snapshots/diff.js.snap b/test/snapshots/diff.js.snap index 288ce034ec4808999ab0fd3fd9daaca6f46e73ec..ee3b34489b1b3be30c089f63b3feb09be1ede43b 100644 GIT binary patch literal 4658 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 J5^KTx002o@uipRw