Skip to content

Commit

Permalink
expect: Improve report when matcher fails, part 8 (#7876)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrottimark authored and SimenB committed Feb 13, 2019
1 parent 0cf47c4 commit 5050654
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 82 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,7 @@
### Features

- `[expect]`: Improve report when matcher fails, part 7 ([#7866](https://github.com/facebook/jest/pull/7866))
- `[expect]`: Improve report when matcher fails, part 8 ([#7876](https://github.com/facebook/jest/pull/7876))

### Fixes

Expand Down
175 changes: 107 additions & 68 deletions packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap
Expand Up @@ -389,139 +389,178 @@ Received: <red>true</>"
`;

exports[`.toBeCloseTo() {pass: false} expect(-Infinity)toBeCloseTo( -1.23) 1`] = `
"<dim>expect(</><red>received</><dim>).toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>-1.23</>
Received: <red>-Infinity</>"
Expected: <green>-1.23</>
Received: <red>-Infinity</>

Expected precision: <green>2</>
Expected difference: < <green>0.005</>
Received difference: <red>Infinity</>"
`;

exports[`.toBeCloseTo() {pass: false} expect(Infinity)toBeCloseTo( -Infinity) 1`] = `
"<dim>expect(</><red>received</><dim>).toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Expected: <green>-Infinity</>
Received: <red>Infinity</>

Precision: <green>2</>-digit
Expected: <green>-Infinity</>
Received: <red>Infinity</>"
Expected precision: <green>2</>
Expected difference: < <green>0.005</>
Received difference: <red>Infinity</>"
`;

exports[`.toBeCloseTo() {pass: false} expect(Infinity)toBeCloseTo( 1.23) 1`] = `
"<dim>expect(</><red>received</><dim>).toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Expected: <green>1.23</>
Received: <red>Infinity</>

Precision: <green>2</>-digit
Expected: <green>1.23</>
Received: <red>Infinity</>"
Expected precision: <green>2</>
Expected difference: < <green>0.005</>
Received difference: <red>Infinity</>"
`;

exports[`.toBeCloseTo() {pass: true} expect(-Infinity)toBeCloseTo( -Infinity) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>-Infinity</>
Received: <red>-Infinity</>"
Expected: not <green>-Infinity</>
"
`;

exports[`.toBeCloseTo() {pass: true} expect(0)toBeCloseTo( 0) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>0</>
Received: <red>0</>"
Expected: not <green>0</>
"
`;

exports[`.toBeCloseTo() {pass: true} expect(0)toBeCloseTo( 0.001) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>0.001</>
Received: <red>0</>"
Expected: not <green>0.001</>
Received: <red>0</>

Expected precision: <green>2</>
Expected difference: not < <green>0.005</>
Received difference: <red>0.001</>"
`;

exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.225) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Expected: not <green>1.225</>
Received: <red>1.23</>

Precision: <green>2</>-digit
Expected: <green>1.225</>
Received: <red>1.23</>"
Expected precision: <green>2</>
Expected difference: not < <green>0.005</>
Received difference: <red>0.004999999999999893</>"
`;

exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.226) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>1.226</>
Received: <red>1.23</>"
Expected: not <green>1.226</>
Received: <red>1.23</>

Expected precision: <green>2</>
Expected difference: not < <green>0.005</>
Received difference: <red>0.0040000000000000036</>"
`;

exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.229) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Expected: not <green>1.229</>
Received: <red>1.23</>

Precision: <green>2</>-digit
Expected: <green>1.229</>
Received: <red>1.23</>"
Expected precision: <green>2</>
Expected difference: not < <green>0.005</>
Received difference: <red>0.0009999999999998899</>"
`;

exports[`.toBeCloseTo() {pass: true} expect(1.23)toBeCloseTo( 1.234) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>1.234</>
Received: <red>1.23</>"
Expected: not <green>1.234</>
Received: <red>1.23</>

Expected precision: <green>2</>
Expected difference: not < <green>0.005</>
Received difference: <red>0.0040000000000000036</>"
`;

exports[`.toBeCloseTo() {pass: true} expect(Infinity)toBeCloseTo( Infinity) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>Infinity</>
Received: <red>Infinity</>"
Expected: not <green>Infinity</>
"
`;

exports[`.toBeCloseTo() accepts an optional precision argument: [0, 0.000004, 5] 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>, </><green>precision</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>

Precision: <green>5</>-digit
Expected: <green>0.000004</>
Received: <red>0</>"
Expected: not <green>0.000004</>
Received: <red>0</>

Expected precision: <green>5</>
Expected difference: not < <green>0.000005</>
Received difference: <red>0.000004</>"
`;

exports[`.toBeCloseTo() accepts an optional precision argument: [0, 0.0001, 3] 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>, </><green>precision</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>

Expected: not <green>0.0001</>
Received: <red>0</>

Precision: <green>3</>-digit
Expected: <green>0.0001</>
Received: <red>0</>"
Expected precision: <green>3</>
Expected difference: not < <green>0.0005</>
Received difference: <red>0.0001</>"
`;

exports[`.toBeCloseTo() accepts an optional precision argument: [0, 0.1, 0] 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toBeCloseTo(</><green>expected</><dim>, </><green>precision</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>

Precision: <green>0</>-digit
Expected: <green>0.1</>
Received: <red>0</>"
Expected: not <green>0.1</>
Received: <red>0</>

Expected precision: <green>0</>
Expected difference: not < <green>0.5</>
Received difference: <red>0.1</>"
`;

exports[`.toBeCloseTo() throws: [0, 0.01] 1`] = `
"<dim>expect(</><red>received</><dim>).toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Expected: <green>0.01</>
Received: <red>0</>

Precision: <green>2</>-digit
Expected: <green>0.01</>
Received: <red>0</>"
Expected precision: <green>2</>
Expected difference: < <green>0.005</>
Received difference: <red>0.01</>"
`;

exports[`.toBeCloseTo() throws: [1, 1.23] 1`] = `
"<dim>expect(</><red>received</><dim>).toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Precision: <green>2</>-digit
Expected: <green>1.23</>
Received: <red>1</>"
Expected: <green>1.23</>
Received: <red>1</>

Expected precision: <green>2</>
Expected difference: < <green>0.005</>
Received difference: <red>0.22999999999999998</>"
`;

exports[`.toBeCloseTo() throws: [1.23, 1.2249999] 1`] = `
"<dim>expect(</><red>received</><dim>).toBeCloseTo(</><green>expected</><dim>)</>
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

Expected: <green>1.2249999</>
Received: <red>1.23</>

Precision: <green>2</>-digit
Expected: <green>1.2249999</>
Received: <red>1.23</>"
Expected precision: <green>2</>
Expected difference: < <green>0.005</>
Received difference: <red>0.005000099999999952</>"
`;

exports[`.toBeDefined(), .toBeUndefined() '"a"' is defined 1`] = `
Expand Down
54 changes: 40 additions & 14 deletions packages/expect/src/matchers.js
Expand Up @@ -87,25 +87,51 @@ const matchers: MatchersObject = {
return {actual: received, expected, message, name: 'toBe', pass};
},

toBeCloseTo(actual: number, expected: number, precision?: number = 2) {
toBeCloseTo(received: number, expected: number, precision?: number = 2) {
const secondArgument = arguments.length === 3 ? 'precision' : null;
ensureNumbers(actual, expected, '.toBeCloseTo');
const isNot = this.isNot;
const options = {
isNot,
promise: this.promise,
secondArgument,
};
ensureNumbers(received, expected, '.toBeCloseTo');

let pass = false;
let expectedDiff = 0;
let receivedDiff = 0;

if (actual == Infinity && expected == Infinity) pass = true;
else if (actual == -Infinity && expected == -Infinity) pass = true;
else pass = Math.abs(expected - actual) < Math.pow(10, -precision) / 2;
if (received === Infinity && expected === Infinity) {
pass = true; // Infinity - Infinity is NaN
} else if (received === -Infinity && expected === -Infinity) {
pass = true; // -Infinity - -Infinity is NaN
} else {
expectedDiff = Math.pow(10, -precision) / 2;
receivedDiff = Math.abs(expected - received);
pass = receivedDiff < expectedDiff;
}

const message = () =>
matcherHint('.toBeCloseTo', undefined, undefined, {
isNot: this.isNot,
secondArgument,
}) +
'\n\n' +
`Precision: ${printExpected(precision)}-digit\n` +
`Expected: ${printExpected(expected)}\n` +
`Received: ${printReceived(actual)}`;
const message = pass
? () =>
matcherHint('toBeCloseTo', undefined, undefined, options) +
'\n\n' +
`Expected: not ${printExpected(expected)}\n` +
(receivedDiff === 0
? ''
: `Received: ${printReceived(received)}\n` +
'\n' +
`Expected precision: ${printExpected(precision)}\n` +
`Expected difference: not < ${printExpected(expectedDiff)}\n` +
`Received difference: ${printReceived(receivedDiff)}`)
: () =>
matcherHint('toBeCloseTo', undefined, undefined, options) +
'\n\n' +
`Expected: ${printExpected(expected)}\n` +
`Received: ${printReceived(received)}\n` +
'\n' +
`Expected precision: ${printExpected(precision)}\n` +
`Expected difference: < ${printExpected(expectedDiff)}\n` +
`Received difference: ${printReceived(receivedDiff)}`;

return {message, pass};
},
Expand Down

0 comments on commit 5050654

Please sign in to comment.