From 20c4b66690c0b2ee40cd1be981527705853af56e Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Thu, 31 Aug 2017 13:13:44 -0700 Subject: [PATCH] fix Map equality test #4303 added code to check Set equality in an order-independent way, but applied that logic to all iterable objects. This change limits the scope of the special-case to just Set and Map, and corrects the Map case to test that both keys and values are equal. --- .../__snapshots__/matchers.test.js.snap | 135 ++++++++++++++++++ .../expect/src/__tests__/matchers.test.js | 10 ++ packages/expect/src/utils.js | 27 +++- 3 files changed, 165 insertions(+), 7 deletions(-) diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index 9ad0022d6ade..30279159d8fc 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -1954,6 +1954,35 @@ Received: [1, 2, 3]" `; +exports[`.toEqual() {pass: false} expect([1, 2]).not.toEqual([1, 2]) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + [1, 2] +Received: + [1, 2]" +`; + +exports[`.toEqual() {pass: false} expect([1, 2]).toEqual([2, 1]) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + [2, 1] +Received: + [1, 2] + +Difference: + +- Expected ++ Received + + Array [ ++ 1, + 2, +- 1, + ]" +`; + exports[`.toEqual() {pass: false} expect([1, 3]).toEqual(ArrayContaining [1, 2]) 1`] = ` "expect(received).toEqual(expected) @@ -1975,6 +2004,34 @@ Difference: ]" `; +exports[`.toEqual() {pass: false} expect([1]).not.toEqual([1]) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + [1] +Received: + [1]" +`; + +exports[`.toEqual() {pass: false} expect([1]).toEqual([2]) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + [2] +Received: + [1] + +Difference: + +- Expected ++ Received + + Array [ +- 2, ++ 1, + ]" +`; + exports[`.toEqual() {pass: false} expect([Function anonymous]).not.toEqual(Any) 1`] = ` "expect(received).not.toEqual(expected) @@ -2051,6 +2108,15 @@ Received: {\\"a\\": 99}" `; +exports[`.toEqual() {pass: false} expect({}).not.toEqual({}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + {} +Received: + {}" +`; + exports[`.toEqual() {pass: false} expect(0).toEqual(-0) 1`] = ` "expect(received).toEqual(expected) @@ -2095,6 +2161,66 @@ Difference: Comparing two different types of values. Expected array but received number." `; +exports[`.toEqual() {pass: false} expect(Map {"a" => 0}).toEqual(Map {"b" => 0}) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Map {\\"b\\" => 0} +Received: + Map {\\"a\\" => 0} + +Difference: + +- Expected ++ Received + + Map { +- \\"b\\" => 0, ++ \\"a\\" => 0, + }" +`; + +exports[`.toEqual() {pass: false} expect(Map {"v" => 1}).toEqual(Map {"v" => 2}) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Map {\\"v\\" => 2} +Received: + Map {\\"v\\" => 1} + +Difference: + +- Expected ++ Received + + Map { +- \\"v\\" => 2, ++ \\"v\\" => 1, + }" +`; + +exports[`.toEqual() {pass: false} expect(Map {}).not.toEqual(Map {}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Map {} +Received: + Map {}" +`; + +exports[`.toEqual() {pass: false} expect(Map {}).toEqual(Set {}) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Set {} +Received: + Map {} + +Difference: + + Comparing two different types of values. Expected set but received map." +`; + exports[`.toEqual() {pass: false} expect(Map {1 => "one", 2 => "two"}).not.toEqual(Map {1 => "one", 2 => "two"}) 1`] = ` "expect(received).not.toEqual(expected) @@ -2132,6 +2258,15 @@ Difference: }" `; +exports[`.toEqual() {pass: false} expect(Set {}).not.toEqual(Set {}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Set {} +Received: + Set {}" +`; + exports[`.toEqual() {pass: false} expect(Set {1, 2}).not.toEqual(Set {1, 2}) 1`] = ` "expect(received).not.toEqual(expected) diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 22ad6db509d0..260822431bc9 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -167,9 +167,14 @@ describe('.toEqual()', () => { [{a: 5}, {b: 6}], ['banana', 'apple'], [null, undefined], + [[1], [2]], + [[1, 2], [2, 1]], + [new Map(), new Set()], [new Set([1, 2]), new Set()], [new Set([1, 2]), new Set([1, 2, 3])], [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]])], [{a: 1, b: 2}, jestExpect.objectContaining({a: 2})], [false, jestExpect.objectContaining({a: 2})], [[1, 3], jestExpect.arrayContaining([1, 2])], @@ -198,9 +203,14 @@ describe('.toEqual()', () => { [true, true], [1, 1], ['abc', 'abc'], + [[1], [1]], + [[1, 2], [1, 2]], + [{}, {}], [{a: 99}, {a: 99}], + [new Set(), new Set()], [new Set([1, 2]), new Set([1, 2])], [new Set([1, 2]), new Set([2, 1])], + [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']])], [{a: 1, b: 2}, jestExpect.objectContaining({a: 1})], diff --git a/packages/expect/src/utils.js b/packages/expect/src/utils.js index 750d26861cfc..8d8467922c48 100644 --- a/packages/expect/src/utils.js +++ b/packages/expect/src/utils.js @@ -114,16 +114,29 @@ export const iterableEquality = (a: any, b: any) => { if (a.size !== undefined) { if (a.size !== b.size) { return false; - } else { - const args = []; + } else if (a instanceof Set) { + let allFound = true; for (const aValue of a) { - args.push(aValue); + if (!b.has(aValue)) { + allFound = false; + break; + } } - for (const bValue of b) { - args.push(bValue); + if (allFound) { + return true; + } + } else if (a instanceof Map) { + let allFound = true; + for (const aEntry of a) { + if ( + !b.has(aEntry[0]) || + !equals(aEntry[1], b.get(aEntry[0]), [iterableEquality]) + ) { + allFound = false; + break; + } } - const merged = new a.constructor(args); - if (merged.size === a.size) { + if (allFound) { return true; } }