diff --git a/CHANGELOG.md b/CHANGELOG.md index 52dd9564586b..847432ff5dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -92,6 +92,8 @@ ([#6181](https://github.com/facebook/jest/pull/6181)) * `[expect]` Include custom mock names in error messages ([#6199](https://github.com/facebook/jest/pull/6199)) +* `[jest-diff]` Support returning diff from oneline strings + ([#6221](https://github.com/facebook/jest/pull/6221)) * `[expect]` Improve return matchers ([#6172](https://github.com/facebook/jest/pull/6172)) diff --git a/integration-tests/__tests__/__snapshots__/failures.test.js.snap b/integration-tests/__tests__/__snapshots__/failures.test.js.snap index 5c0dc6ea2565..d2bedc54ac4b 100644 --- a/integration-tests/__tests__/__snapshots__/failures.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/failures.test.js.snap @@ -407,6 +407,9 @@ exports[`works with named snapshot failures 1`] = ` Received value does not match stored snapshot \\"failing named snapshot: snapname 1\\". + - Snapshot + + Received + - \\"bar\\" + \\"foo\\" @@ -840,6 +843,9 @@ exports[`works with snapshot failures 1`] = ` Received value does not match stored snapshot \\"failing snapshot 1\\". + - Snapshot + + Received + - \\"bar\\" + \\"foo\\" diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index 02b7ac8a1a2b..52feb63dea37 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -30,6 +30,7 @@ import { iterableEquality, subsetEquality, typeEquality, + isOneline, } from './utils'; import {equals} from './jasmine_utils'; @@ -59,10 +60,8 @@ const matchers: MatchersObject = { getType(received) === getType(expected) && (getType(received) === 'object' || getType(expected) === 'array') && equals(received, expected, [iterableEquality]); - - const diffString = diff(expected, received, { - expand: this.expand, - }); + const oneline = isOneline(expected, received); + const diffString = diff(expected, received, {expand: this.expand}); return ( matcherHint('.toBe', undefined, undefined, { @@ -72,7 +71,7 @@ const matchers: MatchersObject = { '\n\n' + `Expected: ${printExpected(expected)}\n` + `Received: ${printReceived(received)}` + - (diffString ? `\n\nDifference:\n\n${diffString}` : '') + + (diffString && !oneline ? `\n\nDifference:\n\n${diffString}` : '') + (suggestToEqual ? ` ${SUGGEST_TO_EQUAL}` : '') ); }; @@ -375,9 +374,9 @@ const matchers: MatchersObject = { `Received:\n` + ` ${printReceived(received)}` : () => { - const diffString = diff(expected, received, { - expand: this.expand, - }); + const oneline = isOneline(expected, received); + const diffString = diff(expected, received, {expand: this.expand}); + return ( matcherHint('.toEqual') + '\n\n' + @@ -385,7 +384,7 @@ const matchers: MatchersObject = { ` ${printExpected(expected)}\n` + `Received:\n` + ` ${printReceived(received)}` + - (diffString ? `\n\nDifference:\n\n${diffString}` : '') + (diffString && !oneline ? `\n\nDifference:\n\n${diffString}` : '') ); }; diff --git a/packages/expect/src/spy_matchers.js b/packages/expect/src/spy_matchers.js index e7404c58af7b..f84ddb4a8d68 100644 --- a/packages/expect/src/spy_matchers.js +++ b/packages/expect/src/spy_matchers.js @@ -24,7 +24,7 @@ import { RECEIVED_COLOR, } from 'jest-matcher-utils'; import {equals} from './jasmine_utils'; -import {iterableEquality, partition} from './utils'; +import {iterableEquality, partition, isOneline} from './utils'; import diff from 'jest-diff'; const createToBeCalledMatcher = matcherName => (received, expected) => { @@ -555,12 +555,13 @@ const formatMismatchedArgs = (expected, received) => { const printedArgs = []; for (let i = 0; i < length; i++) { if (!equals(expected[i], received[i], [iterableEquality])) { + const oneline = isOneline(expected[i], received[i]); const diffString = diff(expected[i], received[i]); printedArgs.push( ` ${printExpected(expected[i])}\n` + `as argument ${i + 1}, but it was called with\n` + ` ${printReceived(received[i])}.` + - (diffString ? `\n\nDifference:\n\n${diffString}` : ''), + (diffString && !oneline ? `\n\nDifference:\n\n${diffString}` : ''), ); } else if (i >= expected.length) { printedArgs.push( diff --git a/packages/expect/src/utils.js b/packages/expect/src/utils.js index a6cc277952e6..1f3500d36ba0 100644 --- a/packages/expect/src/utils.js +++ b/packages/expect/src/utils.js @@ -221,3 +221,10 @@ export const isError = (value: any) => { export function emptyObject(obj: any) { return obj && typeof obj === 'object' ? !Object.keys(obj).length : false; } + +const MULTILINE_REGEXP = /[\r\n]/; + +export const isOneline = (expected: any, received: any) => + typeof expected === 'string' && + typeof received === 'string' && + (!MULTILINE_REGEXP.test(expected) || !MULTILINE_REGEXP.test(received)); diff --git a/packages/jest-diff/src/__tests__/__snapshots__/diff.test.js.snap b/packages/jest-diff/src/__tests__/__snapshots__/diff.test.js.snap index e6dc7169be86..35d624575ff4 100644 --- a/packages/jest-diff/src/__tests__/__snapshots__/diff.test.js.snap +++ b/packages/jest-diff/src/__tests__/__snapshots__/diff.test.js.snap @@ -208,3 +208,37 @@ exports[`highlight only the last in odd length of leading spaces (expanded) 1`] + }, {}); " `; + +exports[`oneline strings 1`] = ` +"- Expected ++ Received + +- ab ++ aa" +`; + +exports[`oneline strings 2`] = ` +"- Expected ++ Received + +- 123456789 ++ 234567890" +`; + +exports[`oneline strings 3`] = ` +"- Expected ++ Received + +- oneline ++ multi ++ line" +`; + +exports[`oneline strings 4`] = ` +"- Expected ++ Received + +- multi +- line ++ oneline" +`; diff --git a/packages/jest-diff/src/__tests__/diff.test.js b/packages/jest-diff/src/__tests__/diff.test.js index 6a1f05f37b70..7c60ca75eba6 100644 --- a/packages/jest-diff/src/__tests__/diff.test.js +++ b/packages/jest-diff/src/__tests__/diff.test.js @@ -82,12 +82,10 @@ describe('no visual difference', () => { }); test('oneline strings', () => { - // oneline strings don't produce a diff currently. - expect(diff('ab', 'aa')).toBe(null); - expect(diff('123456789', '234567890')).toBe(null); - // if either string is oneline - expect(diff('oneline', 'multi\nline')).toBe(null); - expect(diff('multi\nline', 'oneline')).toBe(null); + expect(diff('ab', 'aa')).toMatchSnapshot(); + expect(diff('123456789', '234567890')).toMatchSnapshot(); + expect(diff('oneline', 'multi\nline')).toMatchSnapshot(); + expect(diff('multi\nline', 'oneline')).toMatchSnapshot(); }); describe('falls back to not call toJSON', () => { diff --git a/packages/jest-diff/src/diff_strings.js b/packages/jest-diff/src/diff_strings.js index 1afc95ecbbb4..522268b4d4d5 100644 --- a/packages/jest-diff/src/diff_strings.js +++ b/packages/jest-diff/src/diff_strings.js @@ -9,8 +9,8 @@ import chalk from 'chalk'; import {diffLines, structuredPatch} from 'diff'; - import {NO_DIFF_MESSAGE} from './constants.js'; + const DIFF_CONTEXT_DEFAULT = 5; export type DiffOptions = {| diff --git a/packages/jest-diff/src/index.js b/packages/jest-diff/src/index.js index 58024d26a4a4..ecee23658b66 100644 --- a/packages/jest-diff/src/index.js +++ b/packages/jest-diff/src/index.js @@ -47,8 +47,6 @@ const FALLBACK_FORMAT_OPTIONS_0 = Object.assign({}, FALLBACK_FORMAT_OPTIONS, { indent: 0, }); -const MULTILINE_REGEXP = /[\r\n]/; - // Generate a string that will highlight the difference between two values // with green and red. (similar to how github does code diffing) function diff(a: any, b: any, options: ?DiffOptions): ?string { @@ -88,11 +86,7 @@ function diff(a: any, b: any, options: ?DiffOptions): ?string { switch (aType) { case 'string': - const multiline = MULTILINE_REGEXP.test(a) && b.indexOf('\n') !== -1; - if (multiline) { - return diffStrings(a, b, options); - } - return null; + return diffStrings(a, b, options); case 'number': case 'boolean': return null;