Skip to content

Commit

Permalink
expect, jest-matcher-utils: Improve report when matcher fails, part 9 (
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrottimark authored and SimenB committed Feb 22, 2019
1 parent bc892ed commit 9b802c2
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

- `[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))
- `[expect]`: Improve report when matcher fails, part 9 ([#7940](https://github.com/facebook/jest/pull/7940))
- `[pretty-format]` Support `React.memo` ([#7891](https://github.com/facebook/jest/pull/7891))
- `[jest-config]` Print error information on preset normalization error ([#7935](https://github.com/facebook/jest/pull/7935))

Expand Down
52 changes: 52 additions & 0 deletions packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap
Expand Up @@ -563,6 +563,58 @@ Expected difference: < <green>0.005</>
Received difference: <red>0.005000099999999952</>"
`;

exports[`.toBeCloseTo() throws: Matcher error promise empty isNot false received 1`] = `
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>

<bold>Matcher error</>: <red>received</> value must be a number

Received has type: string
Received has value: <red>\\"\\"</>"
`;

exports[`.toBeCloseTo() throws: Matcher error promise empty isNot true expected 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

<bold>Matcher error</>: <green>expected</> value must be a number

Expected has value: <green>undefined</>"
`;

exports[`.toBeCloseTo() throws: Matcher error promise rejects isNot false expected 1`] = `
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

<bold>Matcher error</>: <green>expected</> value must be a number

Expected has type: string
Expected has value: <green>\\"0\\"</>"
`;

exports[`.toBeCloseTo() throws: Matcher error promise rejects isNot true received 1`] = `
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>

<bold>Matcher error</>: <red>received</> value must be a number

Received has type: symbol
Received has value: <red>Symbol(0.1)</>"
`;

exports[`.toBeCloseTo() throws: Matcher error promise resolves isNot false received 1`] = `
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>

<bold>Matcher error</>: <red>received</> value must be a number

Received has type: boolean
Received has value: <red>false</>"
`;

exports[`.toBeCloseTo() throws: Matcher error promise resolves isNot true expected 1`] = `
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>

<bold>Matcher error</>: <green>expected</> value must be a number

Expected has value: <green>null</>"
`;

exports[`.toBeDefined(), .toBeUndefined() '"a"' is defined 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeDefined<dim>()</>

Expand Down
53 changes: 53 additions & 0 deletions packages/expect/src/__tests__/matchers.test.js
Expand Up @@ -1006,6 +1006,59 @@ describe('.toBeCloseTo()', () => {
).toThrowErrorMatchingSnapshot();
});
});

describe('throws: Matcher error', () => {
test('promise empty isNot false received', () => {
const precision = 3;
const expected = 0;
const received = '';
expect(() => {
jestExpect(received).toBeCloseTo(expected, precision);
}).toThrowErrorMatchingSnapshot();
});

test('promise empty isNot true expected', () => {
const received = 0.1;
// expected is undefined
expect(() => {
jestExpect(received).not.toBeCloseTo();
}).toThrowErrorMatchingSnapshot();
});

test('promise rejects isNot false expected', () => {
const expected = '0';
const received = Promise.reject(0.01);
return expect(
jestExpect(received).rejects.toBeCloseTo(expected),
).rejects.toThrowErrorMatchingSnapshot();
});

test('promise rejects isNot true received', () => {
const expected = 0;
const received = Promise.reject(Symbol('0.1'));
return expect(
jestExpect(received).rejects.not.toBeCloseTo(expected),
).rejects.toThrowErrorMatchingSnapshot();
});

test('promise resolves isNot false received', () => {
const precision = 3;
const expected = 0;
const received = Promise.resolve(false);
return expect(
jestExpect(received).resolves.toBeCloseTo(expected, precision),
).rejects.toThrowErrorMatchingSnapshot();
});

test('promise resolves isNot true expected', () => {
const precision = 3;
const expected = null;
const received = Promise.resolve(0.1);
expect(
jestExpect(received).resolves.not.toBeCloseTo(expected, precision),
).rejects.toThrowErrorMatchingSnapshot();
});
});
});

describe('.toMatch()', () => {
Expand Down
13 changes: 6 additions & 7 deletions packages/expect/src/matchers.ts
Expand Up @@ -93,13 +93,12 @@ const matchers: MatchersObject = {
precision: number = 2,
) {
const secondArgument = arguments.length === 3 ? 'precision' : undefined;
const isNot = this.isNot;
const options: MatcherHintOptions = {
isNot,
isNot: this.isNot,
promise: this.promise,
secondArgument,
};
ensureNumbers(received, expected, '.toBeCloseTo');
ensureNumbers(received, expected, 'toBeCloseTo', options);

let pass = false;
let expectedDiff = 0;
Expand Down Expand Up @@ -180,7 +179,7 @@ const matchers: MatchersObject = {
isNot,
promise: this.promise,
};
ensureNumbers(received, expected, '.toBeGreaterThan');
ensureNumbers(received, expected, 'toBeGreaterThan', options);

const pass = received > expected;

Expand All @@ -203,7 +202,7 @@ const matchers: MatchersObject = {
isNot,
promise: this.promise,
};
ensureNumbers(received, expected, '.toBeGreaterThanOrEqual');
ensureNumbers(received, expected, 'toBeGreaterThanOrEqual', options);

const pass = received >= expected;

Expand Down Expand Up @@ -266,7 +265,7 @@ const matchers: MatchersObject = {
isNot,
promise: this.promise,
};
ensureNumbers(received, expected, '.toBeLessThan');
ensureNumbers(received, expected, 'toBeLessThan', options);

const pass = received < expected;

Expand All @@ -285,7 +284,7 @@ const matchers: MatchersObject = {
isNot,
promise: this.promise,
};
ensureNumbers(received, expected, '.toBeLessThanOrEqual');
ensureNumbers(received, expected, 'toBeLessThanOrEqual', options);

const pass = received <= expected;

Expand Down
Expand Up @@ -18,24 +18,76 @@ Expected has type: object
Expected has value: <green>{\\"a\\": 1}</>"
`;
exports[`.ensureNumbers() throws error when expected is not a number 1`] = `
"<dim>expect(</><red>received</><dim>)[.not]This matcher(</><green>expected</><dim>)</>
exports[`.ensureNumbers() throws error when expected is not a number (backward compatibility) 1`] = `
"<dim>expect(</><red>received</><dim>)[.not].toBeCloseTo(</><green>expected</><dim>)</>
<bold>Matcher error</>: <green>expected</> value must be a number
Expected has type: string
Expected has value: <green>\\"not_a_number\\"</>"
`;
exports[`.ensureNumbers() throws error when received is not a number 1`] = `
"<dim>expect(</><red>received</><dim>)[.not]This matcher(</><green>expected</><dim>)</>
exports[`.ensureNumbers() throws error when received is not a number (backward compatibility) 1`] = `
"<dim>expect(</><red>received</><dim>)[.not].toBeCloseTo(</><green>expected</><dim>)</>
<bold>Matcher error</>: <red>received</> value must be a number
Received has type: string
Received has value: <red>\\"not_a_number\\"</>"
`;
exports[`.ensureNumbers() with options promise empty isNot false received 1`] = `
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>
<bold>Matcher error</>: <red>received</> value must be a number
Received has type: string
Received has value: <red>\\"\\"</>"
`;
exports[`.ensureNumbers() with options promise empty isNot true expected 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
<bold>Matcher error</>: <green>expected</> value must be a number
Expected has value: <green>undefined</>"
`;
exports[`.ensureNumbers() with options promise rejects isNot false expected 1`] = `
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
<bold>Matcher error</>: <green>expected</> value must be a number
Expected has type: string
Expected has value: <green>\\"0\\"</>"
`;
exports[`.ensureNumbers() with options promise rejects isNot true received 1`] = `
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
<bold>Matcher error</>: <red>received</> value must be a number
Received has type: symbol
Received has value: <red>Symbol(0.1)</>"
`;
exports[`.ensureNumbers() with options promise resolves isNot false received 1`] = `
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
<bold>Matcher error</>: <red>received</> value must be a number
Received has type: boolean
Received has value: <red>false</>"
`;
exports[`.ensureNumbers() with options promise resolves isNot true expected 1`] = `
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
<bold>Matcher error</>: <green>expected</> value must be a number
Expected has value: <green>null</>"
`;
exports[`.stringify() reduces maxDepth if stringifying very large objects 1`] = `"{\\"a\\": 1, \\"b\\": [Object]}"`;
exports[`.stringify() reduces maxDepth if stringifying very large objects 2`] = `"{\\"a\\": 1, \\"b\\": {\\"0\\": \\"test\\", \\"1\\": \\"test\\", \\"2\\": \\"test\\", \\"3\\": \\"test\\", \\"4\\": \\"test\\", \\"5\\": \\"test\\", \\"6\\": \\"test\\", \\"7\\": \\"test\\", \\"8\\": \\"test\\", \\"9\\": \\"test\\"}}"`;
Expand Down
80 changes: 76 additions & 4 deletions packages/jest-matcher-utils/src/__tests__/index.test.ts
Expand Up @@ -13,6 +13,7 @@ import {
getLabelPrinter,
pluralize,
stringify,
MatcherHintOptions,
} from '../';

describe('.stringify()', () => {
Expand Down Expand Up @@ -98,19 +99,90 @@ describe('.ensureNumbers()', () => {
}).not.toThrow();
});

test('throws error when expected is not a number', () => {
test('throws error when expected is not a number (backward compatibility)', () => {
expect(() => {
// @ts-ignore
ensureNumbers(1, 'not_a_number');
ensureNumbers(1, 'not_a_number', '.toBeCloseTo');
}).toThrowErrorMatchingSnapshot();
});

test('throws error when received is not a number', () => {
test('throws error when received is not a number (backward compatibility)', () => {
expect(() => {
// @ts-ignore
ensureNumbers('not_a_number', 3);
ensureNumbers('not_a_number', 3, '.toBeCloseTo');
}).toThrowErrorMatchingSnapshot();
});

describe('with options', () => {
const matcherName = 'toBeCloseTo';

test('promise empty isNot false received', () => {
const options: MatcherHintOptions = {
isNot: false,
promise: '',
secondArgument: 'precision',
};
expect(() => {
// @ts-ignore
ensureNumbers('', 0, matcherName, options);
}).toThrowErrorMatchingSnapshot();
});

test('promise empty isNot true expected', () => {
const options: MatcherHintOptions = {
isNot: true,
// promise undefined is equivalent to empty string
};
expect(() => {
// @ts-ignore
ensureNumbers(0.1, undefined, matcherName, options);
}).toThrowErrorMatchingSnapshot();
});

test('promise rejects isNot false expected', () => {
const options: MatcherHintOptions = {
isNot: false,
promise: 'rejects',
};
expect(() => {
// @ts-ignore
ensureNumbers(0.01, '0', matcherName, options);
}).toThrowErrorMatchingSnapshot();
});

test('promise rejects isNot true received', () => {
const options: MatcherHintOptions = {
isNot: true,
promise: 'rejects',
};
expect(() => {
// @ts-ignore
ensureNumbers(Symbol('0.1'), 0, matcherName, options);
}).toThrowErrorMatchingSnapshot();
});

test('promise resolves isNot false received', () => {
const options: MatcherHintOptions = {
isNot: false,
promise: 'resolves',
};
expect(() => {
// @ts-ignore
ensureNumbers(false, 0, matcherName, options);
}).toThrowErrorMatchingSnapshot();
});

test('promise resolves isNot true expected', () => {
const options: MatcherHintOptions = {
isNot: true,
promise: 'resolves',
};
expect(() => {
// @ts-ignore
ensureNumbers(0.1, null, matcherName, options);
}).toThrowErrorMatchingSnapshot();
});
});
});

describe('.ensureNoExpected()', () => {
Expand Down

0 comments on commit 9b802c2

Please sign in to comment.