diff --git a/packages/jest-diff/src/__tests__/diff.test.js b/packages/jest-diff/src/__tests__/diff.test.js index b25b2dd7bf7d..de711f47f6ca 100644 --- a/packages/jest-diff/src/__tests__/diff.test.js +++ b/packages/jest-diff/src/__tests__/diff.test.js @@ -551,6 +551,101 @@ describe('indentation in React elements (snapshot)', () => { }); }); +describe('outer React element (non-snapshot)', () => { + const a = { + $$typeof: elementSymbol, + props: { + children: 'Jest', + }, + type: 'h1', + }; + const b = { + $$typeof: elementSymbol, + props: { + children: [ + a, + { + $$typeof: elementSymbol, + props: { + children: 'Delightful JavaScript Testing', + }, + type: 'h2', + }, + ], + }, + type: 'header', + }; + + describe('from less to more', () => { + const expected = [ + '+
', + // following 3 lines are unchanged, except for more indentation + '

', + ' Jest', + '

', + '+

', + '+ Delightful JavaScript Testing', + '+

', + '+
', + ].join('\n'); + + test('(unexpanded)', () => { + expect(stripped(a, b, unexpanded)).toMatch(expected); + }); + test('(expanded)', () => { + expect(stripped(a, b, expanded)).toMatch(expected); + }); + }); + + describe('from more to less', () => { + const expected = [ + '-
', + // following 3 lines are unchanged, except for less indentation + '

', + ' Jest', + '

', + '-

', + '- Delightful JavaScript Testing', + '-

', + '-
', + ].join('\n'); + + test('(unexpanded)', () => { + expect(stripped(b, a, unexpanded)).toMatch(expected); + }); + test('(expanded)', () => { + expect(stripped(b, a, expanded)).toMatch(expected); + }); + }); +}); + +describe('trailing newline in multiline string not enclosed in quotes', () => { + const a = ['line 1', 'line 2', 'line 3'].join('\n'); + const b = a + '\n'; + + describe('from less to more', () => { + const expected = [' line 1', ' line 2', ' line 3', '+ '].join('\n'); + + test('(unexpanded)', () => { + expect(stripped(a, b, unexpanded)).toMatch(expected); + }); + test('(expanded)', () => { + expect(stripped(a, b, expanded)).toMatch(expected); + }); + }); + + describe('from more to less', () => { + const expected = [' line 1', ' line 2', ' line 3', '- '].join('\n'); + + test('(unexpanded)', () => { + expect(stripped(b, a, unexpanded)).toMatch(expected); + }); + test('(expanded)', () => { + expect(stripped(b, a, expanded)).toMatch(expected); + }); + }); +}); + describe('background color of spaces', () => { const baseline = { $$typeof: elementSymbol, diff --git a/packages/jest-diff/src/diff_strings.js b/packages/jest-diff/src/diff_strings.js index f46d0b8f0444..eb83731b6b2d 100644 --- a/packages/jest-diff/src/diff_strings.js +++ b/packages/jest-diff/src/diff_strings.js @@ -223,13 +223,6 @@ const formatHunks = ( ? contextLines : DIFF_CONTEXT_DEFAULT, }; - // Make sure the strings end with a newline. - if (!a.endsWith('\n')) { - a += '\n'; - } - if (!b.endsWith('\n')) { - b += '\n'; - } const {hunks} = structuredPatch('', '', a, b, '', '', options); if (hunks.length === 0) { @@ -260,6 +253,11 @@ export default function diffStrings( options: ?DiffOptions, original?: Original, ): string { + // Because `formatHunks` and `formatChunks` ignore one trailing newline, + // always append newline to strings: + a += '\n'; + b += '\n'; + // `diff` uses the Myers LCS diff algorithm which runs in O(n+d^2) time // (where "d" is the edit distance) and can get very slow for large edit // distances. Mitigate the cost by switching to a lower-resolution diff