Skip to content

Commit 48b11fb

Browse files
microcoodgnapse
authored andcommitted
fix: improved error messages (#15)
1 parent 6f28c1c commit 48b11fb

File tree

10 files changed

+280
-61
lines changed

10 files changed

+280
-61
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"css": "^2.2.3",
3737
"jest-diff": "^22.4.3",
3838
"jest-matcher-utils": "^22.4.3",
39+
"pretty-format": "^23.0.1",
3940
"redent": "^2.0.0"
4041
},
4142
"devDependencies": {
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`.toBeInTheDOM 1`] = `
4+
"<dim>expect(</><red>element</><dim>).not.toBeInTheDOM(</><dim>)</>
5+
6+
Received:
7+
<red><span data-testid=\\"count-value\\" /></>"
8+
`;
9+
10+
exports[`.toBeInTheDOM 2`] = `
11+
"<dim>expect(</><red>element</><dim>).toBeInTheDOM(</><dim>)</>
12+
13+
Received:
14+
<red>null</>"
15+
`;
16+
17+
exports[`.toBeInTheDOM 3`] = `
18+
"<dim>expect(</><red>received</><dim>).toBeInTheDOM(</><dim>)</>
19+
20+
<red>received</> value must be an HTMLElement.
21+
Received:
22+
object: <red>{\\"thisIsNot\\": \\"an html element\\"}</>"
23+
`;
24+
25+
exports[`.toBeVisible 1`] = `
26+
"<dim>expect(</><red>element</><dim>).not.toBeVisible(</><dim>)</>
27+
28+
Received element is visible:
29+
<red><header /></>"
30+
`;
31+
32+
exports[`.toBeVisible 2`] = `
33+
"<dim>expect(</><red>element</><dim>).toBeVisible(</><dim>)</>
34+
35+
Received element is not visible:
36+
<red><p /></>"
37+
`;
38+
39+
exports[`.toHaveAttribute 1`] = `
40+
"<dim>expect(</><red>element</><dim>).not.toHaveAttribute(</><green><green>\\"disabled\\"<green></><dim>) // element.hasAttribute(\\"disabled\\")</>
41+
42+
Expected the element not to have attribute:
43+
<green> disabled</>
44+
Received:
45+
<red> disabled=\\"\\"</>"
46+
`;
47+
48+
exports[`.toHaveAttribute 2`] = `
49+
"<dim>expect(</><red>element</><dim>).not.toHaveAttribute(</><green><green>\\"type\\"<green></><dim>) // element.hasAttribute(\\"type\\")</>
50+
51+
Expected the element not to have attribute:
52+
<green> type</>
53+
Received:
54+
<red> type=\\"submit\\"</>"
55+
`;
56+
57+
exports[`.toHaveAttribute 3`] = `
58+
"<dim>expect(</><red>element</><dim>).toHaveAttribute(</><green><green>\\"class\\"<green></><dim>) // element.hasAttribute(\\"class\\")</>
59+
60+
Expected the element to have attribute:
61+
<green> class</>
62+
Received:
63+
<red> null</>"
64+
`;
65+
66+
exports[`.toHaveAttribute 4`] = `
67+
"<dim>expect(</><red>element</><dim>).not.toHaveAttribute(</><green><green>\\"type\\"<green></><dim>, </><green><green>\\"submit\\"<green></><dim>) // element.getAttribute(\\"type\\") === \\"submit\\"</>
68+
69+
Expected the element not to have attribute:
70+
<green> type=\\"submit\\"</>
71+
Received:
72+
<red> type=\\"submit\\"</>"
73+
`;
74+
75+
exports[`.toHaveAttribute 5`] = `
76+
"<dim>expect(</><red>element</><dim>).toHaveAttribute(</><green><green>\\"type\\"<green></><dim>, </><green><green>\\"button\\"<green></><dim>) // element.getAttribute(\\"type\\") === \\"button\\"</>
77+
78+
Expected the element to have attribute:
79+
<green> type=\\"button\\"</>
80+
Received:
81+
<red> type=\\"submit\\"</>"
82+
`;
83+
84+
exports[`.toHaveAttribute 6`] = `
85+
"<dim>expect(</><red>received</><dim>).not.toHaveAttribute(</><dim>)</>
86+
87+
<red>received</> value must be an HTMLElement.
88+
Received:
89+
object: <red>{\\"thisIsNot\\": \\"an html element\\"}</>"
90+
`;
91+
92+
exports[`.toHaveClass 1`] = `
93+
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"btn\\"<green></><dim>)</>
94+
95+
Expected the element not to have class:
96+
<green> btn</>
97+
Received:
98+
<red> btn extra btn-danger</>"
99+
`;
100+
101+
exports[`.toHaveClass 2`] = `
102+
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"btn-danger\\"<green></><dim>)</>
103+
104+
Expected the element not to have class:
105+
<green> btn-danger</>
106+
Received:
107+
<red> btn extra btn-danger</>"
108+
`;
109+
110+
exports[`.toHaveClass 3`] = `
111+
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"extra\\"<green></><dim>)</>
112+
113+
Expected the element not to have class:
114+
<green> extra</>
115+
Received:
116+
<red> btn extra btn-danger</>"
117+
`;
118+
119+
exports[`.toHaveClass 4`] = `
120+
"<dim>expect(</><red>element</><dim>).toHaveClass(</><green><green>\\"xtra\\"<green></><dim>)</>
121+
122+
Expected the element to have class:
123+
<green> xtra</>
124+
Received:
125+
<red> btn extra btn-danger</>"
126+
`;
127+
128+
exports[`.toHaveClass 5`] = `
129+
"<dim>expect(</><red>element</><dim>).not.toHaveClass(</><green><green>\\"btn btn-danger\\"<green></><dim>)</>
130+
131+
Expected the element not to have class:
132+
<green> btn btn-danger</>
133+
Received:
134+
<red> btn extra btn-danger</>"
135+
`;
136+
137+
exports[`.toHaveClass 6`] = `
138+
"<dim>expect(</><red>element</><dim>).toHaveClass(</><green><green>\\"btn-link\\"<green></><dim>)</>
139+
140+
Expected the element to have class:
141+
<green> btn-link</>
142+
Received:
143+
<red> btn extra btn-danger</>"
144+
`;
145+
146+
exports[`.toHaveClass 7`] = `
147+
"<dim>expect(</><red>element</><dim>).toHaveClass(</><green><green>\\"btn-danger\\"<green></><dim>)</>
148+
149+
Expected the element to have class:
150+
<green> btn-danger</>
151+
Received:
152+
"
153+
`;
154+
155+
exports[`.toHaveStyle 1`] = `
156+
"<dim>expect(</><red>element</><dim>).toHaveStyle(</><dim>)</>
157+
158+
<green>- Expected</>
159+
160+
<green>- font-weight: bold;</>
161+
<dim> </>
162+
<red>+ </>"
163+
`;
164+
165+
exports[`.toHaveStyle 2`] = `
166+
"<dim>expect(</><red>element</><dim>).not.toHaveStyle(</><dim>)</>
167+
168+
<dim>Compared values have no visual difference.</>"
169+
`;
170+
171+
exports[`.toHaveStyle 3`] = `"Syntax error parsing expected css: property missing ':' in 1:24"`;
172+
173+
exports[`.toHaveStyle 4`] = `"Syntax error parsing expected css: property missing ':' in 1:18"`;
174+
175+
exports[`.toHaveTextContent 1`] = `
176+
"<dim>expect(</><red>received</><dim>).toHaveTextContent(</><dim>)</>
177+
178+
<red>received</> value must be an HTMLElement.
179+
Received: <red>null</>"
180+
`;
181+
182+
exports[`.toHaveTextContent 2`] = `
183+
"<dim>expect(</><red>element</><dim>).toHaveTextContent(</><dim>)</>
184+
185+
Expected element to have text content:
186+
<green> 3</>
187+
Received:
188+
<red> 2</>"
189+
`;
190+
191+
exports[`.toHaveTextContent 3`] = `
192+
"<dim>expect(</><red>element</><dim>).not.toHaveTextContent(</><dim>)</>
193+
194+
Expected element not to have text content:
195+
<green> 2</>
196+
Received:
197+
<red> 2</>"
198+
`;

