diff --git a/CHANGELOG.md b/CHANGELOG.md index 1103eb67fcec..ad3d540e7574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features - `[jest-runtime]` Add `jest.isolateModules` for scoped module initialization ([#6701](https://github.com/facebook/jest/pull/6701)) +- `[jest-diff]` [**BREAKING**] Support diffing numbers and booleans instead of returning null for different ones ([#7605](https://github.com/facebook/jest/pull/7605)) - `[jest-diff]` [**BREAKING**] Replace `diff` with `diff-sequences` package ([#6961](https://github.com/facebook/jest/pull/6961)) - `[jest-cli]` [**BREAKING**] Only set error process error codes when they are non-zero ([#7363](https://github.com/facebook/jest/pull/7363)) - `[jest-config]` [**BREAKING**] Deprecate `setupTestFrameworkScriptFile` in favor of new `setupFilesAfterEnv` ([#7119](https://github.com/facebook/jest/pull/7119)) diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index 345f40341f87..0ea765ed015b 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -66,7 +66,10 @@ const matchers: MatchersObject = { (receivedType === 'object' || expectedType === 'array') && equals(received, expected, [iterableEquality]); const oneline = isOneline(expected, received); - const diffString = diff(expected, received, {expand: this.expand}); + const diffString = diff(expected, received, { + expand: this.expand, + omitTrivial: true, + }); return ( matcherHint('.toBe', undefined, undefined, { @@ -420,7 +423,10 @@ const matchers: MatchersObject = { `Expected: ${printExpected(expected)}\n` + `Received: ${printReceived(received)}` : () => { - const diffString = diff(expected, received, {expand: this.expand}); + const diffString = diff(expected, received, { + expand: this.expand, + omitTrivial: true, + }); return ( matcherHint('.toEqual', undefined, undefined, { @@ -552,7 +558,10 @@ const matchers: MatchersObject = { : () => { const diffString = valuePassed && hasEndProp - ? diff(value, result.value, {expand: this.expand}) + ? diff(value, result.value, { + expand: this.expand, + omitTrivial: true, + }) : ''; return ( matcherHint('.toHaveProperty', 'object', 'path', { @@ -677,6 +686,7 @@ const matchers: MatchersObject = { getObjectSubset(receivedObject, expectedObject), { expand: this.expand, + omitTrivial: true, }, ); return ( @@ -712,6 +722,7 @@ const matchers: MatchersObject = { : () => { const diffString = diff(expected, received, { expand: this.expand, + omitTrivial: true, }); return hint + (diffString ? `\n\nDifference:\n\n${diffString}` : ''); }; diff --git a/packages/expect/src/spyMatchers.js b/packages/expect/src/spyMatchers.js index 0d7016a2d37b..2bffe5b186b1 100644 --- a/packages/expect/src/spyMatchers.js +++ b/packages/expect/src/spyMatchers.js @@ -566,7 +566,7 @@ const formatMismatchedArgs = (expected, received) => { 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]); + const diffString = diff(expected[i], received[i], {omitTrivial: true}); printedArgs.push( ` ${printExpected(expected[i])}\n` + `as argument ${i + 1}, but it was called with\n` + diff --git a/packages/jest-circus/src/formatNodeAssertErrors.js b/packages/jest-circus/src/formatNodeAssertErrors.js index 792ef5ad0641..abc20add3ea9 100644 --- a/packages/jest-circus/src/formatNodeAssertErrors.js +++ b/packages/jest-circus/src/formatNodeAssertErrors.js @@ -66,7 +66,12 @@ const formatNodeAssertErrors = (event: Event, state: State) => { error = errors; } return error.code === 'ERR_ASSERTION' - ? {message: assertionErrorMessage(error, {expand: state.expand})} + ? { + message: assertionErrorMessage(error, { + expand: state.expand, + omitTrivial: true, + }), + } : errors; }); } diff --git a/packages/jest-diff/src/__tests__/diff.test.js b/packages/jest-diff/src/__tests__/diff.test.js index 58a622b89c18..fc6a2ddf4480 100644 --- a/packages/jest-diff/src/__tests__/diff.test.js +++ b/packages/jest-diff/src/__tests__/diff.test.js @@ -48,9 +48,12 @@ describe('no visual difference', () => { [[], []], [[1, 2], [1, 2]], [11, 11], + [NaN, NaN], + [Number.NaN, NaN], [() => {}, () => {}], [null, null], [undefined, undefined], + [false, false], [{a: 1}, {a: 1}], [{a: {b: 5}}, {a: {b: 5}}], ].forEach(values => { @@ -178,13 +181,25 @@ describe('objects', () => { }); test('numbers', () => { - const result = diff(123, 234); - expect(result).toBe(null); + expect(stripped(1, 2)).toEqual(expect.stringContaining('- 1\n+ 2')); +}); + +test('-0 and 0', () => { + expect(stripped(-0, 0)).toEqual(expect.stringContaining('- -0\n+ 0')); +}); + +test('numbers with omitTrivial', () => { + expect(diff(1, 2, {omitTrivial: true})).toBeNull(); }); test('booleans', () => { - const result = diff(true, false); - expect(result).toBe(null); + expect(stripped(false, true)).toEqual( + expect.stringContaining('- false\n+ true'), + ); +}); + +test('booleans with omitTrivial', () => { + expect(diff(false, true, {omitTrivial: true})).toBeNull(); }); describe('multiline string non-snapshot', () => { diff --git a/packages/jest-diff/src/diffStrings.js b/packages/jest-diff/src/diffStrings.js index 474278d63fe4..c85b2c9bba04 100644 --- a/packages/jest-diff/src/diffStrings.js +++ b/packages/jest-diff/src/diffStrings.js @@ -19,6 +19,10 @@ export type DiffOptions = {| bAnnotation?: string, expand?: boolean, contextLines?: number, + // Return null instead of diffing numbers or booleans. + // Jest uses this because the matchers already print a short failure reason, + // so the diff output would be redundant for those types. + omitTrivial?: boolean, |}; type Original = {| diff --git a/packages/jest-diff/src/index.js b/packages/jest-diff/src/index.js index 1b588af4cbc4..21de0e8c6b0c 100644 --- a/packages/jest-diff/src/index.js +++ b/packages/jest-diff/src/index.js @@ -87,9 +87,10 @@ function diff(a: any, b: any, options: ?DiffOptions): ?string { switch (aType) { case 'string': return diffStrings(a, b, options); - case 'number': case 'boolean': - return null; + return compareTrivial(a, b, options); + case 'number': + return compareTrivial(a, b, options); case 'map': return compareObjects(sortMap(a), sortMap(b), options); case 'set': @@ -99,6 +100,22 @@ function diff(a: any, b: any, options: ?DiffOptions): ?string { } } +function compareTrivial( + a: number | boolean, + b: number | boolean, + options: ?DiffOptions, +) { + if (options && options.omitTrivial) { + return null; + } + + return diffStrings( + prettyFormat(a, FORMAT_OPTIONS), + prettyFormat(b, FORMAT_OPTIONS), + options, + ); +} + function sortMap(map) { return new Map(Array.from(map.entries()).sort()); } diff --git a/packages/jest-jasmine2/src/jasmine/Env.js b/packages/jest-jasmine2/src/jasmine/Env.js index 49e8963980b7..2c4ab15ed285 100644 --- a/packages/jest-jasmine2/src/jasmine/Env.js +++ b/packages/jest-jasmine2/src/jasmine/Env.js @@ -578,7 +578,10 @@ export default function(j$) { if (error instanceof AssertionError) { checkIsError = false; - message = assertionErrorMessage(error, {expand: j$.Spec.expand}); + message = assertionErrorMessage(error, { + expand: j$.Spec.expand, + omitTrivial: true, + }); } else { const check = isError(error); diff --git a/packages/jest-jasmine2/src/jasmine/Spec.js b/packages/jest-jasmine2/src/jasmine/Spec.js index fd729e0b2c80..8c1b14050a71 100644 --- a/packages/jest-jasmine2/src/jasmine/Spec.js +++ b/packages/jest-jasmine2/src/jasmine/Spec.js @@ -153,7 +153,10 @@ Spec.prototype.onException = function onException(error) { } if (error instanceof AssertionError) { - error = assertionErrorMessage(error, {expand: this.expand}); + error = assertionErrorMessage(error, { + expand: this.expand, + omitTrivial: true, + }); } this.addExpectationResult( diff --git a/packages/jest-snapshot/src/index.js b/packages/jest-snapshot/src/index.js index 7c0cb0687303..b6a90197a1eb 100644 --- a/packages/jest-snapshot/src/index.js +++ b/packages/jest-snapshot/src/index.js @@ -186,6 +186,7 @@ const _toMatchSnapshot = ({ aAnnotation: 'Snapshot', bAnnotation: 'Received', expand: snapshotState.expand, + omitTrivial: true, }); report = () => diff --git a/packages/pretty-format/src/__tests__/getPrettyPrint.js b/packages/pretty-format/src/__tests__/getPrettyPrint.js index b5dd8e4b2dde..7f682a741d47 100644 --- a/packages/pretty-format/src/__tests__/getPrettyPrint.js +++ b/packages/pretty-format/src/__tests__/getPrettyPrint.js @@ -38,6 +38,7 @@ const getPrettyPrint = (plugins: Plugins) => : () => { const diffString = diff(expected, prettyFormatted, { expand: this.expand, + omitTrivial: true, }); return ( this.utils.matcherHint('.toBe') +