Skip to content

Commit

Permalink
Document and test dontThrow for custom inline snapshot matchers (#10995)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed May 20, 2021
1 parent 4fa3a0b commit a397607
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 0 deletions.
42 changes: 42 additions & 0 deletions docs/ExpectAPI.md
Expand Up @@ -292,6 +292,48 @@ it('observes something', async () => {
});
```

#### Bail out

Usually `jest` tries to match every snapshot that is expected in a test.

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.

In that case you can implement a custom snapshot matcher that throws on the first mismatch instead of collecting every mismatch.

```js
const {toMatchInlineSnapshot} = require('jest-snapshot');

expect.extend({
toMatchStateInlineSnapshot(...args) {
this.dontThrow = () => {};

return toMatchInlineSnapshot.call(this, ...args);
},
});

let state = 'initial';

function transition() {
// Typo in the implementation should cause the test to fail
if (state === 'INITIAL') {
state = 'pending';
} else if (state === 'pending') {
state = 'done';
}
}

it('transitions as expected', () => {
expect(state).toMatchStateInlineSnapshot(`"initial"`);

transition();
// Already produces a mismatch. No point in continuing the test.
expect(state).toMatchStateInlineSnapshot(`"loading"`);

transition();
expect(state).toMatchStateInlineSnapshot(`"done"`);
});
```

### `expect.anything()`

`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:
Expand Down
@@ -1,5 +1,33 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`can bail with a custom inline snapshot matcher 1`] = `
FAIL __tests__/bail.test.js
✕ transitions as expected
● transitions as expected
expect(received).toMatchInlineSnapshot(snapshot)
Snapshot name: \`transitions as expected 2\`
Snapshot: "loading"
Received: "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 | });
at Object.toMatchStateInlineSnapshot (__tests__/bail.test.js:30:17)
› 1 snapshot failed.
Snapshot Summary
› 1 snapshot failed from 1 test suite. Inspect your code changes or re-run jest with \`-u\` to update them.
`;

exports[`works with custom inline snapshot matchers 1`] = `
FAIL __tests__/asynchronous.test.js
✕ new async, inline snapshots
Expand Down
17 changes: 17 additions & 0 deletions e2e/__tests__/customInlineSnapshotMatchers.test.ts
Expand Up @@ -25,3 +25,20 @@ test('works with custom inline snapshot matchers', () => {

expect(wrap(rest)).toMatchSnapshot();
});

test('can bail with a custom inline snapshot matcher', () => {
const {stderr} = runJest('custom-inline-snapshot-matchers', [
// Prevent adding new snapshots or rather changing the test.
'--ci',
'bail.test.js',
]);

let {rest} = extractSummary(stderr);

rest = rest
.split('\n')
.filter(line => line.indexOf('at Error (native)') < 0)
.join('\n');

expect(wrap(rest)).toMatchSnapshot();
});
33 changes: 33 additions & 0 deletions e2e/custom-inline-snapshot-matchers/__tests__/bail.test.js
@@ -0,0 +1,33 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const {toMatchInlineSnapshot} = require('jest-snapshot');

expect.extend({
toMatchStateInlineSnapshot(...args) {
this.dontThrow = () => {};
return toMatchInlineSnapshot.call(this, ...args);
},
});

let state = 'initial';
function transition() {
// Typo in the implementation should cause the test to fail
if (state === 'INITIAL') {
state = 'pending';
} else if (state === 'pending') {
state = 'done';
}
}

it('transitions as expected', () => {
expect(state).toMatchStateInlineSnapshot(`"initial"`);
transition();
// Already produces a mismatch. No point in continuing the test.
expect(state).toMatchStateInlineSnapshot(`"loading"`);
transition();
expect(state).toMatchStateInlineSnapshot(`"done"`);
});
42 changes: 42 additions & 0 deletions website/versioned_docs/version-25.x/ExpectAPI.md
Expand Up @@ -257,6 +257,48 @@ it('stores only 10 characters', () => {
});
```

#### Bail out

Usually `jest` tries to match every snapshot that is expected in a test.

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.

In that case you can implement a custom snapshot matcher that throws on the first mismatch instead of collecting every mismatch.

```js
const {toMatchInlineSnapshot} = require('jest-snapshot');

expect.extend({
toMatchStateInlineSnapshot(...args) {
this.dontThrow = () => {};

return toMatchInlineSnapshot.call(this, ...args);
},
});

let state = 'initial';

function transition() {
// Typo in the implementation should cause the test to fail
if (state === 'INITIAL') {
state = 'pending';
} else if (state === 'pending') {
state = 'done';
}
}

it('transitions as expected', () => {
expect(state).toMatchStateInlineSnapshot(`"initial"`);

transition();
// Already produces a mismatch. No point in continuing the test.
expect(state).toMatchStateInlineSnapshot(`"loading"`);

transition();
expect(state).toMatchStateInlineSnapshot(`"done"`);
});
```

### `expect.anything()`

`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:
Expand Down
42 changes: 42 additions & 0 deletions website/versioned_docs/version-26.x/ExpectAPI.md
Expand Up @@ -257,6 +257,48 @@ it('stores only 10 characters', () => {
});
```

#### Bail out

Usually `jest` tries to match every snapshot that is expected in a test.

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.

In that case you can implement a custom snapshot matcher that throws on the first mismatch instead of collecting every mismatch.

```js
const {toMatchInlineSnapshot} = require('jest-snapshot');

expect.extend({
toMatchStateInlineSnapshot(...args) {
this.dontThrow = () => {};

return toMatchInlineSnapshot.call(this, ...args);
},
});

let state = 'initial';

function transition() {
// Typo in the implementation should cause the test to fail
if (state === 'INITIAL') {
state = 'pending';
} else if (state === 'pending') {
state = 'done';
}
}

it('transitions as expected', () => {
expect(state).toMatchStateInlineSnapshot(`"initial"`);

transition();
// Already produces a mismatch. No point in continuing the test.
expect(state).toMatchStateInlineSnapshot(`"loading"`);

transition();
expect(state).toMatchStateInlineSnapshot(`"done"`);
});
```

### `expect.anything()`

`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:
Expand Down

0 comments on commit a397607

Please sign in to comment.