From 643beb1617492e37adfc29edd41a3a1a63e8699e Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Fri, 11 Jan 2019 00:02:54 +0100 Subject: [PATCH 1/5] do not claim that -0 and 0 have no visual difference --- CHANGELOG.md | 1 + .../src/__tests__/__snapshots__/matchers.test.js.snap | 6 +----- packages/jest-diff/src/index.js | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c60e81dd02b..6d3305ac0c93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ ### Fixes +- `[jest-diff]` Do not claim that `-0` and `0` have no visual difference ([#7605](https://github.com/facebook/jest/pull/7605)) - `[jest-mock]` Fix automock for numeric function names ([#7653](https://github.com/facebook/jest/pull/7653)) - `[jest-config]` Ensure `existsSync` is only called with a string parameter ([#7607](https://github.com/facebook/jest/pull/7607)) - `[expect]` `toStrictEqual` considers sparseness of arrays. ([#7591](https://github.com/facebook/jest/pull/7591)) diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index f8e39e5fc99a..1debb403a675 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -360,11 +360,7 @@ exports[`.toBe() fails for: -0 and 0 1`] = ` "expect(received).toBe(expected) // Object.is equality Expected: 0 -Received: -0 - -Difference: - -Compared values have no visual difference." +Received: -0" `; exports[`.toBe() fails for: 1 and 2 1`] = ` diff --git a/packages/jest-diff/src/index.js b/packages/jest-diff/src/index.js index 716e863fb1c4..32b62ae4b9dc 100644 --- a/packages/jest-diff/src/index.js +++ b/packages/jest-diff/src/index.js @@ -46,7 +46,7 @@ const FALLBACK_FORMAT_OPTIONS_0 = {...FALLBACK_FORMAT_OPTIONS, indent: 0}; // 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 { - if (a === b) { + if (Object.is(a, b)) { return NO_DIFF_MESSAGE; } From 367343a58177b218d13dc641ce4d2af6d9238a00 Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Sun, 20 Jan 2019 17:59:23 +0100 Subject: [PATCH 2/5] support jest-diffing numbers and booleans --- CHANGELOG.md | 1 + packages/expect/src/matchers.js | 6 ++++- packages/jest-diff/src/__tests__/diff.test.js | 15 ++++++++--- packages/jest-diff/src/index.js | 16 ++++++++++-- .../src/__tests__/index.test.js | 25 +++++++++++++++++++ packages/jest-matcher-utils/src/index.js | 13 ++++++++++ 6 files changed, 69 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d3305ac0c93..2937be0fe079 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..6cfc3c8c119e 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -9,7 +9,7 @@ import type {MatchersObject} from 'types/Matchers'; -import diff from 'jest-diff'; +import jestDiff from 'jest-diff'; import getType from 'jest-get-type'; import {escapeStrForRegex} from 'jest-regex-util'; import { @@ -25,6 +25,7 @@ import { printReceived, printExpected, printWithType, + shouldPrintDiff, } from 'jest-matcher-utils'; import { getObjectSubset, @@ -44,6 +45,9 @@ type ContainIterable = | DOMTokenList | HTMLCollection; +const diff: typeof jestDiff = (a, b, options) => + shouldPrintDiff(a, b) ? jestDiff(a, b, options) : null; + const matchers: MatchersObject = { toBe(received: any, expected: any) { const comment = 'Object.is equality'; diff --git a/packages/jest-diff/src/__tests__/diff.test.js b/packages/jest-diff/src/__tests__/diff.test.js index 58a622b89c18..50df67c274f7 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,17 @@ 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('booleans', () => { - const result = diff(true, false); - expect(result).toBe(null); + expect(stripped(false, true)).toEqual( + expect.stringContaining('- false\n+ true'), + ); }); describe('multiline string non-snapshot', () => { diff --git a/packages/jest-diff/src/index.js b/packages/jest-diff/src/index.js index 32b62ae4b9dc..a52fa1c1b524 100644 --- a/packages/jest-diff/src/index.js +++ b/packages/jest-diff/src/index.js @@ -83,9 +83,9 @@ function diff(a: any, b: any, options: ?DiffOptions): ?string { switch (aType) { case 'string': return diffStrings(a, b, options); - case 'number': case 'boolean': - return null; + case 'number': + return comparePrimitive(a, b, options); case 'map': return compareObjects(sortMap(a), sortMap(b), options); case 'set': @@ -95,6 +95,18 @@ function diff(a: any, b: any, options: ?DiffOptions): ?string { } } +function comparePrimitive( + a: number | boolean, + b: number | boolean, + options: ?DiffOptions, +) { + 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-matcher-utils/src/__tests__/index.test.js b/packages/jest-matcher-utils/src/__tests__/index.test.js index 229e8f5b8a72..fcd1e1fd7e77 100644 --- a/packages/jest-matcher-utils/src/__tests__/index.test.js +++ b/packages/jest-matcher-utils/src/__tests__/index.test.js @@ -11,6 +11,7 @@ import { ensureNoExpected, getLabelPrinter, pluralize, + shouldPrintDiff, stringify, } from '../'; @@ -129,6 +130,30 @@ describe('.ensureNoExpected()', () => { }); }); +describe('shouldPrintDiff', () => { + test('true', () => { + [ + ['a', 'b'], + ['a', {}], + ['a', null], + ['a', undefined], + ['a', 1], + ['a', true], + [1, true], + ].forEach(([actual, expected]) => + expect(shouldPrintDiff(actual, expected)).toBe(true), + ); + }); + + test('two booleans', () => { + expect(shouldPrintDiff(false, true)).toBe(false); + }); + + test('two numbers', () => { + expect(shouldPrintDiff(1, 2)).toBe(false); + }); +}); + describe('.pluralize()', () => { test('one', () => expect(pluralize('apple', 1)).toEqual('one apple')); test('two', () => expect(pluralize('apple', 2)).toEqual('two apples')); diff --git a/packages/jest-matcher-utils/src/index.js b/packages/jest-matcher-utils/src/index.js index f969e9363b9b..69edbc51b31f 100644 --- a/packages/jest-matcher-utils/src/index.js +++ b/packages/jest-matcher-utils/src/index.js @@ -160,6 +160,19 @@ export const ensureNumbers = ( ensureExpectedIsNumber(expected, matcherName); }; +// Sometimes, e.g. when comparing two numbers, the output from jest-diff +// does not contain more information than the `Expected:` / `Received:` already gives. +// In those cases, we do not print a diff to make the output shorter and not redundant. +export const shouldPrintDiff = (actual: any, expected: any) => { + if (typeof actual === 'number' && typeof expected === 'number') { + return false; + } + if (typeof actual === 'boolean' && typeof expected === 'boolean') { + return false; + } + return true; +}; + export const pluralize = (word: string, count: number) => (NUMBERS[count] || count) + ' ' + word + (count === 1 ? '' : 's'); From 6f7d2098aef8e8b2efd48b51080cb0f871f727c6 Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Sun, 20 Jan 2019 18:46:01 +0100 Subject: [PATCH 3/5] jest-matcher-utils diff --- e2e/__tests__/__snapshots__/failures.test.js.snap | 8 -------- packages/expect/src/matchers.js | 6 +----- packages/jest-circus/src/formatNodeAssertErrors.js | 3 +-- packages/jest-jasmine2/src/assertionErrorMessage.js | 3 +-- packages/jest-matcher-utils/package.json | 1 + .../jest-matcher-utils/src/__tests__/index.test.js | 13 +++++++------ packages/jest-matcher-utils/src/index.js | 5 ++++- 7 files changed, 15 insertions(+), 24 deletions(-) diff --git a/e2e/__tests__/__snapshots__/failures.test.js.snap b/e2e/__tests__/__snapshots__/failures.test.js.snap index 41ff2da7a002..d6cdac0e6940 100644 --- a/e2e/__tests__/__snapshots__/failures.test.js.snap +++ b/e2e/__tests__/__snapshots__/failures.test.js.snap @@ -540,10 +540,6 @@ FAIL __tests__/assertionError.test.js Received: 1 - Difference: - - Compared values have no visual difference. - 33 | 34 | test('assert.notEqual', () => { > 35 | assert.notEqual(1, 1); @@ -677,10 +673,6 @@ FAIL __tests__/assertionError.test.js Message: My custom error message - Difference: - - Compared values have no visual difference. - 53 | 54 | test('assert.notStrictEqual', () => { > 55 | assert.notStrictEqual(1, 1, 'My custom error message'); diff --git a/packages/expect/src/matchers.js b/packages/expect/src/matchers.js index 6cfc3c8c119e..298f1d1cb681 100644 --- a/packages/expect/src/matchers.js +++ b/packages/expect/src/matchers.js @@ -9,7 +9,6 @@ import type {MatchersObject} from 'types/Matchers'; -import jestDiff from 'jest-diff'; import getType from 'jest-get-type'; import {escapeStrForRegex} from 'jest-regex-util'; import { @@ -17,6 +16,7 @@ import { RECEIVED_COLOR, SUGGEST_TO_EQUAL, SUGGEST_TO_CONTAIN_EQUAL, + diff, ensureNoExpected, ensureNumbers, getLabelPrinter, @@ -25,7 +25,6 @@ import { printReceived, printExpected, printWithType, - shouldPrintDiff, } from 'jest-matcher-utils'; import { getObjectSubset, @@ -45,9 +44,6 @@ type ContainIterable = | DOMTokenList | HTMLCollection; -const diff: typeof jestDiff = (a, b, options) => - shouldPrintDiff(a, b) ? jestDiff(a, b, options) : null; - const matchers: MatchersObject = { toBe(received: any, expected: any) { const comment = 'Object.is equality'; diff --git a/packages/jest-circus/src/formatNodeAssertErrors.js b/packages/jest-circus/src/formatNodeAssertErrors.js index 792ef5ad0641..a13caf678687 100644 --- a/packages/jest-circus/src/formatNodeAssertErrors.js +++ b/packages/jest-circus/src/formatNodeAssertErrors.js @@ -10,9 +10,8 @@ import type {DiffOptions} from 'jest-diff/src/diffStrings'; import type {Event, State} from 'types/Circus'; -import {printExpected, printReceived} from 'jest-matcher-utils'; +import {diff, printExpected, printReceived} from 'jest-matcher-utils'; import chalk from 'chalk'; -import diff from 'jest-diff'; import prettyFormat from 'pretty-format'; type AssertionError = {| diff --git a/packages/jest-jasmine2/src/assertionErrorMessage.js b/packages/jest-jasmine2/src/assertionErrorMessage.js index 5051c8d1c250..3e066ae8377d 100644 --- a/packages/jest-jasmine2/src/assertionErrorMessage.js +++ b/packages/jest-jasmine2/src/assertionErrorMessage.js @@ -9,9 +9,8 @@ import type {DiffOptions} from 'jest-diff/src/diffStrings'; -import {printReceived, printExpected} from 'jest-matcher-utils'; +import {diff, printReceived, printExpected} from 'jest-matcher-utils'; import chalk from 'chalk'; -import diff from 'jest-diff'; type AssertionError = {| actual: ?string, diff --git a/packages/jest-matcher-utils/package.json b/packages/jest-matcher-utils/package.json index 15f3019ef755..beaeacc8b9dc 100644 --- a/packages/jest-matcher-utils/package.json +++ b/packages/jest-matcher-utils/package.json @@ -14,6 +14,7 @@ "main": "build/index.js", "dependencies": { "chalk": "^2.0.1", + "jest-diff": "^23.6.0", "jest-get-type": "^22.1.0", "pretty-format": "^23.6.0" } diff --git a/packages/jest-matcher-utils/src/__tests__/index.test.js b/packages/jest-matcher-utils/src/__tests__/index.test.js index fcd1e1fd7e77..703ab50fa0d0 100644 --- a/packages/jest-matcher-utils/src/__tests__/index.test.js +++ b/packages/jest-matcher-utils/src/__tests__/index.test.js @@ -7,11 +7,11 @@ */ import { + diff, ensureNumbers, ensureNoExpected, getLabelPrinter, pluralize, - shouldPrintDiff, stringify, } from '../'; @@ -130,8 +130,9 @@ describe('.ensureNoExpected()', () => { }); }); -describe('shouldPrintDiff', () => { - test('true', () => { +jest.mock('jest-diff', () => () => 'diff output'); +describe('diff', () => { + test('forwards to jest-diff', () => { [ ['a', 'b'], ['a', {}], @@ -141,16 +142,16 @@ describe('shouldPrintDiff', () => { ['a', true], [1, true], ].forEach(([actual, expected]) => - expect(shouldPrintDiff(actual, expected)).toBe(true), + expect(diff(actual, expected)).toBe('diff output'), ); }); test('two booleans', () => { - expect(shouldPrintDiff(false, true)).toBe(false); + expect(diff(false, true)).toBe(null); }); test('two numbers', () => { - expect(shouldPrintDiff(1, 2)).toBe(false); + expect(diff(1, 2)).toBe(null); }); }); diff --git a/packages/jest-matcher-utils/src/index.js b/packages/jest-matcher-utils/src/index.js index 69edbc51b31f..a7b040e867a5 100644 --- a/packages/jest-matcher-utils/src/index.js +++ b/packages/jest-matcher-utils/src/index.js @@ -10,6 +10,7 @@ import type {MatcherHintOptions} from 'types/Matchers'; import chalk from 'chalk'; +import jestDiff from 'jest-diff'; import getType from 'jest-get-type'; import prettyFormat from 'pretty-format'; const { @@ -163,7 +164,7 @@ export const ensureNumbers = ( // Sometimes, e.g. when comparing two numbers, the output from jest-diff // does not contain more information than the `Expected:` / `Received:` already gives. // In those cases, we do not print a diff to make the output shorter and not redundant. -export const shouldPrintDiff = (actual: any, expected: any) => { +const shouldPrintDiff = (actual: any, expected: any) => { if (typeof actual === 'number' && typeof expected === 'number') { return false; } @@ -172,6 +173,8 @@ export const shouldPrintDiff = (actual: any, expected: any) => { } return true; }; +export const diff: typeof jestDiff = (a, b, options) => + shouldPrintDiff(a, b) ? jestDiff(a, b, options) : null; export const pluralize = (word: string, count: number) => (NUMBERS[count] || count) + ' ' + word + (count === 1 ? '' : 's'); From c8273c72504996c18e65856fa4c5483b59273840 Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Sun, 20 Jan 2019 18:55:55 +0100 Subject: [PATCH 4/5] spyMatchers jest-matcher-utils diff --- packages/expect/src/spyMatchers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/expect/src/spyMatchers.js b/packages/expect/src/spyMatchers.js index 0d7016a2d37b..50f623d9c770 100644 --- a/packages/expect/src/spyMatchers.js +++ b/packages/expect/src/spyMatchers.js @@ -13,6 +13,7 @@ const CALL_PRINT_LIMIT = 3; const RETURN_PRINT_LIMIT = 5; const LAST_CALL_PRINT_LIMIT = 1; import { + diff, ensureExpectedIsNumber, ensureNoExpected, EXPECTED_COLOR, @@ -26,7 +27,6 @@ import { } from 'jest-matcher-utils'; import {equals} from './jasmineUtils'; import {iterableEquality, partition, isOneline} from './utils'; -import diff from 'jest-diff'; const createToBeCalledMatcher = matcherName => (received, expected) => { ensureNoExpected(expected, matcherName); From 92214a54a2db7a3d77fb2a0051accabe23c85353 Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Sun, 20 Jan 2019 18:58:48 +0100 Subject: [PATCH 5/5] update package.json jest-diff deps --- packages/expect/package.json | 1 - packages/jest-circus/package.json | 2 +- packages/jest-jasmine2/package.json | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/expect/package.json b/packages/expect/package.json index 0a6b1c3c28c3..f357e11b07a6 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -11,7 +11,6 @@ "browser": "build-es5/index.js", "dependencies": { "ansi-styles": "^3.2.0", - "jest-diff": "^23.6.0", "jest-get-type": "^22.1.0", "jest-matcher-utils": "^23.6.0", "jest-message-util": "^23.4.0", diff --git a/packages/jest-circus/package.json b/packages/jest-circus/package.json index 7778c15cdd52..f3b4ede5d59f 100644 --- a/packages/jest-circus/package.json +++ b/packages/jest-circus/package.json @@ -14,7 +14,6 @@ "co": "^4.6.0", "expect": "^23.6.0", "is-generator-fn": "^2.0.0", - "jest-diff": "^23.6.0", "jest-each": "^23.6.0", "jest-matcher-utils": "^23.6.0", "jest-message-util": "^23.4.0", @@ -25,6 +24,7 @@ }, "devDependencies": { "execa": "^1.0.0", + "jest-diff": "^23.6.0", "jest-runtime": "^23.6.0" }, "engines": { diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index 454a2e9e0d3f..e67ff83d48b4 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -14,7 +14,6 @@ "co": "^4.6.0", "expect": "^23.6.0", "is-generator-fn": "^2.0.0", - "jest-diff": "^23.6.0", "jest-each": "^23.6.0", "jest-matcher-utils": "^23.6.0", "jest-message-util": "^23.4.0", @@ -23,6 +22,7 @@ "pretty-format": "^23.6.0" }, "devDependencies": { + "jest-diff": "^23.6.0", "jest-runtime": "^23.6.0" }, "engines": {