src/__tests__/index.js

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import '../extend-expect'
2+
import {plugins} from 'pretty-format'
23
import {render} from './helpers/test-utils'
34

5+
expect.addSnapshotSerializer(plugins.ConvertAnsi)
6+
47
test('.toBeInTheDOM', () => {
58
const {queryByTestId} = render(`<span data-testid="count-value">2</span>`)
69

@@ -10,13 +13,13 @@ test('.toBeInTheDOM', () => {
1013
// negative test cases wrapped in throwError assertions for coverage.
1114
expect(() =>
1215
expect(queryByTestId('count-value')).not.toBeInTheDOM(),
13-
).toThrowError()
16+
).toThrowErrorMatchingSnapshot()
1417
expect(() =>
1518
expect(queryByTestId('count-value1')).toBeInTheDOM(),
16-
).toThrowError()
19+
).toThrowErrorMatchingSnapshot()
1720
expect(() =>
1821
expect({thisIsNot: 'an html element'}).toBeInTheDOM(),
19-
).toThrowError()
22+
).toThrowErrorMatchingSnapshot()
2023
})
2124

2225
test('.toHaveTextContent', () => {
@@ -27,14 +30,14 @@ test('.toHaveTextContent', () => {
2730
expect(queryByTestId('count-value')).not.toHaveTextContent('21')
2831
expect(() =>
2932
expect(queryByTestId('count-value2')).toHaveTextContent('2'),
30-
).toThrowError()
33+
).toThrowErrorMatchingSnapshot()
3134

3235
expect(() =>
3336
expect(queryByTestId('count-value')).toHaveTextContent('3'),
34-
).toThrowError()
37+
).toThrowErrorMatchingSnapshot()
3538
expect(() =>
3639
expect(queryByTestId('count-value')).not.toHaveTextContent('2'),
37-
).toThrowError()
40+
).toThrowErrorMatchingSnapshot()
3841
})
3942

