diff --git a/CHANGELOG.md b/CHANGELOG.md index 80a3ad1707b6..d3e3025a0511 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `[babel-plugin-jest-hoist]` Expand list of whitelisted globals in global mocks ([#8429](https://github.com/facebook/jest/pull/8429) - `[jest-core]` Make watch plugin initialization errors look nice ([#8422](https://github.com/facebook/jest/pull/8422)) +- `[jest-snapshot]` Prevent inline snapshots from drifting when inline snapshots are updated ([#8492](https://github.com/facebook/jest/pull/8492)) ### Chore & Maintenance diff --git a/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts b/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts index a6173b61cb86..68826b5aec2a 100644 --- a/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts +++ b/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts @@ -236,6 +236,56 @@ test('saveInlineSnapshots() indents multi-line snapshots with spaces', () => { ); }); +test('saveInlineSnapshots() does not re-indent already indented snapshots', () => { + const filename = path.join(__dirname, 'my.test.js'); + (fs.readFileSync as jest.Mock).mockImplementation( + () => + "it('is a test', () => {\n" + + " expect({a: 'a'}).toMatchInlineSnapshot();\n" + + '});\n' + + "it('is a another test', () => {\n" + + " expect({a: 'a'}).toMatchInlineSnapshot(`\n" + + ' Object {\n' + + " b: 'b'\n" + + ' }\n' + + ' `);\n' + + '});\n', + ); + (prettier.resolveConfig.sync as jest.Mock).mockReturnValue({ + bracketSpacing: false, + singleQuote: true, + }); + + saveInlineSnapshots( + [ + { + frame: {column: 20, file: filename, line: 2} as Frame, + snapshot: `\nObject {\n a: 'a'\n}\n`, + }, + ], + prettier, + babelTraverse, + ); + + expect(fs.writeFileSync).toHaveBeenCalledWith( + filename, + "it('is a test', () => {\n" + + " expect({a: 'a'}).toMatchInlineSnapshot(`\n" + + ' Object {\n' + + " a: 'a'\n" + + ' }\n' + + ' `);\n' + + '});\n' + + "it('is a another test', () => {\n" + + " expect({a: 'a'}).toMatchInlineSnapshot(`\n" + + ' Object {\n' + + " b: 'b'\n" + + ' }\n' + + ' `);\n' + + '});\n', + ); +}); + test('saveInlineSnapshots() indents multi-line snapshots with tabs', () => { const filename = path.join(__dirname, 'my.test.js'); (fs.readFileSync as jest.Mock).mockImplementation( diff --git a/packages/jest-snapshot/src/inline_snapshots.ts b/packages/jest-snapshot/src/inline_snapshots.ts index ec2612ae2ce6..8b3e38afcc28 100644 --- a/packages/jest-snapshot/src/inline_snapshots.ts +++ b/packages/jest-snapshot/src/inline_snapshots.ts @@ -120,6 +120,14 @@ const groupSnapshotsByFile = groupSnapshotsBy(({frame: {file}}) => file); const indent = (snapshot: string, numIndents: number, indentation: string) => { const lines = snapshot.split('\n'); + // Prevent re-identation of inline snapshots. + if ( + lines.length >= 2 && + lines[1].startsWith(indentation.repeat(numIndents + 1)) + ) { + return snapshot; + } + return lines .map((line, index) => { if (index === 0) {