diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index aa0d250d4cb4..96ff8dbb4fbe 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -4314,6 +4314,13 @@ exports[`toMatchObject() {pass: true} expect({"a": undefined}).toMatchObject({"a Expected: not {"a": undefined} `; +exports[`toMatchObject() {pass: true} expect({}).toMatchObject({"a": undefined, "b": "b", "c": "c"}) 1`] = ` +expect(received).not.toMatchObject(expected) + +Expected: not {"a": undefined, "b": "b", "c": "c"} +Received: {} +`; + exports[`toMatchObject() {pass: true} expect({}).toMatchObject({"a": undefined, "b": "b"}) 1`] = ` expect(received).not.toMatchObject(expected) @@ -4321,6 +4328,13 @@ Expected: not {"a": undefined, "b": "b"} Received: {} `; +exports[`toMatchObject() {pass: true} expect({}).toMatchObject({"d": 4}) 1`] = ` +expect(received).not.toMatchObject(expected) + +Expected: not {"d": 4} +Received: {} +`; + exports[`toMatchObject() {pass: true} expect(2015-11-30T00:00:00.000Z).toMatchObject(2015-11-30T00:00:00.000Z) 1`] = ` expect(received).not.toMatchObject(expected) diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 4223f4e53475..0cf0b703f34b 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -1958,6 +1958,22 @@ describe('toMatchObject()', () => { } } + class Sub extends Foo { + get c() { + return 'c'; + } + } + + const withDefineProperty = (obj, key, val) => { + Object.defineProperty(obj, key, { + get() { + return val; + }, + }); + + return obj; + }; + const testNotToMatchSnapshots = tuples => { tuples.forEach(([n1, n2]) => { it(`{pass: true} expect(${stringify(n1)}).toMatchObject(${stringify( @@ -2082,6 +2098,11 @@ describe('toMatchObject()', () => { {a: 'b', c: 'd', [Symbol.for('jest')]: 'jest'}, {a: 'b', c: 'd', [Symbol.for('jest')]: 'jest'}, ], + // These snapshots will show {} as the object because the properties + // are not enumerable. We will need to somehow make the serialization of + // these keys a little smarter before reporting accurately. + [new Sub(), {a: undefined, b: 'b', c: 'c'}], + [withDefineProperty(new Sub(), 'd', 4), {d: 4}], ]); testToMatchSnapshots([ diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index d386c8ad8edf..26570c0ae29a 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -21,6 +21,9 @@ type GetPath = { value?: unknown; }; +const hasPropertyInObject = (object: object, key: string) => + typeof object === 'object' && key in object; + // Return whether object instance inherits getter from its class. const hasGetterFromConstructor = (object: object, key: string) => { const constructor = object.constructor; @@ -299,7 +302,7 @@ export const subsetEquality = ( } const result = object != null && - hasOwnProperty(object, key) && + hasPropertyInObject(object, key) && equals(object[key], subset[key], [ iterableEquality, subsetEqualityWithContext(seenReferences),