Skip to content

Commit a397607

Browse files
authored
Document and test dontThrow for custom inline snapshot matchers (#10995)
1 parent 4fa3a0b commit a397607

File tree

6 files changed

+204
-0
lines changed

6 files changed

+204
-0
lines changed

docs/ExpectAPI.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,48 @@ it('observes something', async () => {
292292
});
293293
```
294294

295+
#### Bail out
296+
297+
Usually `jest` tries to match every snapshot that is expected in a test.
298+
299+
Sometimes it might not make sense to continue the test if a prior snapshot failed. For example, when you make snapshots of a state-machine after various transitions you can abort the test once one transition produced the wrong state.
300+
301+
In that case you can implement a custom snapshot matcher that throws on the first mismatch instead of collecting every mismatch.
302+
303+
```js
304+
const {toMatchInlineSnapshot} = require('jest-snapshot');
305+
306+
expect.extend({
307+
toMatchStateInlineSnapshot(...args) {
308+
this.dontThrow = () => {};
309+
310+
return toMatchInlineSnapshot.call(this, ...args);
311+
},
312+
});
313+
314+
let state = 'initial';
315+
316+
function transition() {
317+
// Typo in the implementation should cause the test to fail
318+
if (state === 'INITIAL') {
319+
state = 'pending';
320+
} else if (state === 'pending') {
321+
state = 'done';
322+
}
323+
}
324+
325+
it('transitions as expected', () => {
326+
expect(state).toMatchStateInlineSnapshot(`"initial"`);
327+
328+
transition();
329+
// Already produces a mismatch. No point in continuing the test.
330+
expect(state).toMatchStateInlineSnapshot(`"loading"`);
331+
332+
transition();
333+
expect(state).toMatchStateInlineSnapshot(`"done"`);
334+
});
335+
```
336+
295337
### `expect.anything()`
296338

297339
`expect.anything()` matches anything but `null` or `undefined`. You can use it inside `toEqual` or `toBeCalledWith` instead of a literal value. For example, if you want to check that a mock function is called with a non-null argument:

e2e/__tests__/__snapshots__/customInlineSnapshotMatchers.test.ts.snap

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`can bail with a custom inline snapshot matcher 1`] = `
4+
FAIL __tests__/bail.test.js
5+
✕ transitions as expected
6+
7+
● transitions as expected
8+
9+
expect(received).toMatchInlineSnapshot(snapshot)
10+
11+
Snapshot name: \`transitions as expected 2\`
12+
13+
Snapshot: "loading"
14+
Received: "initial"
15+
16+
28 | transition();
17+
29 | // Already produces a mismatch. No point in continuing the test.
18+
> 30 | expect(state).toMatchStateInlineSnapshot(\`"loading"\`);
19+
| ^
20+
31 | transition();
21+
32 | expect(state).toMatchStateInlineSnapshot(\`"done"\`);
22+
33 | });
23+
24+
at Object.toMatchStateInlineSnapshot (__tests__/bail.test.js:30:17)
25+
26+
› 1 snapshot failed.
27+
Snapshot Summary
28+
› 1 snapshot failed from 1 test suite. Inspect your code changes or re-run jest with \`-u\` to update them.
29+
`;
30+
331
exports[`works with custom inline snapshot matchers 1`] = `
432
FAIL __tests__/asynchronous.test.js
533
✕ new async, inline snapshots

e2e/__tests__/customInlineSnapshotMatchers.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,20 @@ test('works with custom inline snapshot matchers', () => {
2525

2626
expect(wrap(rest)).toMatchSnapshot();
2727
});
28+
29+
test('can bail with a custom inline snapshot matcher', () => {
30+
const {stderr} = runJest('custom-inline-snapshot-matchers', [
31+
// Prevent adding new snapshots or rather changing the test.
32+
'--ci',
33+
'bail.test.js',
34+
]);
35+
36+
let {rest} = extractSummary(stderr);
37+
38+
rest = rest
39+
.split('\n')
40+
.filter(line => line.indexOf('at Error (native)') < 0)
41+
.join('\n');
42+
43+
expect(wrap(rest)).toMatchSnapshot();
44+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
const {toMatchInlineSnapshot} = require('jest-snapshot');
8+
9+
expect.extend({
10+
toMatchStateInlineSnapshot(...args) {
11+
this.dontThrow = () => {};
12+
return toMatchInlineSnapshot.call(this, ...args);
13+
},
14+
});
15+
16+
let state = 'initial';
17+
function transition() {
18+
// Typo in the implementation should cause the test to fail
19+
if (state === 'INITIAL') {
20+
state = 'pending';
21+
} else if (state === 'pending') {
22+
state = 'done';
23+
}
24+
}
25+
26+
it('transitions as expected', () => {
27+
expect(state).toMatchStateInlineSnapshot(`"initial"`);
28+
transition();
29+
// Already produces a mismatch. No point in continuing the test.
30+
expect(state).toMatchStateInlineSnapshot(`"loading"`);
31+
transition();
32+
expect(state).toMatchStateInlineSnapshot(`"done"`);
33+
});

website/versioned_docs/version-25.x/ExpectAPI.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,48 @@ it('stores only 10 characters', () => {
257257
});
258258
```
259259

260+
#### Bail out
261+
262+
Usually `jest` tries to match every snapshot that is expected in a test.
263+
264+
Sometimes it might not make sense to continue the test if a prior snapshot failed. For example, when you make snapshots of a state-machine after various transitions you can abort the test once one transition produced the wrong state.
265+
266+
In that case you can implement a custom snapshot matcher that throws on the first mismatch instead of collecting every mismatch.
267+
268+
```js
269+
const {toMatchInlineSnapshot} = require('jest-snapshot');
270+
271+
expect.extend({
272+
toMatchStateInlineSnapshot(...args) {
273+
this.dontThrow = () => {};
274+
275+
return toMatchInlineSnapshot.call(this, ...args);
276+
},
277+
});
278+
279+
let state = 'initial';
280+
281+
function transition() {
282+
// Typo in the implementation should cause the test to fail
283+
if (state === 'INITIAL') {
284+
state = 'pending';
285+
} else if (state === 'pending') {
286+
state = 'done';
287+
}
288+
}
289+
290+
it('transitions as expected', () => {
291+
expect(state).toMatchStateInlineSnapshot(`"initial"`);
292+
293+
transition();
294+
// Already produces a mismatch. No point in continuing the test.
295+
expect(state).toMatchStateInlineSnapshot(`"loading"`);
296+
297+
transition();
298+
expect(state).toMatchStateInlineSnapshot(`"done"`);
299+
});
300+
```
301+
260302
### `expect.anything()`
261303

262304
`expect.anything()` matches anything but `null` or `undefined`. You can use it inside `toEqual` or `toBeCalledWith` instead of a literal value. For example, if you want to check that a mock function is called with a non-null argument:

website/versioned_docs/version-26.x/ExpectAPI.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,48 @@ it('stores only 10 characters', () => {
257257
});
258258
```
259259

260+
#### Bail out
261+
262+
Usually `jest` tries to match every snapshot that is expected in a test.
263+
264+
Sometimes it might not make sense to continue the test if a prior snapshot failed. For example, when you make snapshots of a state-machine after various transitions you can abort the test once one transition produced the wrong state.
265+
266+
In that case you can implement a custom snapshot matcher that throws on the first mismatch instead of collecting every mismatch.
267+
268+
```js
269+
const {toMatchInlineSnapshot} = require('jest-snapshot');
270+
271+
expect.extend({
272+
toMatchStateInlineSnapshot(...args) {
273+
this.dontThrow = () => {};
274+
275+
return toMatchInlineSnapshot.call(this, ...args);
276+
},
277+
});
278+
279+
let state = 'initial';
280+
281+
function transition() {
282+
// Typo in the implementation should cause the test to fail
283+
if (state === 'INITIAL') {
284+
state = 'pending';
285+
} else if (state === 'pending') {
286+
state = 'done';
287+
}
288+
}
289+
290+
it('transitions as expected', () => {
291+
expect(state).toMatchStateInlineSnapshot(`"initial"`);
292+
293+
transition();
294+
// Already produces a mismatch. No point in continuing the test.
295+
expect(state).toMatchStateInlineSnapshot(`"loading"`);
296+
297+
transition();
298+
expect(state).toMatchStateInlineSnapshot(`"done"`);
299+
});
300+
```
301+
260302
### `expect.anything()`
261303

262304
`expect.anything()` matches anything but `null` or `undefined`. You can use it inside `toEqual` or `toBeCalledWith` instead of a literal value. For example, if you want to check that a mock function is called with a non-null argument:

0 commit comments

Comments
 (0)