From 9bc6a08d4938c4592544c9761ae86c9a42de888f Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 00:04:10 +0200 Subject: [PATCH 01/11] iterableEquality when given iterator within inequal object --- packages/expect/src/__tests__/utils.test.js | 30 +++++++++++++++++++++ packages/expect/src/utils.ts | 4 +++ 2 files changed, 34 insertions(+) diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.js index 0850053b120a..244fed652455 100644 --- a/packages/expect/src/__tests__/utils.test.js +++ b/packages/expect/src/__tests__/utils.test.js @@ -271,6 +271,36 @@ describe('iterableEquality', () => { ).toBe(false); }); + test('returns false when given iterator within inequal object', () => { + const a = { + [Symbol.iterator]: () => ({next: () => ({done: true})}), + a: [1], + }; + const b = { + [Symbol.iterator]: () => ({next: () => ({done: true})}), + a: [], + }; + + expect(iterableEquality(a, b)).toEqual(false); + }); + + test('returns false when given iterator within inequal nested object', () => { + const a = { + [Symbol.iterator]: () => ({next: () => ({done: true})}), + a: { + b: [1], + }, + }; + const b = { + [Symbol.iterator]: () => ({next: () => ({done: true})}), + a: { + b: [], + }, + }; + + expect(iterableEquality(a, b)).toEqual(false); + }); + test('returns true when given circular Set shape', () => { const a1 = new Set(); const a2 = new Set(); diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index 2c0f8837a5a3..40576d5f04be 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -251,6 +251,10 @@ export const iterableEquality = ( return false; } + if (isObjectWithKeys(a) && isObjectWithKeys(b)) { + return equals(a, b); + } + // Remove the first value from the stack of traversed values. aStack.pop(); bStack.pop(); From 86312c91c8df274ab8295d5afc2a9a6b66e41bf5 Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 10:36:01 +0200 Subject: [PATCH 02/11] remove unnecessary object check --- packages/expect/src/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index 40576d5f04be..c8648f0e504f 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -251,8 +251,8 @@ export const iterableEquality = ( return false; } - if (isObjectWithKeys(a) && isObjectWithKeys(b)) { - return equals(a, b); + if (!equals(a, b)) { + return false; } // Remove the first value from the stack of traversed values. From 7e13ba4a45dfe3b1d1e3447e0e03a22012119543 Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 11:01:51 +0200 Subject: [PATCH 03/11] check equality again only if object has keys --- packages/expect/src/utils.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index c8648f0e504f..b8dd74bead26 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -251,8 +251,10 @@ export const iterableEquality = ( return false; } - if (!equals(a, b)) { - return false; + if (Object.keys(a).length && Object.keys(b).length) { + if (!equals(a, b)) { + return false; + } } // Remove the first value from the stack of traversed values. From 8ec8ab561db7c6bfb80b4e480e9828c79da435b1 Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 11:40:09 +0200 Subject: [PATCH 04/11] ignore iterators while checking other properties --- packages/expect/src/__tests__/utils.test.js | 17 +++++++++++++++-- packages/expect/src/utils.ts | 6 ++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.js index 244fed652455..b091c962b169 100644 --- a/packages/expect/src/__tests__/utils.test.js +++ b/packages/expect/src/__tests__/utils.test.js @@ -271,7 +271,20 @@ describe('iterableEquality', () => { ).toBe(false); }); - test('returns false when given iterator within inequal object', () => { + test('returns true when given iterator within equal objects', () => { + const a = { + [Symbol.iterator]: () => ({next: () => ({done: true})}), + a: [], + }; + const b = { + [Symbol.iterator]: () => ({next: () => ({done: true})}), + a: [], + }; + + expect(iterableEquality(a, b)).toEqual(true); + }); + + test('returns false when given iterator within inequal objects', () => { const a = { [Symbol.iterator]: () => ({next: () => ({done: true})}), a: [1], @@ -284,7 +297,7 @@ describe('iterableEquality', () => { expect(iterableEquality(a, b)).toEqual(false); }); - test('returns false when given iterator within inequal nested object', () => { + test('returns false when given iterator within inequal nested objects', () => { const a = { [Symbol.iterator]: () => ({next: () => ({done: true})}), a: { diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index b8dd74bead26..102c1644cc90 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -251,8 +251,10 @@ export const iterableEquality = ( return false; } - if (Object.keys(a).length && Object.keys(b).length) { - if (!equals(a, b)) { + if (!emptyObject(a) && !emptyObject(b)) { + const aEntries = Object.entries(a); + const bEntries = Object.entries(b); + if (!equals(aEntries, bEntries)) { return false; } } From 53408bd48f3d3541dda09bf95814922317ec7206 Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 12:13:54 +0200 Subject: [PATCH 05/11] remove unnecessary emptyObject check --- packages/expect/src/__tests__/utils.test.js | 6 +++--- packages/expect/src/utils.ts | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.js index b091c962b169..7c0ae5d4478a 100644 --- a/packages/expect/src/__tests__/utils.test.js +++ b/packages/expect/src/__tests__/utils.test.js @@ -281,7 +281,7 @@ describe('iterableEquality', () => { a: [], }; - expect(iterableEquality(a, b)).toEqual(true); + expect(iterableEquality(a, b)).toBe(true); }); test('returns false when given iterator within inequal objects', () => { @@ -294,7 +294,7 @@ describe('iterableEquality', () => { a: [], }; - expect(iterableEquality(a, b)).toEqual(false); + expect(iterableEquality(a, b)).toBe(false); }); test('returns false when given iterator within inequal nested objects', () => { @@ -311,7 +311,7 @@ describe('iterableEquality', () => { }, }; - expect(iterableEquality(a, b)).toEqual(false); + expect(iterableEquality(a, b)).toBe(false); }); test('returns true when given circular Set shape', () => { diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index 102c1644cc90..e3a225947e75 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -251,12 +251,10 @@ export const iterableEquality = ( return false; } - if (!emptyObject(a) && !emptyObject(b)) { - const aEntries = Object.entries(a); - const bEntries = Object.entries(b); - if (!equals(aEntries, bEntries)) { - return false; - } + const aEntries = Object.entries(a); + const bEntries = Object.entries(b); + if (!equals(aEntries, bEntries)) { + return false; } // Remove the first value from the stack of traversed values. From 87c4e62fb0782b9b19eb3ef88bf2cc86aa5375c1 Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 12:51:08 +0200 Subject: [PATCH 06/11] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e23216d3f0a3..9e4a44e31be3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `[@jest/runtime, @jest/transform]` Allow custom transforms for JSON dependencies ([#2578](https://github.com/facebook/jest/pull/2578)) - `[jest-core]` Make `detectOpenHandles` imply `runInBand` ([#8283](https://github.com/facebook/jest/pull/8283)) - `[jest-haste-map]` Fix the `mapper` option which was incorrectly ignored ([#8299](https://github.com/facebook/jest/pull/8299)) +- `[expect]` Fix `iterableEquality` ignores other properties ([#8359](https://github.com/facebook/jest/pull/8359)) ### Chore & Maintenance From 84f8bda38feb074660b0e0c2efa6c044559c4e74 Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 13:41:22 +0200 Subject: [PATCH 07/11] add getObjectEntries instead of Object.entries --- packages/expect/src/__tests__/utils.test.js | 13 +++++++++++++ packages/expect/src/utils.ts | 7 +++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.js index 7c0ae5d4478a..4c1ab5668bda 100644 --- a/packages/expect/src/__tests__/utils.test.js +++ b/packages/expect/src/__tests__/utils.test.js @@ -12,6 +12,7 @@ const {stringify} = require('jest-matcher-utils'); const { emptyObject, getObjectSubset, + getObjectEntries, getPath, hasOwnProperty, subsetEquality, @@ -166,6 +167,18 @@ describe('getObjectSubset()', () => { }); }); +describe('getObjectEntries', () => { + test('returns an empty array when called with null', () => { + expect(getObjectEntries(null)).toEqual([]); + }); + test('returns an empty array when called with undefined', () => { + expect(getObjectEntries(undefined)).toEqual([]); + }); + test('returns object entries', () => { + expect(getObjectEntries({ a: 1, b: 2 })).toEqual([['a', 1], ['b', 2]]); + }); +}) + describe('emptyObject()', () => { test('matches an empty object', () => { expect(emptyObject({})).toBe(true); diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index e3a225947e75..ee5758308318 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -133,6 +133,9 @@ export const getObjectSubset = (object: any, subset: any): any => { return object; }; +export const getObjectEntries = (object: any): Array => + object == null ? [] : Object.keys(object).map((key) => [key, object[key]]) + const IteratorSymbol = Symbol.iterator; const hasIterator = (object: any) => @@ -251,8 +254,8 @@ export const iterableEquality = ( return false; } - const aEntries = Object.entries(a); - const bEntries = Object.entries(b); + const aEntries = getObjectEntries(a); + const bEntries = getObjectEntries(b); if (!equals(aEntries, bEntries)) { return false; } From 80680544a2462e4c57c552331644731c85cfd0a9 Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 13:42:42 +0200 Subject: [PATCH 08/11] import in ascending order --- packages/expect/src/__tests__/utils.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.js index 4c1ab5668bda..303a249c5ca3 100644 --- a/packages/expect/src/__tests__/utils.test.js +++ b/packages/expect/src/__tests__/utils.test.js @@ -11,8 +11,8 @@ const {stringify} = require('jest-matcher-utils'); const { emptyObject, - getObjectSubset, getObjectEntries, + getObjectSubset, getPath, hasOwnProperty, subsetEquality, From 3cd2b4e1506645ca84e621d817311e9878be44cc Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Mon, 22 Apr 2019 14:23:03 +0200 Subject: [PATCH 09/11] better type for getObjectEntries - fix linting issue --- packages/expect/src/__tests__/utils.test.js | 4 ++-- packages/expect/src/utils.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.js index 303a249c5ca3..dbb5f2b6ef18 100644 --- a/packages/expect/src/__tests__/utils.test.js +++ b/packages/expect/src/__tests__/utils.test.js @@ -175,9 +175,9 @@ describe('getObjectEntries', () => { expect(getObjectEntries(undefined)).toEqual([]); }); test('returns object entries', () => { - expect(getObjectEntries({ a: 1, b: 2 })).toEqual([['a', 1], ['b', 2]]); + expect(getObjectEntries({a: 1, b: 2})).toEqual([['a', 1], ['b', 2]]); }); -}) +}); describe('emptyObject()', () => { test('matches an empty object', () => { diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index ee5758308318..02330e9a57d9 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -133,8 +133,12 @@ export const getObjectSubset = (object: any, subset: any): any => { return object; }; -export const getObjectEntries = (object: any): Array => - object == null ? [] : Object.keys(object).map((key) => [key, object[key]]) +// NOTE: Should be removed after dropping node@6.x support, +// and we should use (Object.entries) +export const getObjectEntries: typeof Object.entries = ( + object: any, +): Array<[string, any]> => + object == null ? [] : Object.keys(object).map(key => [key, object[key]]); const IteratorSymbol = Symbol.iterator; From 416f5b3ee7deb555f4ff830e878ceb0ff8d8c7ae Mon Sep 17 00:00:00 2001 From: Abdel-Rhman Ragab Date: Sat, 23 Nov 2019 21:25:39 +0100 Subject: [PATCH 10/11] replace getObjectEntries with Object.entries --- CHANGELOG.md | 1 - packages/expect/src/__tests__/utils.test.js | 13 ------------- packages/expect/src/utils.ts | 11 ++--------- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c4e1186eaf8..e06f30ef60df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -184,7 +184,6 @@ - `[jest-runtime]` Fix virtual mocks not being unmockable after previously being mocked ([#8396](https://github.com/facebook/jest/pull/8396)) - `[jest-transform]` Replace special characters in transform cache filenames to support Windows ([#8353](https://github.com/facebook/jest/pull/8353)) - `[jest-config]` Allow exactly one project ([#7498](https://github.com/facebook/jest/pull/7498)) ->>>>>>> d74da1a0dde8f17997022f40a4adc07823d50c69 ### Chore & Maintenance diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.js index dd967900cd2e..000c83f8f9da 100644 --- a/packages/expect/src/__tests__/utils.test.js +++ b/packages/expect/src/__tests__/utils.test.js @@ -11,7 +11,6 @@ const {stringify} = require('jest-matcher-utils'); const { emptyObject, - getObjectEntries, getObjectSubset, getPath, hasOwnProperty, @@ -276,18 +275,6 @@ describe('getObjectSubset', () => { }); }); -describe('getObjectEntries', () => { - test('returns an empty array when called with null', () => { - expect(getObjectEntries(null)).toEqual([]); - }); - test('returns an empty array when called with undefined', () => { - expect(getObjectEntries(undefined)).toEqual([]); - }); - test('returns object entries', () => { - expect(getObjectEntries({a: 1, b: 2})).toEqual([['a', 1], ['b', 2]]); - }); -}); - describe('emptyObject()', () => { test('matches an empty object', () => { expect(emptyObject({})).toBe(true); diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index 8591eac08f93..6828d1870055 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -142,13 +142,6 @@ export const getObjectSubset = ( return object; }; -// NOTE: Should be removed after dropping node@6.x support, -// and we should use (Object.entries) -export const getObjectEntries: typeof Object.entries = ( - object: any, -): Array<[string, any]> => - object == null ? [] : Object.keys(object).map(key => [key, object[key]]); - const IteratorSymbol = Symbol.iterator; const hasIterator = (object: any) => @@ -267,8 +260,8 @@ export const iterableEquality = ( return false; } - const aEntries = getObjectEntries(a); - const bEntries = getObjectEntries(b); + const aEntries = Object.entries(a); + const bEntries = Object.entries(b); if (!equals(aEntries, bEntries)) { return false; } From 5a46db11e23d68e4697bb2f49e5c855da93499d5 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 24 Feb 2022 21:04:24 +0100 Subject: [PATCH 11/11] move changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec69a36a3ed9..4ae06c8a4e65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ - `[expect]` Move typings of `.not`, `.rejects` and `.resolves` modifiers outside of `Matchers` interface ([#12346](https://github.com/facebook/jest/pull/12346)) - `[expect]` Throw useful error if `expect.extend` is called with invalid matchers ([#12488](https://github.com/facebook/jest/pull/12488)) +- `[expect]` Fix `iterableEquality` ignores other properties ([#8359](https://github.com/facebook/jest/pull/8359)) - `[jest-config]` Correctly detect CI environment and update snapshots accordingly ([#12378](https://github.com/facebook/jest/pull/12378)) - `[jest-config]` Pass `moduleTypes` to `ts-node` to enforce CJS when transpiling ([#12397](https://github.com/facebook/jest/pull/12397)) - `[jest-config, jest-haste-map]` Allow searching for tests in `node_modules` by exposing `retainAllFiles` ([#11084](https://github.com/facebook/jest/pull/11084)) @@ -1028,8 +1029,6 @@ ## 25.1.0 -- `[expect]` Fix `iterableEquality` ignores other properties ([#8359](https://github.com/facebook/jest/pull/8359)) - ### Features - `[babel-plugin-jest-hoist]` Show codeframe on static hoisting issues ([#8865](https://github.com/facebook/jest/pull/8865))