From 97f030814628efe7877e6ad655bb55867268b304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20Pokorn=C3=BD?= Date: Fri, 9 Feb 2018 10:14:13 +0100 Subject: [PATCH] Ignore order on unordered Immutable.js structures (#5501) --- .../__snapshots__/matchers.test.js.snap | 288 ++++++++++++++++++ .../expect/src/__tests__/matchers.test.js | 56 ++++ packages/expect/src/jasmine_utils.js | 21 ++ packages/expect/src/utils.js | 11 +- 4 files changed, 373 insertions(+), 3 deletions(-) diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index 40ab85b5d621..7a1471e697b2 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -2247,6 +2247,294 @@ Difference: Comparing two different types of values. Expected array but received number." `; +exports[`.toEqual() {pass: false} expect(Immutable.List [1, 2]).not.toEqual(Immutable.List [1, 2]) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.List [1, 2] +Received: + Immutable.List [1, 2]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.List [1, 2]).toEqual(Immutable.List [2, 1]) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.List [2, 1] +Received: + Immutable.List [1, 2] + +Difference: + +- Expected ++ Received + + Immutable.List [ ++ 1, + 2, +- 1, + ]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.List [1]).not.toEqual(Immutable.List [1]) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.List [1] +Received: + Immutable.List [1]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.List [1]).toEqual(Immutable.List [2]) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.List [2] +Received: + Immutable.List [1] + +Difference: + +- Expected ++ Received + + Immutable.List [ +- 2, ++ 1, + ]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Map {"1": Immutable.Map {"2": {"a": 99}}}).not.toEqual(Immutable.Map {"1": Immutable.Map {"2": {"a": 99}}}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.Map {\\"1\\": Immutable.Map {\\"2\\": {\\"a\\": 99}}} +Received: + Immutable.Map {\\"1\\": Immutable.Map {\\"2\\": {\\"a\\": 99}}}" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Map {"1": Immutable.Map {"2": {"a": 99}}}).toEqual(Immutable.Map {"1": Immutable.Map {"2": {"a": 11}}}) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.Map {\\"1\\": Immutable.Map {\\"2\\": {\\"a\\": 11}}} +Received: + Immutable.Map {\\"1\\": Immutable.Map {\\"2\\": {\\"a\\": 99}}} + +Difference: + +- Expected ++ Received + + Immutable.Map { + \\"1\\": Immutable.Map { + \\"2\\": Object { +- \\"a\\": 11, ++ \\"a\\": 99, + }, + }, + }" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Map {"a": 0}).toEqual(Immutable.Map {"b": 0}) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.Map {\\"b\\": 0} +Received: + Immutable.Map {\\"a\\": 0} + +Difference: + +- Expected ++ Received + + Immutable.Map { +- \\"b\\": 0, ++ \\"a\\": 0, + }" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Map {"v": 1}).toEqual(Immutable.Map {"v": 2}) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.Map {\\"v\\": 2} +Received: + Immutable.Map {\\"v\\": 1} + +Difference: + +- Expected ++ Received + + Immutable.Map { +- \\"v\\": 2, ++ \\"v\\": 1, + }" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Map {}).not.toEqual(Immutable.Map {}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.Map {} +Received: + Immutable.Map {}" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Map {1: "one", 2: "two"}).not.toEqual(Immutable.Map {1: "one", 2: "two"}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.Map {1: \\"one\\", 2: \\"two\\"} +Received: + Immutable.Map {1: \\"one\\", 2: \\"two\\"}" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Map {1: "one", 2: "two"}).not.toEqual(Immutable.Map {2: "two", 1: "one"}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.Map {2: \\"two\\", 1: \\"one\\"} +Received: + Immutable.Map {1: \\"one\\", 2: \\"two\\"}" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.OrderedMap {1: "one", 2: "two"}).not.toEqual(Immutable.OrderedMap {1: "one", 2: "two"}) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.OrderedMap {1: \\"one\\", 2: \\"two\\"} +Received: + Immutable.OrderedMap {1: \\"one\\", 2: \\"two\\"}" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.OrderedMap {1: "one", 2: "two"}).toEqual(Immutable.OrderedMap {2: "two", 1: "one"}) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.OrderedMap {2: \\"two\\", 1: \\"one\\"} +Received: + Immutable.OrderedMap {1: \\"one\\", 2: \\"two\\"} + +Difference: + +- Expected ++ Received + + Immutable.OrderedMap { ++ 1: \\"one\\", + 2: \\"two\\", +- 1: \\"one\\", + }" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.OrderedSet []).not.toEqual(Immutable.OrderedSet []) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.OrderedSet [] +Received: + Immutable.OrderedSet []" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.OrderedSet [1, 2]).not.toEqual(Immutable.OrderedSet [1, 2]) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.OrderedSet [1, 2] +Received: + Immutable.OrderedSet [1, 2]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.OrderedSet [1, 2]).toEqual(Immutable.OrderedSet [2, 1]) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.OrderedSet [2, 1] +Received: + Immutable.OrderedSet [1, 2] + +Difference: + +- Expected ++ Received + + Immutable.OrderedSet [ ++ 1, + 2, +- 1, + ]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Set []).not.toEqual(Immutable.Set []) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.Set [] +Received: + Immutable.Set []" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Set [1, 2]).not.toEqual(Immutable.Set [1, 2]) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.Set [1, 2] +Received: + Immutable.Set [1, 2]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Set [1, 2]).not.toEqual(Immutable.Set [2, 1]) 1`] = ` +"expect(received).not.toEqual(expected) + +Expected value to not equal: + Immutable.Set [2, 1] +Received: + Immutable.Set [1, 2]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Set [1, 2]).toEqual(Immutable.Set []) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.Set [] +Received: + Immutable.Set [1, 2] + +Difference: + +- Expected ++ Received + +- Immutable.Set [] ++ Immutable.Set [ ++ 1, ++ 2, ++ ]" +`; + +exports[`.toEqual() {pass: false} expect(Immutable.Set [1, 2]).toEqual(Immutable.Set [1, 2, 3]) 1`] = ` +"expect(received).toEqual(expected) + +Expected value to equal: + Immutable.Set [1, 2, 3] +Received: + Immutable.Set [1, 2] + +Difference: + +- Expected ++ Received + + Immutable.Set [ + 1, + 2, +- 3, + ]" +`; + exports[`.toEqual() {pass: false} expect(Map {"a" => 0}).toEqual(Map {"b" => 0}) 1`] = ` "expect(received).toEqual(expected) diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 62c026a26c98..7a3d2805b89a 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -8,6 +8,7 @@ const {stringify} = require('jest-matcher-utils'); const jestExpect = require('../'); +const Immutable = require('immutable'); it('should throw if passed two arguments', () => { expect(() => jestExpect('foo', 'bar')).toThrow( @@ -200,12 +201,31 @@ describe('.toEqual()', () => { [null, undefined], [[1], [2]], [[1, 2], [2, 1]], + [Immutable.List([1]), Immutable.List([2])], + [Immutable.List([1, 2]), Immutable.List([2, 1])], [new Map(), new Set()], [new Set([1, 2]), new Set()], [new Set([1, 2]), new Set([1, 2, 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]])], + [Immutable.Map({a: 0}), Immutable.Map({b: 0})], + [Immutable.Map({v: 1}), Immutable.Map({v: 2})], + [ + Immutable.OrderedMap() + .set(1, 'one') + .set(2, 'two'), + Immutable.OrderedMap() + .set(2, 'two') + .set(1, 'one'), + ], + [ + Immutable.Map({1: Immutable.Map({2: {a: 99}})}), + Immutable.Map({1: Immutable.Map({2: {a: 11}})}), + ], [{a: 1, b: 2}, jestExpect.objectContaining({a: 2})], [false, jestExpect.objectContaining({a: 2})], [[1, 3], jestExpect.arrayContaining([1, 2])], @@ -236,14 +256,50 @@ describe('.toEqual()', () => { ['abc', 'abc'], [[1], [1]], [[1, 2], [1, 2]], + [Immutable.List([1]), Immutable.List([1])], + [Immutable.List([1, 2]), Immutable.List([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])], + [Immutable.Set(), Immutable.Set()], + [Immutable.Set([1, 2]), Immutable.Set([1, 2])], + [Immutable.Set([1, 2]), Immutable.Set([2, 1])], + [Immutable.OrderedSet(), Immutable.OrderedSet()], + [Immutable.OrderedSet([1, 2]), Immutable.OrderedSet([1, 2])], [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']])], + [Immutable.Map(), Immutable.Map()], + [ + Immutable.Map() + .set(1, 'one') + .set(2, 'two'), + Immutable.Map() + .set(1, 'one') + .set(2, 'two'), + ], + [ + Immutable.Map() + .set(1, 'one') + .set(2, 'two'), + Immutable.Map() + .set(2, 'two') + .set(1, 'one'), + ], + [ + Immutable.OrderedMap() + .set(1, 'one') + .set(2, 'two'), + Immutable.OrderedMap() + .set(1, 'one') + .set(2, 'two'), + ], + [ + Immutable.Map({1: Immutable.Map({2: {a: 99}})}), + Immutable.Map({1: Immutable.Map({2: {a: 99}})}), + ], [{a: 1, b: 2}, jestExpect.objectContaining({a: 1})], [[1, 2, 3], jestExpect.arrayContaining([2, 3])], ['abcd', jestExpect.stringContaining('bc')], diff --git a/packages/expect/src/jasmine_utils.js b/packages/expect/src/jasmine_utils.js index 47051a075b34..9e68921a2507 100644 --- a/packages/expect/src/jasmine_utils.js +++ b/packages/expect/src/jasmine_utils.js @@ -275,3 +275,24 @@ export function hasProperty(obj: Object | null, property: string) { return hasProperty(getPrototype(obj), property); } + +// SENTINEL constants are from https://github.com/facebook/immutable-js +const IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; +const IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; +const IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; + +export function isImmutableUnorderedKeyed(maybeKeyed: any) { + return !!( + maybeKeyed && + maybeKeyed[IS_KEYED_SENTINEL] && + !maybeKeyed[IS_ORDERED_SENTINEL] + ); +} + +export function isImmutableUnorderedSet(maybeSet: any) { + return !!( + maybeSet && + maybeSet[IS_SET_SENTINEL] && + !maybeSet[IS_ORDERED_SENTINEL] + ); +} diff --git a/packages/expect/src/utils.js b/packages/expect/src/utils.js index 7d1859b95c65..010f5d9b8d40 100644 --- a/packages/expect/src/utils.js +++ b/packages/expect/src/utils.js @@ -7,7 +7,12 @@ * @flow */ -import {equals, isA} from './jasmine_utils'; +import { + equals, + isA, + isImmutableUnorderedKeyed, + isImmutableUnorderedSet, +} from './jasmine_utils'; type GetPath = { hasEndProp?: boolean, @@ -119,7 +124,7 @@ export const iterableEquality = (a: any, b: any) => { if (a.size !== undefined) { if (a.size !== b.size) { return false; - } else if (isA('Set', a)) { + } else if (isA('Set', a) || isImmutableUnorderedSet(a)) { let allFound = true; for (const aValue of a) { if (!b.has(aValue)) { @@ -130,7 +135,7 @@ export const iterableEquality = (a: any, b: any) => { if (allFound) { return true; } - } else if (isA('Map', a)) { + } else if (isA('Map', a) || isImmutableUnorderedKeyed(a)) { let allFound = true; for (const aEntry of a) { if (