Skip to content

Commit 9b802c2

Browse files
pedrottimarkSimenB
authored andcommitted
expect, jest-matcher-utils: Improve report when matcher fails, part 9 (#7940)
1 parent bc892ed commit 9b802c2

7 files changed

Lines changed: 259 additions & 22 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- `[expect]`: Improve report when matcher fails, part 7 ([#7866](https://github.com/facebook/jest/pull/7866))
66
- `[expect]`: Improve report when matcher fails, part 8 ([#7876](https://github.com/facebook/jest/pull/7876))
7+
- `[expect]`: Improve report when matcher fails, part 9 ([#7940](https://github.com/facebook/jest/pull/7940))
78
- `[pretty-format]` Support `React.memo` ([#7891](https://github.com/facebook/jest/pull/7891))
89
- `[jest-config]` Print error information on preset normalization error ([#7935](https://github.com/facebook/jest/pull/7935))
910

packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,58 @@ Expected difference: < <green>0.005</>
563563
Received difference: <red>0.005000099999999952</>"
564564
`;
565565

566+
exports[`.toBeCloseTo() throws: Matcher error promise empty isNot false received 1`] = `
567+
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>
568+
569+
<bold>Matcher error</>: <red>received</> value must be a number
570+
571+
Received has type: string
572+
Received has value: <red>\\"\\"</>"
573+
`;
574+
575+
exports[`.toBeCloseTo() throws: Matcher error promise empty isNot true expected 1`] = `
576+
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
577+
578+
<bold>Matcher error</>: <green>expected</> value must be a number
579+
580+
Expected has value: <green>undefined</>"
581+
`;
582+
583+
exports[`.toBeCloseTo() throws: Matcher error promise rejects isNot false expected 1`] = `
584+
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
585+
586+
<bold>Matcher error</>: <green>expected</> value must be a number
587+
588+
Expected has type: string
589+
Expected has value: <green>\\"0\\"</>"
590+
`;
591+
592+
exports[`.toBeCloseTo() throws: Matcher error promise rejects isNot true received 1`] = `
593+
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
594+
595+
<bold>Matcher error</>: <red>received</> value must be a number
596+
597+
Received has type: symbol
598+
Received has value: <red>Symbol(0.1)</>"
599+
`;
600+
601+
exports[`.toBeCloseTo() throws: Matcher error promise resolves isNot false received 1`] = `
602+
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>
603+
604+
<bold>Matcher error</>: <red>received</> value must be a number
605+
606+
Received has type: boolean
607+
Received has value: <red>false</>"
608+
`;
609+
610+
exports[`.toBeCloseTo() throws: Matcher error promise resolves isNot true expected 1`] = `
611+
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>
612+
613+
<bold>Matcher error</>: <green>expected</> value must be a number
614+
615+
Expected has value: <green>null</>"
616+
`;
617+
566618
exports[`.toBeDefined(), .toBeUndefined() '"a"' is defined 1`] = `
567619
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeDefined<dim>()</>
568620

packages/expect/src/__tests__/matchers.test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,59 @@ describe('.toBeCloseTo()', () => {
10061006
).toThrowErrorMatchingSnapshot();
10071007
});
10081008
});
1009+
1010+
describe('throws: Matcher error', () => {
1011+
test('promise empty isNot false received', () => {
1012+
const precision = 3;
1013+
const expected = 0;
1014+
const received = '';
1015+
expect(() => {
1016+
jestExpect(received).toBeCloseTo(expected, precision);
1017+
}).toThrowErrorMatchingSnapshot();
1018+
});
1019+
1020+
test('promise empty isNot true expected', () => {
1021+
const received = 0.1;
1022+
// expected is undefined
1023+
expect(() => {
1024+
jestExpect(received).not.toBeCloseTo();
1025+
}).toThrowErrorMatchingSnapshot();
1026+
});
1027+
1028+
test('promise rejects isNot false expected', () => {
1029+
const expected = '0';
1030+
const received = Promise.reject(0.01);
1031+
return expect(
1032+
jestExpect(received).rejects.toBeCloseTo(expected),
1033+
).rejects.toThrowErrorMatchingSnapshot();
1034+
});
1035+
1036+
test('promise rejects isNot true received', () => {
1037+
const expected = 0;
1038+
const received = Promise.reject(Symbol('0.1'));
1039+
return expect(
1040+
jestExpect(received).rejects.not.toBeCloseTo(expected),
1041+
).rejects.toThrowErrorMatchingSnapshot();
1042+
});
1043+
1044+
test('promise resolves isNot false received', () => {
1045+
const precision = 3;
1046+
const expected = 0;
1047+
const received = Promise.resolve(false);
1048+
return expect(
1049+
jestExpect(received).resolves.toBeCloseTo(expected, precision),
1050+
).rejects.toThrowErrorMatchingSnapshot();
1051+
});
1052+
1053+
test('promise resolves isNot true expected', () => {
1054+
const precision = 3;
1055+
const expected = null;
1056+
const received = Promise.resolve(0.1);
1057+
expect(
1058+
jestExpect(received).resolves.not.toBeCloseTo(expected, precision),
1059+
).rejects.toThrowErrorMatchingSnapshot();
1060+
});
1061+
});
10091062
});
10101063

10111064
describe('.toMatch()', () => {

packages/expect/src/matchers.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,12 @@ const matchers: MatchersObject = {
9393
precision: number = 2,
9494
) {
9595
const secondArgument = arguments.length === 3 ? 'precision' : undefined;
96-
const isNot = this.isNot;
9796
const options: MatcherHintOptions = {
98-
isNot,
97+
isNot: this.isNot,
9998
promise: this.promise,
10099
secondArgument,
101100
};
102-
ensureNumbers(received, expected, '.toBeCloseTo');
101+
ensureNumbers(received, expected, 'toBeCloseTo', options);
103102

104103
let pass = false;
105104
let expectedDiff = 0;
@@ -180,7 +179,7 @@ const matchers: MatchersObject = {
180179
isNot,
181180
promise: this.promise,
182181
};
183-
ensureNumbers(received, expected, '.toBeGreaterThan');
182+
ensureNumbers(received, expected, 'toBeGreaterThan', options);
184183

185184
const pass = received > expected;
186185

@@ -203,7 +202,7 @@ const matchers: MatchersObject = {
203202
isNot,
204203
promise: this.promise,
205204
};
206-
ensureNumbers(received, expected, '.toBeGreaterThanOrEqual');
205+
ensureNumbers(received, expected, 'toBeGreaterThanOrEqual', options);
207206

208207
const pass = received >= expected;
209208

@@ -266,7 +265,7 @@ const matchers: MatchersObject = {
266265
isNot,
267266
promise: this.promise,
268267
};
269-
ensureNumbers(received, expected, '.toBeLessThan');
268+
ensureNumbers(received, expected, 'toBeLessThan', options);
270269

271270
const pass = received < expected;
272271

@@ -285,7 +284,7 @@ const matchers: MatchersObject = {
285284
isNot,
286285
promise: this.promise,
287286
};
288-
ensureNumbers(received, expected, '.toBeLessThanOrEqual');
287+
ensureNumbers(received, expected, 'toBeLessThanOrEqual', options);
289288

290289
const pass = received <= expected;
291290

packages/jest-matcher-utils/src/__tests__/__snapshots__/index.test.ts.snap

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,76 @@ Expected has type: object
1818
Expected has value: <green>{\\"a\\": 1}</>"
1919
`;
2020
21-
exports[`.ensureNumbers() throws error when expected is not a number 1`] = `
22-
"<dim>expect(</><red>received</><dim>)[.not]This matcher(</><green>expected</><dim>)</>
21+
exports[`.ensureNumbers() throws error when expected is not a number (backward compatibility) 1`] = `
22+
"<dim>expect(</><red>received</><dim>)[.not].toBeCloseTo(</><green>expected</><dim>)</>
2323
2424
<bold>Matcher error</>: <green>expected</> value must be a number
2525
2626
Expected has type: string
2727
Expected has value: <green>\\"not_a_number\\"</>"
2828
`;
2929
30-
exports[`.ensureNumbers() throws error when received is not a number 1`] = `
31-
"<dim>expect(</><red>received</><dim>)[.not]This matcher(</><green>expected</><dim>)</>
30+
exports[`.ensureNumbers() throws error when received is not a number (backward compatibility) 1`] = `
31+
"<dim>expect(</><red>received</><dim>)[.not].toBeCloseTo(</><green>expected</><dim>)</>
3232
3333
<bold>Matcher error</>: <red>received</> value must be a number
3434
3535
Received has type: string
3636
Received has value: <red>\\"not_a_number\\"</>"
3737
`;
3838
39+
exports[`.ensureNumbers() with options promise empty isNot false received 1`] = `
40+
"<dim>expect(</><red>received</><dim>).</>toBeCloseTo<dim>(</><green>expected</><dim>, </><green>precision</><dim>)</>
41+
42+
<bold>Matcher error</>: <red>received</> value must be a number
43+
44+
Received has type: string
45+
Received has value: <red>\\"\\"</>"
46+
`;
47+
48+
exports[`.ensureNumbers() with options promise empty isNot true expected 1`] = `
49+
"<dim>expect(</><red>received</><dim>).</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
50+
51+
<bold>Matcher error</>: <green>expected</> value must be a number
52+
53+
Expected has value: <green>undefined</>"
54+
`;
55+
56+
exports[`.ensureNumbers() with options promise rejects isNot false expected 1`] = `
57+
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
58+
59+
<bold>Matcher error</>: <green>expected</> value must be a number
60+
61+
Expected has type: string
62+
Expected has value: <green>\\"0\\"</>"
63+
`;
64+
65+
exports[`.ensureNumbers() with options promise rejects isNot true received 1`] = `
66+
"<dim>expect(</><red>received</><dim>).</>rejects<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
67+
68+
<bold>Matcher error</>: <red>received</> value must be a number
69+
70+
Received has type: symbol
71+
Received has value: <red>Symbol(0.1)</>"
72+
`;
73+
74+
exports[`.ensureNumbers() with options promise resolves isNot false received 1`] = `
75+
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
76+
77+
<bold>Matcher error</>: <red>received</> value must be a number
78+
79+
Received has type: boolean
80+
Received has value: <red>false</>"
81+
`;
82+
83+
exports[`.ensureNumbers() with options promise resolves isNot true expected 1`] = `
84+
"<dim>expect(</><red>received</><dim>).</>resolves<dim>.</>not<dim>.</>toBeCloseTo<dim>(</><green>expected</><dim>)</>
85+
86+
<bold>Matcher error</>: <green>expected</> value must be a number
87+
88+
Expected has value: <green>null</>"
89+
`;
90+
3991
exports[`.stringify() reduces maxDepth if stringifying very large objects 1`] = `"{\\"a\\": 1, \\"b\\": [Object]}"`;
4092
4193
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\\"}}"`;

packages/jest-matcher-utils/src/__tests__/index.test.ts

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
getLabelPrinter,
1414
pluralize,
1515
stringify,
16+
MatcherHintOptions,
1617
} from '../';
1718

1819
describe('.stringify()', () => {
@@ -98,19 +99,90 @@ describe('.ensureNumbers()', () => {
9899
}).not.toThrow();
99100
});
100101

101-
test('throws error when expected is not a number', () => {
102+
test('throws error when expected is not a number (backward compatibility)', () => {
102103
expect(() => {
103104
// @ts-ignore
104-
ensureNumbers(1, 'not_a_number');
105+
ensureNumbers(1, 'not_a_number', '.toBeCloseTo');
105106
}).toThrowErrorMatchingSnapshot();
106107
});
107108

108-
test('throws error when received is not a number', () => {
109+
test('throws error when received is not a number (backward compatibility)', () => {
109110
expect(() => {
110111
// @ts-ignore
111-
ensureNumbers('not_a_number', 3);
112+
ensureNumbers('not_a_number', 3, '.toBeCloseTo');
112113
}).toThrowErrorMatchingSnapshot();
113114
});
115+
116+
describe('with options', () => {
117+
const matcherName = 'toBeCloseTo';
118+
119+
test('promise empty isNot false received', () => {
120+
const options: MatcherHintOptions = {
121+
isNot: false,
122+
promise: '',
123+
secondArgument: 'precision',
124+
};
125+
expect(() => {
126+
// @ts-ignore
127+
ensureNumbers('', 0, matcherName, options);
128+
}).toThrowErrorMatchingSnapshot();
129+
});
130+
131+
test('promise empty isNot true expected', () => {
132+
const options: MatcherHintOptions = {
133+
isNot: true,
134+
// promise undefined is equivalent to empty string
135+
};
136+
expect(() => {
137+
// @ts-ignore
138+
ensureNumbers(0.1, undefined, matcherName, options);
139+
}).toThrowErrorMatchingSnapshot();
140+
});
141+
142+
test('promise rejects isNot false expected', () => {
143+
const options: MatcherHintOptions = {
144+
isNot: false,
145+
promise: 'rejects',
146+
};
147+
expect(() => {
148+
// @ts-ignore
149+
ensureNumbers(0.01, '0', matcherName, options);
150+
}).toThrowErrorMatchingSnapshot();
151+
});
152+
153+
test('promise rejects isNot true received', () => {
154+
const options: MatcherHintOptions = {
155+
isNot: true,
156+
promise: 'rejects',
157+
};
158+
expect(() => {
159+
// @ts-ignore
160+
ensureNumbers(Symbol('0.1'), 0, matcherName, options);
161+
}).toThrowErrorMatchingSnapshot();
162+
});
163+
164+
test('promise resolves isNot false received', () => {
165+
const options: MatcherHintOptions = {
166+
isNot: false,
167+
promise: 'resolves',
168+
};
169+
expect(() => {
170+
// @ts-ignore
171+
ensureNumbers(false, 0, matcherName, options);
172+
}).toThrowErrorMatchingSnapshot();
173+
});
174+
175+
test('promise resolves isNot true expected', () => {
176+
const options: MatcherHintOptions = {
177+
isNot: true,
178+
promise: 'resolves',
179+
};
180+
expect(() => {
181+
// @ts-ignore
182+
ensureNumbers(0.1, null, matcherName, options);
183+
}).toThrowErrorMatchingSnapshot();
184+
});
185+
});
114186
});
115187

116188
describe('.ensureNoExpected()', () => {

0 commit comments

Comments
 (0)