4043
test('.toHaveAttribute', () => {
@@ -52,19 +55,22 @@ test('.toHaveAttribute', () => {
5255

5356
expect(() =>
5457
expect(queryByTestId('ok-button')).not.toHaveAttribute('disabled'),
55-
).toThrowError()
58+
).toThrowErrorMatchingSnapshot()
5659
expect(() =>
5760
expect(queryByTestId('ok-button')).not.toHaveAttribute('type'),
58-
).toThrowError()
61+
).toThrowErrorMatchingSnapshot()
5962
expect(() =>
6063
expect(queryByTestId('ok-button')).toHaveAttribute('class'),
61-
).toThrowError()
64+
).toThrowErrorMatchingSnapshot()
6265
expect(() =>
6366
expect(queryByTestId('ok-button')).not.toHaveAttribute('type', 'submit'),
64-
).toThrowError()
67+
).toThrowErrorMatchingSnapshot()
6568
expect(() =>
6669
expect(queryByTestId('ok-button')).toHaveAttribute('type', 'button'),
67-
).toThrowError()
70+
).toThrowErrorMatchingSnapshot()
71+
expect(() =>
72+
expect({thisIsNot: 'an html element'}).not.toHaveAttribute(),
73+
).toThrowErrorMatchingSnapshot()
6874
})
6975

