Skip to content

Commit

Permalink
Fix for #6138: Deep compare set values and map keys (#6150)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisblossom authored and cpojer committed May 22, 2018
1 parent e84f154 commit 95c1e53
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@
configuration ([#5976](https://github.com/facebook/jest/pull/5976))
* `[website]` Fix website docs
([#5853](https://github.com/facebook/jest/pull/5853))
* `[expect]` Fix isEqual Set and Map to compare object values and keys
regardless of order ([#6150](https://github.com/facebook/jest/pull/6150))
* `[pretty-format]` [**BREAKING**] Remove undefined props from React elements
([#6162](https://github.com/facebook/jest/pull/6162))

Expand Down
201 changes: 201 additions & 0 deletions packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,88 @@ Difference:
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(Map {["v"] => 1}).toEqual(Map {["v"] => 2}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected value to equal:
<green>Map {[\\"v\\"] => 2}</>
Received:
<red>Map {[\\"v\\"] => 1}</>

Difference:

<green>- Expected</>
<red>+ Received</>

<dim> Map {</>
<dim> Array [</>
<dim> \\"v\\",</>
<green>- ] => 2,</>
<red>+ ] => 1,</>
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(Map {[1] => "one", [2] => "two", [3] => "three", [3] => "four"}).not.toEqual(Map {[3] => "three", [3] => "four", [2] => "two", [1] => "one"}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Map {[3] => \\"three\\", [3] => \\"four\\", [2] => \\"two\\", [1] => \\"one\\"}</>
Received:
<red>Map {[1] => \\"one\\", [2] => \\"two\\", [3] => \\"three\\", [3] => \\"four\\"}</>"
`;

exports[`.toEqual() {pass: false} expect(Map {[1] => "one", [2] => "two"}).not.toEqual(Map {[2] => "two", [1] => "one"}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Map {[2] => \\"two\\", [1] => \\"one\\"}</>
Received:
<red>Map {[1] => \\"one\\", [2] => \\"two\\"}</>"
`;

exports[`.toEqual() {pass: false} expect(Map {[1] => Map {[1] => "one"}, [2] => Map {[2] => "two"}}).not.toEqual(Map {[2] => Map {[2] => "two"}, [1] => Map {[1] => "one"}}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Map {[2] => Map {[2] => \\"two\\"}, [1] => Map {[1] => \\"one\\"}}</>
Received:
<red>Map {[1] => Map {[1] => \\"one\\"}, [2] => Map {[2] => \\"two\\"}}</>"
`;

exports[`.toEqual() {pass: false} expect(Map {[1] => Map {[1] => "one"}}).toEqual(Map {[1] => Map {[1] => "two"}}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected value to equal:
<green>Map {[1] => Map {[1] => \\"two\\"}}</>
Received:
<red>Map {[1] => Map {[1] => \\"one\\"}}</>

Difference:

<green>- Expected</>
<red>+ Received</>

<yellow>@@ -2,8 +2,8 @@</>
<dim> Array [</>
<dim> 1,</>
<dim> ] => Map {</>
<dim> Array [</>
<dim> 1,</>
<green>- ] => \\"two\\",</>
<red>+ ] => \\"one\\",</>
<dim> },</>
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(Map {{"a": 1} => "one", {"b": 2} => "two"}).not.toEqual(Map {{"b": 2} => "two", {"a": 1} => "one"}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Map {{\\"b\\": 2} => \\"two\\", {\\"a\\": 1} => \\"one\\"}</>
Received:
<red>Map {{\\"a\\": 1} => \\"one\\", {\\"b\\": 2} => \\"two\\"}</>"
`;

exports[`.toEqual() {pass: false} expect(Map {}).not.toEqual(Map {}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expand Down Expand Up @@ -2354,6 +2436,92 @@ Difference:
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(Map {1 => ["one"], 2 => ["two"]}).not.toEqual(Map {2 => ["two"], 1 => ["one"]}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Map {2 => [\\"two\\"], 1 => [\\"one\\"]}</>
Received:
<red>Map {1 => [\\"one\\"], 2 => [\\"two\\"]}</>"
`;

exports[`.toEqual() {pass: false} expect(Set {[1], [2], [3], [3]}).not.toEqual(Set {[3], [3], [2], [1]}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Set {[3], [3], [2], [1]}</>
Received:
<red>Set {[1], [2], [3], [3]}</>"
`;

exports[`.toEqual() {pass: false} expect(Set {[1], [2]}).not.toEqual(Set {[2], [1]}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Set {[2], [1]}</>
Received:
<red>Set {[1], [2]}</>"
`;

exports[`.toEqual() {pass: false} expect(Set {[1], [2]}).toEqual(Set {[1], [2], [2]}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected value to equal:
<green>Set {[1], [2], [2]}</>
Received:
<red>Set {[1], [2]}</>

Difference:

<green>- Expected</>
<red>+ Received</>

<yellow>@@ -3,9 +3,6 @@</>
<dim> 1,</>
<dim> ],</>
<dim> Array [</>
<dim> 2,</>
<dim> ],</>
<green>- Array [</>
<green>- 2,</>
<green>- ],</>
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(Set {[1], [2]}).toEqual(Set {[1], [2], [3]}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected value to equal:
<green>Set {[1], [2], [3]}</>
Received:
<red>Set {[1], [2]}</>

Difference:

<green>- Expected</>
<red>+ Received</>

<yellow>@@ -3,9 +3,6 @@</>
<dim> 1,</>
<dim> ],</>
<dim> Array [</>
<dim> 2,</>
<dim> ],</>
<green>- Array [</>
<green>- 3,</>
<green>- ],</>
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(Set {{"a": 1}, {"b": 2}}).not.toEqual(Set {{"b": 2}, {"a": 1}}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Set {{\\"b\\": 2}, {\\"a\\": 1}}</>
Received:
<red>Set {{\\"a\\": 1}, {\\"b\\": 2}}</>"
`;

exports[`.toEqual() {pass: false} expect(Set {}).not.toEqual(Set {}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expand Down Expand Up @@ -2421,6 +2589,39 @@ Difference:
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(Set {Set {[1]}, Set {[2]}}).not.toEqual(Set {Set {[2]}, Set {[1]}}) 1`] = `
"<dim>expect(</><red>received</><dim>).not.toEqual(</><green>expected</><dim>)</>

Expected value to not equal:
<green>Set {Set {[2]}, Set {[1]}}</>
Received:
<red>Set {Set {[1]}, Set {[2]}}</>"
`;

exports[`.toEqual() {pass: false} expect(Set {Set {1}, Set {2}}).toEqual(Set {Set {1}, Set {3}}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected value to equal:
<green>Set {Set {1}, Set {3}}</>
Received:
<red>Set {Set {1}, Set {2}}</>

Difference:

<green>- Expected</>
<red>+ Received</>

<dim> Set {</>
<dim> Set {</>
<dim> 1,</>
<dim> },</>
<dim> Set {</>
<green>- 3,</>
<red>+ 2,</>
<dim> },</>
<dim> }</>"
`;

exports[`.toEqual() {pass: false} expect(false).toEqual(ObjectContaining {"a": 2}) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expand Down
38 changes: 38 additions & 0 deletions packages/expect/src/__tests__/matchers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,23 @@ describe('.toEqual()', () => {
[new Map(), new Set()],
[new Set([1, 2]), new Set()],
[new Set([1, 2]), new Set([1, 2, 3])],
[new Set([[1], [2]]), new Set([[1], [2], [3]])],
[new Set([[1], [2]]), new Set([[1], [2], [2]])],
[
new Set([new Set([1]), new Set([2])]),
new Set([new Set([1]), new Set([3])]),
],
[Immutable.Set([1, 2]), Immutable.Set()],
[Immutable.Set([1, 2]), Immutable.Set([1, 2, 3])],
[Immutable.OrderedSet([1, 2]), Immutable.OrderedSet([2, 1])],
[new Map([[1, 'one'], [2, 'two']]), new Map([[1, 'one']])],
[new Map([['a', 0]]), new Map([['b', 0]])],
[new Map([['v', 1]]), new Map([['v', 2]])],
[new Map([[['v'], 1]]), new Map([[['v'], 2]])],
[
new Map([[[1], new Map([[[1], 'one']])]]),
new Map([[[1], new Map([[[1], 'two']])]]),
],
[Immutable.Map({a: 0}), Immutable.Map({b: 0})],
[Immutable.Map({v: 1}), Immutable.Map({v: 2})],
[
Expand Down Expand Up @@ -304,6 +315,13 @@ describe('.toEqual()', () => {
[new Set(), new Set()],
[new Set([1, 2]), new Set([1, 2])],
[new Set([1, 2]), new Set([2, 1])],
[new Set([[1], [2]]), new Set([[2], [1]])],
[
new Set([new Set([[1]]), new Set([[2]])]),
new Set([new Set([[2]]), new Set([[1]])]),
],
[new Set([[1], [2], [3], [3]]), new Set([[3], [3], [2], [1]])],
[new Set([{a: 1}, {b: 2}]), new Set([{b: 2}, {a: 1}])],
[Immutable.Set(), Immutable.Set()],
[Immutable.Set([1, 2]), Immutable.Set([1, 2])],
[Immutable.Set([1, 2]), Immutable.Set([2, 1])],
Expand All @@ -312,6 +330,26 @@ describe('.toEqual()', () => {
[new Map(), new Map()],
[new Map([[1, 'one'], [2, 'two']]), new Map([[1, 'one'], [2, 'two']])],
[new Map([[1, 'one'], [2, 'two']]), new Map([[2, 'two'], [1, 'one']])],
[
new Map([[[1], 'one'], [[2], 'two'], [[3], 'three'], [[3], 'four']]),
new Map([[[3], 'three'], [[3], 'four'], [[2], 'two'], [[1], 'one']]),
],
[
new Map([[[1], new Map([[[1], 'one']])], [[2], new Map([[[2], 'two']])]]),
new Map([[[2], new Map([[[2], 'two']])], [[1], new Map([[[1], 'one']])]]),
],
[
new Map([[[1], 'one'], [[2], 'two']]),
new Map([[[2], 'two'], [[1], 'one']]),
],
[
new Map([[{a: 1}, 'one'], [{b: 2}, 'two']]),
new Map([[{b: 2}, 'two'], [{a: 1}, 'one']]),
],
[
new Map([[1, ['one']], [2, ['two']]]),
new Map([[2, ['two']], [1, ['one']]]),
],
[Immutable.Map(), Immutable.Map()],
[
Immutable.Map()
Expand Down
34 changes: 30 additions & 4 deletions packages/expect/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,18 @@ export const iterableEquality = (a: any, b: any) => {
let allFound = true;
for (const aValue of a) {
if (!b.has(aValue)) {
allFound = false;
break;
let has = false;
for (const bValue of b) {
const isEqual = equals(aValue, bValue, [iterableEquality]);
if (isEqual === true) {
has = true;
}
}

if (has === false) {
allFound = false;
break;
}
}
}
if (allFound) {
Expand All @@ -142,8 +152,24 @@ export const iterableEquality = (a: any, b: any) => {
!b.has(aEntry[0]) ||
!equals(aEntry[1], b.get(aEntry[0]), [iterableEquality])
) {
allFound = false;
break;
let has = false;
for (const bEntry of b) {
const matchedKey = equals(aEntry[0], bEntry[0], [iterableEquality]);

let matchedValue = false;
if (matchedKey === true) {
matchedValue = equals(aEntry[1], bEntry[1], [iterableEquality]);
}

if (matchedValue === true) {
has = true;
}
}

if (has === false) {
allFound = false;
break;
}
}
}
if (allFound) {
Expand Down

0 comments on commit 95c1e53

Please sign in to comment.