Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/expect/src/jest-expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
const { subset: actualSubset, stripped } = getObjectSubset(
actual,
expected,
customTesters,
)
if ((pass && isNot) || (!pass && !isNot)) {
const msg = utils.getMessage(this, [
Expand Down
12 changes: 10 additions & 2 deletions packages/expect/src/jest-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ export function getObjectKeys(object: object): Array<string | symbol> {
export function getObjectSubset(
object: any,
subset: any,
customTesters: Array<Tester> = [],
customTesters: Array<Tester>,
): { subset: any; stripped: number } {
let stripped = 0

Expand All @@ -702,13 +702,21 @@ export function getObjectSubset(
subsetEquality,
])
) {
// Avoid unnecessary copy which might return Object instead of subclass.
// return "expected" subset to avoid showing irrelavant toMatchObject diff
return subset
}

const trimmed: any = {}
seenReferences.set(object, trimmed)

// preserve constructor for toMatchObject diff
if (typeof object.constructor === 'function' && typeof object.constructor.name === 'string') {
Object.defineProperty(trimmed, 'constructor', {
enumerable: false,
value: object.constructor,
})
}

for (const key of getObjectKeys(object)) {
if (hasPropertyInObject(subset, key)) {
trimmed[key] = seenReferences.has(object[key])
Expand Down
122 changes: 121 additions & 1 deletion test/core/test/jest-expect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -927,12 +927,12 @@ function trim(s: string): string {
function getError(f: () => unknown) {
try {
f()
return expect.unreachable()
}
catch (error) {
const processed = processError(error)
return [stripVTControlCharacters(processed.message), stripVTControlCharacters(trim(processed.diff))]
}
return expect.unreachable()
}

it('toMatchObject error diff', () => {
Expand Down Expand Up @@ -1059,6 +1059,126 @@ it('toMatchObject error diff', () => {
}",
]
`)

// https://github.com/vitest-dev/vitest/issues/6543
class Foo {
constructor(public value: any) {}
}

class Bar {
constructor(public value: any) {}
}

expect(new Foo(0)).toMatchObject(new Bar(0))
expect(new Foo(0)).toMatchObject({ value: 0 })
expect({ value: 0 }).toMatchObject(new Bar(0))

expect(getError(() => expect(new Foo(0)).toMatchObject(new Bar(1)))).toMatchInlineSnapshot(`
[
"expected Foo{ value: +0 } to match object Bar{ value: 1 }",
"- Expected
+ Received

- Bar {
- "value": 1,
+ Foo {
+ "value": 0,
}",
]
`)

expect(getError(() => expect(new Foo(0)).toMatchObject({ value: 1 }))).toMatchInlineSnapshot(`
[
"expected Foo{ value: +0 } to match object { value: 1 }",
"- Expected
+ Received

- Object {
- "value": 1,
+ Foo {
+ "value": 0,
}",
]
`)

expect(getError(() => expect({ value: 0 }).toMatchObject(new Bar(1)))).toMatchInlineSnapshot(`
[
"expected { value: +0 } to match object Bar{ value: 1 }",
"- Expected
+ Received

- Bar {
- "value": 1,
+ Object {
+ "value": 0,
}",
]
`)

expect(getError(() =>
expect({
bad: new Foo(1),
good: new Foo(0),
}).toMatchObject({
bad: new Bar(2),
good: new Bar(0),
}),
)).toMatchInlineSnapshot(`
[
"expected { bad: Foo{ value: 1 }, …(1) } to match object { bad: Bar{ value: 2 }, …(1) }",
"- Expected
+ Received

Object {
- "bad": Bar {
- "value": 2,
+ "bad": Foo {
+ "value": 1,
},
"good": Bar {
"value": 0,
},
}",
]
`)

expect(getError(() =>
expect(new Foo(new Foo(1))).toMatchObject(new Bar(new Bar(0))),
)).toMatchInlineSnapshot(`
[
"expected Foo{ value: Foo{ value: 1 } } to match object Bar{ value: Bar{ value: +0 } }",
"- Expected
+ Received

- Bar {
- "value": Bar {
- "value": 0,
+ Foo {
+ "value": Foo {
+ "value": 1,
},
}",
]
`)

expect(new Foo(new Foo(1))).toMatchObject(new Bar(new Foo(1)))
expect(getError(() =>
expect(new Foo(new Foo(1))).toMatchObject(new Bar(new Foo(2))),
)).toMatchInlineSnapshot(`
[
"expected Foo{ value: Foo{ value: 1 } } to match object Bar{ value: Foo{ value: 2 } }",
"- Expected
+ Received

- Bar {
+ Foo {
"value": Foo {
- "value": 2,
+ "value": 1,
},
}",
]
`)
})

it('toHaveProperty error diff', () => {
Expand Down
Loading