7076
test('.toHaveClass', () => {
@@ -89,25 +95,25 @@ test('.toHaveClass', () => {
8995

9096
expect(() =>
9197
expect(queryByTestId('delete-button')).not.toHaveClass('btn'),
92-
).toThrowError()
98+
).toThrowErrorMatchingSnapshot()
9399
expect(() =>
94100
expect(queryByTestId('delete-button')).not.toHaveClass('btn-danger'),
95-
).toThrowError()
101+
).toThrowErrorMatchingSnapshot()
96102
expect(() =>
97103
expect(queryByTestId('delete-button')).not.toHaveClass('extra'),
98-
).toThrowError()
104+
).toThrowErrorMatchingSnapshot()
99105
expect(() =>
100106
expect(queryByTestId('delete-button')).toHaveClass('xtra'),
101-
).toThrowError()
107+
).toThrowErrorMatchingSnapshot()
102108
expect(() =>
103109
expect(queryByTestId('delete-button')).not.toHaveClass('btn btn-danger'),
104-
).toThrowError()
110+
).toThrowErrorMatchingSnapshot()
105111
expect(() =>
106112
expect(queryByTestId('delete-button')).toHaveClass('btn-link'),
107-
).toThrowError()
113+
).toThrowErrorMatchingSnapshot()
108114
expect(() =>
109115
expect(queryByTestId('cancel-button')).toHaveClass('btn-danger'),
110-
).toThrowError()
116+
).toThrowErrorMatchingSnapshot()
111117
})
112118

113119
test('.toHaveStyle', () => {
@@ -149,20 +155,20 @@ test('.toHaveStyle', () => {
149155

150156
expect(() =>
151157
expect(container.querySelector('.label')).toHaveStyle('font-weight: bold'),
152-
).toThrowError()
158+
).toThrowErrorMatchingSnapshot()
153159
expect(() =>
154160
expect(container.querySelector('.label')).not.toHaveStyle('color: white'),
155-
).toThrowError()
161+
).toThrowErrorMatchingSnapshot()
156162

157163
// Make sure the test fails if the css syntax is not valid
158164
expect(() =>
159165
expect(container.querySelector('.label')).not.toHaveStyle(
160166
'font-weight bold',
161167
),
162-
).toThrowError()
168+
).toThrowErrorMatchingSnapshot()
163169
expect(() =>
164170
expect(container.querySelector('.label')).toHaveStyle('color white'),
165-
).toThrowError()
171+
).toThrowErrorMatchingSnapshot()
166172

167173
document.body.removeChild(style)
168174
document.body.removeChild(container)
@@ -194,8 +200,8 @@ test('.toBeVisible', () => {
194200

195201
expect(() =>
196202
expect(container.querySelector('header')).not.toBeVisible(),
197-
).toThrowError()
203+
).toThrowErrorMatchingSnapshot()
198204
expect(() =>
199205
expect(container.querySelector('p')).toBeVisible(),
200-
).toThrowError()
206+
).toThrowErrorMatchingSnapshot()
201207
})

src/to-be-in-the-dom.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1-
import {matcherHint} from 'jest-matcher-utils'
2-
import {checkHtmlElement, getMessage} from './utils'
1+
import {matcherHint, printReceived} from 'jest-matcher-utils'
2+
import {checkHtmlElement} from './utils'
33

44
export function toBeInTheDOM(received) {
55
if (received) {
6-
checkHtmlElement(received)
6+
checkHtmlElement(received, toBeInTheDOM, this)
77
}
88
return {
99
pass: !!received,
1010
message: () => {
11-
const to = this.isNot ? 'not to' : 'to'
12-
return getMessage(
11+
return [
1312
matcherHint(`${this.isNot ? '.not' : ''}.toBeInTheDOM`, 'element', ''),
14-
'Expected',
15-
`element ${to} be present`,
16-
'Received',
17-
received,
18-
)
13+
'',
14+
'Received:',
15+
` ${printReceived(received ? received.cloneNode(false) : received)}`,
16+
].join('\n')
1917
},
2018
}
2119
}

0 commit comments

Comments
 (0)