Skip to content

Commit

Permalink
jest-snapshot: Improve report when matcher fails, part 14 (#8132)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrottimark authored and SimenB committed Mar 19, 2019
1 parent 0c7bda2 commit e04b034
Show file tree
Hide file tree
Showing 16 changed files with 263 additions and 143 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

### Features

- `[jest-snapshot]` Improve report when matcher fails, part 14 ([#8132](https://github.com/facebook/jest/pull/8132))
- `[@jest/reporter]` Display todo and skip test descriptions when verbose is true ([#8038](https://github.com/facebook/jest/pull/8038))

### Fixes
Expand Down
8 changes: 4 additions & 4 deletions docs/ExpectAPI.md
Expand Up @@ -1125,13 +1125,13 @@ test('this house has my desired features', () => {
});
```

### `.toMatchSnapshot(propertyMatchers?, snapshotName?)`
### `.toMatchSnapshot(propertyMatchers?, hint?)`

This ensures that a value matches the most recent snapshot. Check out [the Snapshot Testing guide](SnapshotTesting.md) for more information.

You can provide an optional `propertyMatchers` object argument, which has asymmetric matchers as values of a subset of expected properties, **if** the received value will be an **object** instance. It is like `toMatchObject` with flexible criteria for a subset of properties, followed by a snapshot test as exact criteria for the rest of the properties.

You can provide an optional `snapshotName` string argument that is appended to the test name. Jest always appends a number at the end of a snapshot key to differentiate snapshots from a single `it` or `test` block. Jest sorts snapshots by key in the corresponding `.snap` file.
You can provide an optional `hint` string argument that is appended to the test name. Although Jest always appends a number at the end of a snapshot name, short descriptive hints might be more useful than numbers to differentiate **multiple** snapshots in a **single** `it` or `test` block. Jest sorts snapshots by name in the corresponding `.snap` file.

### `.toMatchInlineSnapshot(propertyMatchers?, inlineSnapshot)`

Expand Down Expand Up @@ -1223,11 +1223,11 @@ test('throws on octopus', () => {

> Note: You must wrap the code in a function, otherwise the error will not be caught and the assertion will fail.
### `.toThrowErrorMatchingSnapshot(snapshotName?)`
### `.toThrowErrorMatchingSnapshot(hint?)`

Use `.toThrowErrorMatchingSnapshot` to test that a function throws an error matching the most recent snapshot when it is called.

You can provide an optional `snapshotName` string argument that is appended to the test name. Jest always appends a number at the end of a snapshot key to differentiate snapshots from a single `it` or `test` block. Jest sorts snapshots by key in the corresponding `.snap` file.
You can provide an optional `hint` string argument that is appended to the test name. Although Jest always appends a number at the end of a snapshot name, short descriptive hints might be more useful than numbers to differentiate **multiple** snapshots in a **single** `it` or `test` block. Jest sorts snapshots by name in the corresponding `.snap` file.

For example, let's say you have a `drinkFlavor` function that throws whenever the flavor is `'octopus'`, and is coded like this:

Expand Down
62 changes: 31 additions & 31 deletions e2e/__tests__/__snapshots__/failures.test.ts.snap
Expand Up @@ -381,35 +381,6 @@ FAIL __tests__/asyncFailures.test.js
at Object.test (__tests__/asyncFailures.test.js:23:1)
`;
exports[`works with named snapshot failures 1`] = `
FAIL __tests__/snapshotNamed.test.js
✕ failing named snapshot
● failing named snapshot
expect(value).toMatchSnapshot()
Received value does not match stored snapshot "failing named snapshot: snapname 1".
- Snapshot
+ Received
- "bar"
+ "foo"
10 |
11 | test('failing named snapshot', () => {
> 12 | expect('foo').toMatchSnapshot('snapname');
| ^
13 | });
14 |
at Object.toMatchSnapshot (__tests__/snapshotNamed.test.js:12:17)
› 1 snapshot failed.
`;
exports[`works with node assert 1`] = `
FAIL __tests__/assertionError.test.js
✕ assert
Expand Down Expand Up @@ -819,9 +790,9 @@ FAIL __tests__/snapshot.test.js
● failing snapshot
expect(value).toMatchSnapshot()
expect(received).toMatchSnapshot()
Received value does not match stored snapshot "failing snapshot 1".
Snapshot name: \`failing snapshot 1\`
- Snapshot
+ Received
Expand All @@ -841,3 +812,32 @@ FAIL __tests__/snapshot.test.js
› 1 snapshot failed.
`;
exports[`works with snapshot failures with hint 1`] = `
FAIL __tests__/snapshotWithHint.test.js
✕ failing snapshot with hint
● failing snapshot with hint
expect(received).toMatchSnapshot(hint)
Snapshot name: \`failing snapshot with hint: descriptive hint 1\`
- Snapshot
+ Received
- "bar"
+ "foo"
10 |
11 | test('failing snapshot with hint', () => {
> 12 | expect('foo').toMatchSnapshot('descriptive hint');
| ^
13 | });
14 |
at Object.toMatchSnapshot (__tests__/snapshotWithHint.test.js:12:17)
› 1 snapshot failed.
`;
Expand Up @@ -4,8 +4,8 @@ exports[`can press "u" to update snapshots: test results 1`] = `
FAIL __tests__/bar.spec.js
✕ bar
● bar
expect(value).toMatchSnapshot()
Received value does not match stored snapshot "bar 1".
expect(received).toMatchSnapshot()
Snapshot name: \`bar 1\`
- Snapshot
+ Received
- "foo"
Expand Down
4 changes: 2 additions & 2 deletions e2e/__tests__/failures.test.ts
Expand Up @@ -173,8 +173,8 @@ test('works with snapshot failures', () => {
).toMatchSnapshot();
});

test('works with named snapshot failures', () => {
const {stderr} = runJest(dir, ['snapshotNamed.test.js']);
test('works with snapshot failures with hint', () => {
const {stderr} = runJest(dir, ['snapshotWithHint.test.js']);

const result = normalizeDots(cleanStderr(stderr));

Expand Down
6 changes: 2 additions & 4 deletions e2e/__tests__/toMatchInlineSnapshot.test.ts
Expand Up @@ -52,7 +52,7 @@ test('basic support', () => {
});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
const fileAfter = readFile(filename);
expect(stderr).toMatch('Received value does not match stored snapshot');
expect(stderr).toMatch('Snapshot name: `inline snapshots 1`');
expect(status).toBe(1);
expect(wrap(fileAfter)).toMatchSnapshot('snapshot mismatch');
}
Expand Down Expand Up @@ -101,9 +101,7 @@ test('handles property matchers', () => {
});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
const fileAfter = readFile(filename);
expect(stderr).toMatch(
'Received value does not match snapshot properties for "handles property matchers 1".',
);
expect(stderr).toMatch('Snapshot name: `handles property matchers 1`');
expect(stderr).toMatch('Snapshots: 1 failed, 1 total');
expect(status).toBe(1);
expect(wrap(fileAfter)).toMatchSnapshot('snapshot failed');
Expand Down
26 changes: 12 additions & 14 deletions e2e/__tests__/toMatchSnapshot.test.ts
Expand Up @@ -42,7 +42,7 @@ test('basic support', () => {
[filename]: template(['{apple: "updated value"}']),
});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch('Received value does not match stored snapshot');
expect(stderr).toMatch('Snapshot name: `snapshots 1`');
expect(status).toBe(1);
}

Expand Down Expand Up @@ -107,7 +107,7 @@ test('first snapshot fails, second passes', () => {
{
writeFiles(TESTS_DIR, {[filename]: template([`'kiwi'`, `'banana'`])});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch('Received value does not match stored snapshot');
expect(stderr).toMatch('Snapshot name: `snapshots 1`');
expect(stderr).toMatch('- "apple"\n + "kiwi"');
expect(stderr).not.toMatch('1 obsolete snapshot found');
expect(status).toBe(1);
Expand Down Expand Up @@ -178,9 +178,7 @@ test('handles property matchers', () => {
{
writeFiles(TESTS_DIR, {[filename]: template(['"string"'])});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch(
'Received value does not match snapshot properties for "handles property matchers 1".',
);
expect(stderr).toMatch('Snapshot name: `handles property matchers 1`');
expect(stderr).toMatch('Snapshots: 1 failed, 1 total');
expect(status).toBe(1);
}
Expand Down Expand Up @@ -229,10 +227,10 @@ test('handles invalid property matchers', () => {
}
});

test('handles property matchers with custom name', () => {
const filename = 'handle-property-matchers-with-name.test.js';
const template = makeTemplate(`test('handles property matchers with name', () => {
expect({createdAt: $1}).toMatchSnapshot({createdAt: expect.any(Date)}, 'custom-name');
test('handles property matchers with hint', () => {
const filename = 'handle-property-matchers-with-hint.test.js';
const template = makeTemplate(`test('handles property matchers with hint', () => {
expect({createdAt: $1}).toMatchSnapshot({createdAt: expect.any(Date)}, 'descriptive hint');
});
`);

Expand All @@ -253,9 +251,9 @@ test('handles property matchers with custom name', () => {
writeFiles(TESTS_DIR, {[filename]: template(['"string"'])});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch(
'Received value does not match snapshot properties for "handles property matchers with name: custom-name 1".',
'Snapshot name: `handles property matchers with hint: descriptive hint 1`',
);
expect(stderr).toMatch('Expected snapshot to match properties:');
expect(stderr).toMatch('Expected properties:');
expect(stderr).toMatch('Snapshots: 1 failed, 1 total');
expect(status).toBe(1);
}
Expand Down Expand Up @@ -285,9 +283,9 @@ test('handles property matchers with deep properties', () => {
writeFiles(TESTS_DIR, {[filename]: template(['"string"', '"Jest"'])});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch(
'Received value does not match snapshot properties for "handles property matchers with deep properties 1".',
'Snapshot name: `handles property matchers with deep properties 1`',
);
expect(stderr).toMatch('Expected snapshot to match properties:');
expect(stderr).toMatch('Expected properties:');
expect(stderr).toMatch('Snapshots: 1 failed, 1 total');
expect(status).toBe(1);
}
Expand All @@ -296,7 +294,7 @@ test('handles property matchers with deep properties', () => {
writeFiles(TESTS_DIR, {[filename]: template(['new Date()', '"CHANGED"'])});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch(
'Received value does not match stored snapshot "handles property matchers with deep properties 1"',
'Snapshot name: `handles property matchers with deep properties 1`',
);
expect(stderr).toMatch('Snapshots: 1 failed, 1 total');
expect(status).toBe(1);
Expand Down
4 changes: 1 addition & 3 deletions e2e/__tests__/toThrowErrorMatchingInlineSnapshot.test.ts
Expand Up @@ -81,9 +81,7 @@ test('cannot be used with .not', () => {
{
writeFiles(TESTS_DIR, {[filename]: template()});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch(
'Jest: `.not` cannot be used with `.toThrowErrorMatchingInlineSnapshot()`.',
);
expect(stderr).toMatch('.not cannot be used with snapshot matchers');
expect(status).toBe(1);
}
});
Expand Down
6 changes: 2 additions & 4 deletions e2e/__tests__/toThrowErrorMatchingSnapshot.test.ts
Expand Up @@ -43,7 +43,7 @@ test(`throws the error if tested function didn't throw error`, () => {
{
writeFiles(TESTS_DIR, {[filename]: template()});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch(`Expected the function to throw an error.`);
expect(stderr).toMatch('Received function did not throw');
expect(status).toBe(1);
}
});
Expand Down Expand Up @@ -74,9 +74,7 @@ test('cannot be used with .not', () => {
{
writeFiles(TESTS_DIR, {[filename]: template()});
const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]);
expect(stderr).toMatch(
'Jest: `.not` cannot be used with `.toThrowErrorMatchingSnapshot()`.',
);
expect(stderr).toMatch('.not cannot be used with snapshot matchers');
expect(status).toBe(1);
}
});
Expand Down

This file was deleted.

@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`failing snapshot with hint: descriptive hint 1`] = `"bar"`;
Expand Up @@ -8,6 +8,6 @@
*/
'use strict';

test('failing named snapshot', () => {
expect('foo').toMatchSnapshot('snapname');
test('failing snapshot with hint', () => {
expect('foo').toMatchSnapshot('descriptive hint');
});
2 changes: 1 addition & 1 deletion e2e/snapshot/__tests__/snapshot.test.js
Expand Up @@ -31,7 +31,7 @@ describe('snapshot', () => {

it('cannot be used with .not', () => {
expect(() => expect('').not.toMatchSnapshot()).toThrow(
'Jest: `.not` cannot be used with `.toMatchSnapshot()`.'
'.not cannot be used with snapshot matchers'
);
});

Expand Down
1 change: 1 addition & 0 deletions packages/jest-matcher-utils/src/index.ts
Expand Up @@ -40,6 +40,7 @@ export {DiffOptions};
export const EXPECTED_COLOR = chalk.green;
export const RECEIVED_COLOR = chalk.red;
export const INVERTED_COLOR = chalk.inverse;
export const BOLD_WEIGHT = chalk.bold;
const DIM_COLOR = chalk.dim;

const NUMBERS = [
Expand Down

0 comments on commit e04b034

Please sign in to comment.