Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jest-snapshot: Improve report when matcher fails, part 14 #8132

Merged
merged 13 commits into from
Mar 19, 2019
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 CHANGELOG.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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.

`;
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`failing snapshot with hint: descriptive hint 1`] = `"bar"`;
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading