diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index 5a3e468bb84b..6e9c035453aa 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -3688,6 +3688,23 @@ Difference: }" `; +exports[`toMatchObject() {pass: false} expect({"a": "b"}).toMatchObject({"c": "d"}) 1`] = ` +"expect(received).toMatchObject(expected) + +Expected value to match object: + {\\"c\\": \\"d\\"} +Received: + {\\"a\\": \\"b\\"} +Difference: +- Expected ++ Received + + Object { +- \\"c\\": \\"d\\", ++ \\"a\\": \\"b\\", + }" +`; + exports[`toMatchObject() {pass: false} expect({"a": [{"a": "a", "b": "b"}]}).toMatchObject({"a": [{"a": "c"}]}) 1`] = ` "expect(received).toMatchObject(expected) @@ -4026,6 +4043,15 @@ Received: {\\"a\\": \\"b\\", \\"t\\": {\\"x\\": {\\"r\\": \\"r\\"}, \\"z\\": \\"z\\"}}" `; +exports[`toMatchObject() {pass: true} expect({"a": "b"}).toMatchObject({"a": "b"}) 1`] = ` +"expect(received).not.toMatchObject(expected) + +Expected value not to match object: + {\\"a\\": \\"b\\"} +Received: + {\\"a\\": \\"b\\"}" +`; + exports[`toMatchObject() {pass: true} expect({"a": [{"a": "a", "b": "b"}]}).toMatchObject({"a": [{"a": "a"}]}) 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 344e451b55e4..83662ae03c41 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -1142,6 +1142,7 @@ describe('toMatchObject()', () => { [new Error('foo'), new Error('foo')], [new Error('bar'), {message: 'bar'}], [new Foo(), {a: undefined, b: 'b'}], + [Object.assign(Object.create(null), {a: 'b'}), {a: 'b'}], ].forEach(([n1, n2]) => { it(`{pass: true} expect(${stringify(n1)}).toMatchObject(${stringify( n2, @@ -1178,6 +1179,7 @@ describe('toMatchObject()', () => { [[1, 2, 3], [2, 3, 1]], [[1, 2, 3], [1, 2, 2]], [new Error('foo'), new Error('bar')], + [Object.assign(Object.create(null), {a: 'b'}), {c: 'd'}], ].forEach(([n1, n2]) => { it(`{pass: false} expect(${stringify(n1)}).toMatchObject(${stringify( n2, diff --git a/packages/expect/src/utils.js b/packages/expect/src/utils.js index 2c7de7ab2237..24197cc2c50f 100644 --- a/packages/expect/src/utils.js +++ b/packages/expect/src/utils.js @@ -21,9 +21,17 @@ type GetPath = { value?: any, }; -export const hasOwnProperty = (object: Object, value: string) => - Object.prototype.hasOwnProperty.call(object, value) || - Object.prototype.hasOwnProperty.call(object.constructor.prototype, value); +export const hasOwnProperty = (object: Object, value: string) => { + // Account for objects created using unconventional means such as + // `Object.create(null)`, in which case the `object.constructor` is undefined + // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Custom_and_Null_objects + const objectConstructor = object.constructor || Object; + + return ( + Object.prototype.hasOwnProperty.call(object, value) || + Object.prototype.hasOwnProperty.call(objectConstructor.prototype, value) + ); +}; export const getPath = ( object: Object,