diff --git a/packages/expect-utils/src/utils.ts b/packages/expect-utils/src/utils.ts index 32a403ba4874..0c1cc7b243fe 100644 --- a/packages/expect-utils/src/utils.ts +++ b/packages/expect-utils/src/utils.ts @@ -43,6 +43,17 @@ const hasPropertyInObject = (object: object, key: string | symbol): boolean => { ); }; +// Retrieves an object's keys for evaluation by getObjectSubset. This evaluates +// the prototype chain for string keys but not for symbols. (Otherwise, it +// could find values such as a Set or Map's Symbol.toStringTag, with unexpected +// results.) +// +// Compare with subsetEquality's use of Reflect.ownKeys. +const getObjectKeys = (object: object) => [ + ...Object.keys(object), + ...Object.getOwnPropertySymbols(object), +]; + export const getPath = ( object: Record, propertyPath: string | Array, @@ -131,7 +142,7 @@ export const getObjectSubset = ( const trimmed: any = {}; seenReferences.set(object, trimmed); - Object.keys(object) + getObjectKeys(object) .filter(key => hasPropertyInObject(subset, key)) .forEach(key => { trimmed[key] = seenReferences.has(object[key]) @@ -144,7 +155,7 @@ export const getObjectSubset = ( ); }); - if (Object.keys(trimmed).length > 0) { + if (getObjectKeys(trimmed).length > 0) { return trimmed; } } diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index f02029f00d96..31c26a85f106 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -4140,13 +4140,13 @@ exports[`toMatchObject() {pass: false} expect({"a": "a", "c": "d"}).toMatchObjec exports[`toMatchObject() {pass: false} expect({"a": "b", "c": "d", Symbol(jest): "jest"}).toMatchObject({"a": "c", Symbol(jest): Any}) 1`] = ` expect(received).toMatchObject(expected) -- Expected - 2 +- Expected - 1 + Received + 1 Object { - "a": "c", -- Symbol(jest): Any, + "a": "b", + Symbol(jest): Any, } `;