Skip to content

Commit 8ee59f0

Browse files
authoredFeb 23, 2024··
fix(expect): show diff on toContain/toMatch assertion error (#5267)
1 parent 558bb88 commit 8ee59f0

File tree

4 files changed

+82
-24
lines changed

4 files changed

+82
-24
lines changed
 

‎docs/api/expect.md

-4
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,6 @@ test('top fruits', () => {
544544
})
545545
```
546546

547-
::: tip
548-
If the value in the error message is too truncated, you can increase [chaiConfig.truncateThreshold](/config/#chaiconfig-truncatethreshold) in your config file.
549-
:::
550-
551547
## toMatchObject
552548

553549
- **Type:** `(received: object | array) => Awaitable<void>`

‎packages/expect/src/jest-expect.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,16 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
170170
)
171171
})
172172
def('toMatch', function (expected: string | RegExp) {
173-
if (typeof expected === 'string')
174-
return this.include(expected)
175-
else
176-
return this.match(expected)
173+
const actual = this._obj as string
174+
return this.assert(
175+
typeof expected === 'string'
176+
? actual.includes(expected)
177+
: actual.match(expected),
178+
`expected #{this} to match #{exp}`,
179+
`expected #{this} not to match #{exp}`,
180+
expected,
181+
actual,
182+
)
177183
})
178184
def('toContain', function (item) {
179185
const actual = this._obj as Iterable<unknown> | string | Node | DOMTokenList
@@ -203,6 +209,16 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
203209
actual.value,
204210
)
205211
}
212+
// handle simple case on our own using `this.assert` to include diff in error message
213+
if (typeof actual === 'string' && typeof item === 'string') {
214+
return this.assert(
215+
actual.includes(item),
216+
`expected #{this} to contain #{exp}`,
217+
`expected #{this} not to contain #{exp}`,
218+
item,
219+
actual,
220+
)
221+
}
206222
// make "actual" indexable to have compatibility with jest
207223
if (actual != null && typeof actual !== 'string')
208224
utils.flag(this, 'object', Array.from(actual as Iterable<unknown>))

‎test/core/test/__snapshots__/jest-expect.test.ts.snap

+39
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,42 @@ exports[`asymmetric matcher error 23`] = `
310310
"message": "expected error to be instance of MyError1",
311311
}
312312
`;
313+
314+
exports[`toMatch/toContain diff 1`] = `
315+
{
316+
"actual": "hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello",
317+
"diff": "- Expected
318+
+ Received
319+
320+
- world
321+
+ hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello",
322+
"expected": "world",
323+
"message": "expected 'hellohellohellohellohellohellohellohe…' to contain 'world'",
324+
}
325+
`;
326+
327+
exports[`toMatch/toContain diff 2`] = `
328+
{
329+
"actual": "hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello",
330+
"diff": "- Expected
331+
+ Received
332+
333+
- world
334+
+ hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello",
335+
"expected": "world",
336+
"message": "expected 'hellohellohellohellohellohellohellohe…' to match 'world'",
337+
}
338+
`;
339+
340+
exports[`toMatch/toContain diff 3`] = `
341+
{
342+
"actual": "hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello",
343+
"diff": "- Expected:
344+
/world/
345+
346+
+ Received:
347+
"hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello"",
348+
"expected": "/world/",
349+
"message": "expected 'hellohellohellohellohellohellohellohe…' to match /world/",
350+
}
351+
`;

‎test/core/test/jest-expect.test.ts

+23-16
Original file line numberDiff line numberDiff line change
@@ -993,25 +993,26 @@ it('toHaveProperty error diff', () => {
993993
`)
994994
})
995995

996+
function snapshotError(f: () => unknown) {
997+
try {
998+
f()
999+
}
1000+
catch (error) {
1001+
const e = processError(error)
1002+
expect({
1003+
message: e.message,
1004+
diff: e.diff,
1005+
expected: e.expected,
1006+
actual: e.actual,
1007+
}).toMatchSnapshot()
1008+
return
1009+
}
1010+
expect.unreachable()
1011+
}
1012+
9961013
it('asymmetric matcher error', () => {
9971014
setupColors(getDefaultColors())
9981015

999-
function snapshotError(f: () => unknown) {
1000-
try {
1001-
f()
1002-
return expect.unreachable()
1003-
}
1004-
catch (error) {
1005-
const e = processError(error)
1006-
expect({
1007-
message: e.message,
1008-
diff: e.diff,
1009-
expected: e.expected,
1010-
actual: e.actual,
1011-
}).toMatchSnapshot()
1012-
}
1013-
}
1014-
10151016
expect.extend({
10161017
stringContainingCustom(received: unknown, other: string) {
10171018
return {
@@ -1084,4 +1085,10 @@ it('asymmetric matcher error', () => {
10841085
}).toThrow(MyError1))
10851086
})
10861087

1088+
it('toMatch/toContain diff', () => {
1089+
snapshotError(() => expect('hello'.repeat(20)).toContain('world'))
1090+
snapshotError(() => expect('hello'.repeat(20)).toMatch('world'))
1091+
snapshotError(() => expect('hello'.repeat(20)).toMatch(/world/))
1092+
})
1093+
10871094
it('timeout', () => new Promise(resolve => setTimeout(resolve, 500)))

0 commit comments

Comments
 (0)
Please sign in to comment.