diff --git a/e2e/__tests__/__snapshots__/to_match_inline_snapshot.test.js.snap b/e2e/__tests__/__snapshots__/to_match_inline_snapshot.test.js.snap index 9045ee66b05f..2f2925ef254f 100644 --- a/e2e/__tests__/__snapshots__/to_match_inline_snapshot.test.js.snap +++ b/e2e/__tests__/__snapshots__/to_match_inline_snapshot.test.js.snap @@ -96,6 +96,28 @@ Object { " `; +exports[`removes obsolete external snapshots: external snapshot cleaned 1`] = ` +"test('removes obsolete external snapshots', () => { + expect('1').toMatchInlineSnapshot(\`\\"1\\"\`); +}); +" +`; + +exports[`removes obsolete external snapshots: initial write 1`] = ` +" + test('removes obsolete external snapshots', () => { + expect('1').toMatchSnapshot(); + }); + " +`; + +exports[`removes obsolete external snapshots: inline snapshot written 1`] = ` +"test('removes obsolete external snapshots', () => { + expect('1').toMatchInlineSnapshot(\`\\"1\\"\`); +}); +" +`; + exports[`supports async matchers 1`] = ` "test('inline snapshots', async () => { expect(Promise.resolve('success')).resolves.toMatchInlineSnapshot( diff --git a/e2e/__tests__/to_match_inline_snapshot.test.js b/e2e/__tests__/to_match_inline_snapshot.test.js index 54b0173ed6fd..07cc4af3cd6a 100644 --- a/e2e/__tests__/to_match_inline_snapshot.test.js +++ b/e2e/__tests__/to_match_inline_snapshot.test.js @@ -130,6 +130,54 @@ test('handles property matchers', () => { } }); +test('removes obsolete external snapshots', () => { + const filename = 'removes-obsolete-external-snapshots.test.js'; + const snapshotPath = path.join( + TESTS_DIR, + '__snapshots__', + filename + '.snap', + ); + const template = makeTemplate(` + test('removes obsolete external snapshots', () => { + expect('1').$1(); + }); + `); + + { + writeFiles(TESTS_DIR, {[filename]: template(['toMatchSnapshot'])}); + const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]); + const fileAfter = readFile(filename); + expect(stderr).toMatch('1 snapshot written from 1 test suite.'); + expect(status).toBe(0); + expect(fileAfter).toMatchSnapshot('initial write'); + expect(fs.existsSync(snapshotPath)).toEqual(true); + } + + { + writeFiles(TESTS_DIR, {[filename]: template(['toMatchInlineSnapshot'])}); + const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]); + const fileAfter = readFile(filename); + expect(stderr).toMatch('Snapshots: 1 obsolete, 1 written, 1 total'); + expect(status).toBe(1); + expect(fileAfter).toMatchSnapshot('inline snapshot written'); + expect(fs.existsSync(snapshotPath)).toEqual(true); + } + + { + const {stderr, status} = runJest(DIR, [ + '-w=1', + '--ci=false', + filename, + '-u', + ]); + const fileAfter = readFile(filename); + expect(stderr).toMatch('Snapshots: 1 file removed, 1 passed, 1 total'); + expect(status).toBe(0); + expect(fileAfter).toMatchSnapshot('external snapshot cleaned'); + expect(fs.existsSync(snapshotPath)).toEqual(false); + } +}); + test('supports async matchers', () => { const filename = 'async-matchers.test.js'; const test = ` diff --git a/packages/jest-snapshot/src/State.js b/packages/jest-snapshot/src/State.js index d24e116fe2a9..923d60461beb 100644 --- a/packages/jest-snapshot/src/State.js +++ b/packages/jest-snapshot/src/State.js @@ -170,7 +170,12 @@ export default class SnapshotState { key = testNameToKey(testName, count); } - this._uncheckedKeys.delete(key); + // Do not mark the snapshot as "checked" if the snapshot is inline and + // there's an external snapshot. This way the external snapshot can be + // removed with `--updateSnapshot`. + if (!(isInline && this._snapshotData[key])) { + this._uncheckedKeys.delete(key); + } const receivedSerialized = serialize(received); const expected = isInline ? inlineSnapshot : this._snapshotData[key];