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