diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cbbb653666e..549d7efa84ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Fixes +- `[jest-snapshot]` Inline snapshots: do not indent empty lines ([#8277](https://github.com/facebook/jest/pull/8277)) + ### Chore & Maintenance ### Performance diff --git a/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap b/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap index 6de95cb08b08..67f659ceb42c 100644 --- a/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap +++ b/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap @@ -40,6 +40,30 @@ test('inline snapshots', () => `; +exports[`do not indent empty lines: initial write 1`] = ` +test('inline snapshots', () => + expect(\`hello + +world\`).toMatchInlineSnapshot(\` + "hello + + world" + \`)); + +`; + +exports[`do not indent empty lines: snapshot passed 1`] = ` +test('inline snapshots', () => + expect(\`hello + +world\`).toMatchInlineSnapshot(\` + "hello + + world" + \`)); + +`; + exports[`handles property matchers: initial write 1`] = ` test('handles property matchers', () => { expect({createdAt: new Date()}).toMatchInlineSnapshot( diff --git a/e2e/__tests__/toMatchInlineSnapshot.test.ts b/e2e/__tests__/toMatchInlineSnapshot.test.ts index 655a32d42c22..88219a30a261 100644 --- a/e2e/__tests__/toMatchInlineSnapshot.test.ts +++ b/e2e/__tests__/toMatchInlineSnapshot.test.ts @@ -71,6 +71,33 @@ test('basic support', () => { } }); +test('do not indent empty lines', () => { + const filename = 'empty-line-indent.test.js'; + const template = makeTemplate( + `test('inline snapshots', () => expect($1).toMatchInlineSnapshot());\n`, + ); + + { + writeFiles(TESTS_DIR, { + [filename]: template(['`hello\n\nworld`']), + }); + 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(wrap(fileAfter)).toMatchSnapshot('initial write'); + } + + { + const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false', filename]); + const fileAfter = readFile(filename); + expect(stderr).toMatch('Snapshots: 1 passed, 1 total'); + expect(stderr).not.toMatch('1 snapshot written from 1 test suite.'); + expect(status).toBe(0); + expect(wrap(fileAfter)).toMatchSnapshot('snapshot passed'); + } +}); + test('handles property matchers', () => { const filename = 'handle-property-matchers.test.js'; const template = makeTemplate(`test('handles property matchers', () => { diff --git a/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts b/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts index fd47d3d0348a..a6173b61cb86 100644 --- a/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts +++ b/packages/jest-snapshot/src/__tests__/inline_snapshots.test.ts @@ -304,3 +304,36 @@ test('saveInlineSnapshots() indents snapshots after prettier reformats', () => { ' `));\n', ); }); + +test('saveInlineSnapshots() does not indent empty lines', () => { + const filename = path.join(__dirname, 'my.test.js'); + (fs.readFileSync as jest.Mock).mockImplementation( + () => + "it('is a test', () => expect(`hello\n\nworld`).toMatchInlineSnapshot());\n", + ); + (prettier.resolveConfig.sync as jest.Mock).mockReturnValue({ + bracketSpacing: false, + singleQuote: true, + }); + + saveInlineSnapshots( + [ + { + frame: {column: 9, file: filename, line: 3} as Frame, + snapshot: `\nhello\n\nworld\n`, + }, + ], + prettier, + babelTraverse, + ); + + expect(fs.writeFileSync).toHaveBeenCalledWith( + filename, + "it('is a test', () =>\n" + + ' expect(`hello\n\nworld`).toMatchInlineSnapshot(`\n' + + ' hello\n' + + '\n' + + ' world\n' + + ' `));\n', + ); +}); diff --git a/packages/jest-snapshot/src/index.ts b/packages/jest-snapshot/src/index.ts index 8d3d12398c8f..b579e279e7a8 100644 --- a/packages/jest-snapshot/src/index.ts +++ b/packages/jest-snapshot/src/index.ts @@ -95,13 +95,16 @@ function stripAddedIndentation(inlineSnapshot: string) { } for (let i = 1; i < lines.length - 1; i++) { - if (lines[i].indexOf(indentation) !== 0) { - // All lines except first and last should have the same indent as the - // first line (or more). If this isn't the case we don't want to touch it. - return inlineSnapshot; - } + if (lines[i] !== '') { + if (lines[i].indexOf(indentation) !== 0) { + // All lines except first and last should either be blank or have the same + // indent as the first line (or more). If this isn't the case we don't + // want to touch the snapshot at all. + return inlineSnapshot; + } - lines[i] = lines[i].substr(indentation.length); + lines[i] = lines[i].substr(indentation.length); + } } // Last line is a special case because it won't have the same indent as others diff --git a/packages/jest-snapshot/src/inline_snapshots.ts b/packages/jest-snapshot/src/inline_snapshots.ts index 3e256df2912f..846d5e80d692 100644 --- a/packages/jest-snapshot/src/inline_snapshots.ts +++ b/packages/jest-snapshot/src/inline_snapshots.ts @@ -126,6 +126,11 @@ const indent = (snapshot: string, numIndents: number, indentation: string) => { // First line is either a 1-line snapshot or a blank line. return line; } else if (index !== lines.length - 1) { + // Do not indent empty lines. + if (line === '') { + return line; + } + // Not last line, indent one level deeper than expect call. return indentation.repeat(numIndents + 1) + line; } else {