diff --git a/CHANGELOG.md b/CHANGELOG.md index a28b710420af..7d3bc2b40354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ - `[jest-cli]` Don't report promises as open handles ([#6716](https://github.com/facebook/jest/pull/6716)) - `[jest-each]` Add timeout support to parameterised tests ([#6660](https://github.com/facebook/jest/pull/6660)) - `[jest-cli]` Improve the message when running coverage while there are no files matching global threshold ([#6334](https://github.com/facebook/jest/pull/6334)) +- `[jest-snapshot]` Correctly merge property matchers with the rest of the snapshot in `toMatchSnapshot`. ([#6528](https://github.com/facebook/jest/pull/6528)) +- `[jest-snapshot]` Add error messages for invalid property matchers. ([#6528](https://github.com/facebook/jest/pull/6528)) ## 23.4.2 diff --git a/e2e/__tests__/to_match_snapshot.test.js b/e2e/__tests__/to_match_snapshot.test.js index 84a9c3efc191..b1ae499d0fc2 100644 --- a/e2e/__tests__/to_match_snapshot.test.js +++ b/e2e/__tests__/to_match_snapshot.test.js @@ -191,6 +191,49 @@ test('handles property matchers', () => { } }); +test('handles invalid property matchers', () => { + const filename = 'handle-property-matchers.test.js'; + { + writeFiles(TESTS_DIR, { + [filename]: `test('invalid property matchers', () => { + expect({foo: 'bar'}).toMatchSnapshot(null); + }); + `, + }); + const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]); + expect(stderr).toMatch('Property matchers must be an object.'); + expect(status).toBe(1); + } + { + writeFiles(TESTS_DIR, { + [filename]: `test('invalid property matchers', () => { + expect({foo: 'bar'}).toMatchSnapshot(null, 'test-name'); + }); + `, + }); + const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]); + expect(stderr).toMatch('Property matchers must be an object.'); + expect(stderr).toMatch( + 'To provide a snapshot test name without property matchers, use: toMatchSnapshot("name")', + ); + expect(status).toBe(1); + } + { + writeFiles(TESTS_DIR, { + [filename]: `test('invalid property matchers', () => { + expect({foo: 'bar'}).toMatchSnapshot(undefined, 'test-name'); + }); + `, + }); + const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]); + expect(stderr).toMatch('Property matchers must be an object.'); + expect(stderr).toMatch( + 'To provide a snapshot test name without property matchers, use: toMatchSnapshot("name")', + ); + expect(status).toBe(1); + } +}); + 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', () => { @@ -217,20 +260,21 @@ test('handles property matchers with custom name', () => { expect(stderr).toMatch( 'Received value does not match snapshot properties for "handles property matchers with name: custom-name 1".', ); + expect(stderr).toMatch('Expected snapshot to match properties:'); expect(stderr).toMatch('Snapshots: 1 failed, 1 total'); expect(status).toBe(1); } }); -test('handles property matchers with deep expect.objectContaining', () => { +test('handles property matchers with deep properties', () => { const filename = 'handle-property-matchers-with-name.test.js'; - const template = makeTemplate(`test('handles property matchers with deep expect.objectContaining', () => { - expect({ user: { createdAt: $1, name: 'Jest' }}).toMatchSnapshot({ user: expect.objectContaining({ createdAt: expect.any(Date) }) }); + const template = makeTemplate(`test('handles property matchers with deep properties', () => { + expect({ user: { createdAt: $1, name: $2 }}).toMatchSnapshot({ user: { createdAt: expect.any(Date), name: $2 }}); }); `); { - writeFiles(TESTS_DIR, {[filename]: template(['new Date()'])}); + writeFiles(TESTS_DIR, {[filename]: template(['new Date()', '"Jest"'])}); const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]); expect(stderr).toMatch('1 snapshot written from 1 test suite.'); expect(status).toBe(0); @@ -243,10 +287,21 @@ test('handles property matchers with deep expect.objectContaining', () => { } { - writeFiles(TESTS_DIR, {[filename]: template(['"string"'])}); + 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".', + ); + expect(stderr).toMatch('Expected snapshot to match properties:'); + expect(stderr).toMatch('Snapshots: 1 failed, 1 total'); + expect(status).toBe(1); + } + + { + 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 snapshot properties for "handles property matchers with deep expect.objectContaining 1".', + 'Received value does not match stored snapshot "handles property matchers with deep properties 1"', ); expect(stderr).toMatch('Snapshots: 1 failed, 1 total'); expect(status).toBe(1); diff --git a/packages/jest-snapshot/src/__tests__/utils.test.js b/packages/jest-snapshot/src/__tests__/utils.test.js index 76cb798902f1..339911334ecb 100644 --- a/packages/jest-snapshot/src/__tests__/utils.test.js +++ b/packages/jest-snapshot/src/__tests__/utils.test.js @@ -18,6 +18,7 @@ const { saveSnapshotFile, serialize, testNameToKey, + deepMerge, SNAPSHOT_GUIDE_LINK, SNAPSHOT_VERSION, SNAPSHOT_VERSION_WARNING, @@ -198,3 +199,15 @@ test('serialize handles \\r\\n', () => { expect(serializedData).toBe('\n"