Skip to content

Commit dd6d4c6

Browse files
jgozKent C. Dodds
authored andcommitted
fix: allow SVGElements in matchers (#29)
* Allow SVGElements in expect() matchers Fixes #28 * Add jgoz as contributor
1 parent 1812d58 commit dd6d4c6

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

.all-contributorsrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@
158158
"doc",
159159
"test"
160160
]
161+
},
162+
{
163+
"login": "jgoz",
164+
"name": "John Gozde",
165+
"avatar_url": "https://avatars2.githubusercontent.com/u/132233?v=4",
166+
"profile": "https://github.com/jgoz",
167+
"contributions": [
168+
"bug",
169+
"code"
170+
]
161171
}
162172
]
163173
}

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
[![downloads][downloads-badge]][npmtrends]
1717
[![MIT License][license-badge]][license]
1818

19-
[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors)
19+
[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors)
2020
[![PRs Welcome][prs-badge]][prs]
2121
[![Code of Conduct][coc-badge]][coc]
2222

@@ -46,6 +46,7 @@ to maintain.
4646
- [Usage](#usage)
4747
- [Custom matchers](#custom-matchers)
4848
- [`toBeInTheDOM`](#tobeinthedom)
49+
- [`toBeEmpty`](#tobeempty)
4950
- [`toContainElement`](#tocontainelement)
5051
- [`toHaveTextContent`](#tohavetextcontent)
5152
- [`toHaveAttribute`](#tohaveattribute)
@@ -318,7 +319,7 @@ Thanks goes to these people ([emoji key][emojis]):
318319
| [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub><b>Kent C. Dodds</b></sub>](https://kentcdodds.com)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=kentcdodds "Code") [📖](https://github.com/gnapse/jest-dom/commits?author=kentcdodds "Documentation") [🚇](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/gnapse/jest-dom/commits?author=kentcdodds "Tests") | [<img src="https://avatars1.githubusercontent.com/u/2430381?v=4" width="100px;"/><br /><sub><b>Ryan Castner</b></sub>](http://audiolion.github.io)<br />[📖](https://github.com/gnapse/jest-dom/commits?author=audiolion "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/8008023?v=4" width="100px;"/><br /><sub><b>Daniel Sandiego</b></sub>](https://www.dnlsandiego.com)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=dnlsandiego "Code") | [<img src="https://avatars2.githubusercontent.com/u/12592677?v=4" width="100px;"/><br /><sub><b>Paweł Mikołajczyk</b></sub>](https://github.com/Miklet)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=Miklet "Code") | [<img src="https://avatars3.githubusercontent.com/u/464978?v=4" width="100px;"/><br /><sub><b>Alejandro Ñáñez Ortiz</b></sub>](http://co.linkedin.com/in/alejandronanez/)<br />[📖](https://github.com/gnapse/jest-dom/commits?author=alejandronanez "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/1402095?v=4" width="100px;"/><br /><sub><b>Matt Parrish</b></sub>](https://github.com/pbomb)<br />[🐛](https://github.com/gnapse/jest-dom/issues?q=author%3Apbomb "Bug reports") [💻](https://github.com/gnapse/jest-dom/commits?author=pbomb "Code") [📖](https://github.com/gnapse/jest-dom/commits?author=pbomb "Documentation") [⚠️](https://github.com/gnapse/jest-dom/commits?author=pbomb "Tests") | [<img src="https://avatars1.githubusercontent.com/u/1288694?v=4" width="100px;"/><br /><sub><b>Justin Hall</b></sub>](https://github.com/wKovacs64)<br />[📦](#platform-wKovacs64 "Packaging/porting to new platform") |
319320
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
320321
| [<img src="https://avatars1.githubusercontent.com/u/1241511?s=460&v=4" width="100px;"/><br /><sub><b>Anto Aravinth</b></sub>](https://github.com/antoaravinth)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=antoaravinth "Code") [⚠️](https://github.com/gnapse/jest-dom/commits?author=antoaravinth "Tests") [📖](https://github.com/gnapse/jest-dom/commits?author=antoaravinth "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/3462296?v=4" width="100px;"/><br /><sub><b>Jonah Moses</b></sub>](https://github.com/JonahMoses)<br />[📖](https://github.com/gnapse/jest-dom/commits?author=JonahMoses "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/4002543?v=4" width="100px;"/><br /><sub><b>Łukasz Gandecki</b></sub>](http://team.thebrain.pro)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=lgandecki "Code") [⚠️](https://github.com/gnapse/jest-dom/commits?author=lgandecki "Tests") [📖](https://github.com/gnapse/jest-dom/commits?author=lgandecki "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/498274?v=4" width="100px;"/><br /><sub><b>Ivan Babak</b></sub>](https://sompylasar.github.io)<br />[🐛](https://github.com/gnapse/jest-dom/issues?q=author%3Asompylasar "Bug reports") [🤔](#ideas-sompylasar "Ideas, Planning, & Feedback") | [<img src="https://avatars3.githubusercontent.com/u/4439618?v=4" width="100px;"/><br /><sub><b>Jesse Day</b></sub>](https://github.com/jday3)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=jday3 "Code") | [<img src="https://avatars0.githubusercontent.com/u/15199?v=4" width="100px;"/><br /><sub><b>Ernesto García</b></sub>](http://gnapse.github.io)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=gnapse "Code") [📖](https://github.com/gnapse/jest-dom/commits?author=gnapse "Documentation") [⚠️](https://github.com/gnapse/jest-dom/commits?author=gnapse "Tests") | [<img src="https://avatars0.githubusercontent.com/u/79312?v=4" width="100px;"/><br /><sub><b>Mark Volkmann</b></sub>](http://ociweb.com/mark/)<br />[🐛](https://github.com/gnapse/jest-dom/issues?q=author%3Amvolkmann "Bug reports") [💻](https://github.com/gnapse/jest-dom/commits?author=mvolkmann "Code") |
321-
| [<img src="https://avatars1.githubusercontent.com/u/1659099?v=4" width="100px;"/><br /><sub><b>smacpherson64</b></sub>](https://github.com/smacpherson64)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=smacpherson64 "Code") [📖](https://github.com/gnapse/jest-dom/commits?author=smacpherson64 "Documentation") [⚠️](https://github.com/gnapse/jest-dom/commits?author=smacpherson64 "Tests") |
322+
| [<img src="https://avatars1.githubusercontent.com/u/1659099?v=4" width="100px;"/><br /><sub><b>smacpherson64</b></sub>](https://github.com/smacpherson64)<br />[💻](https://github.com/gnapse/jest-dom/commits?author=smacpherson64 "Code") [📖](https://github.com/gnapse/jest-dom/commits?author=smacpherson64 "Documentation") [⚠️](https://github.com/gnapse/jest-dom/commits?author=smacpherson64 "Tests") | [<img src="https://avatars2.githubusercontent.com/u/132233?v=4" width="100px;"/><br /><sub><b>John Gozde</b></sub>](https://github.com/jgoz)<br />[🐛](https://github.com/gnapse/jest-dom/issues?q=author%3Ajgoz "Bug reports") [💻](https://github.com/gnapse/jest-dom/commits?author=jgoz "Code") |
322323

323324
<!-- ALL-CONTRIBUTORS-LIST:END -->
324325

src/__tests__/index.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,42 @@ test('.toBeInTheDOM', () => {
88
const {queryByTestId} = render(`
99
<span data-testid="count-container">
1010
<span data-testid="count-value"></span>
11+
<svg data-testid="svg-element"></svg>
1112
</span>`)
1213

1314
const containerElement = queryByTestId('count-container')
1415
const valueElement = queryByTestId('count-value')
1516
const nonExistantElement = queryByTestId('not-exists')
17+
const svgElement = queryByTestId('svg-element')
1618
const fakeElement = {thisIsNot: 'an html element'}
1719

1820
// Testing toBeInTheDOM without container
1921
expect(valueElement).toBeInTheDOM()
22+
expect(svgElement).toBeInTheDOM()
2023
expect(nonExistantElement).not.toBeInTheDOM()
2124

2225
// negative test cases wrapped in throwError assertions for coverage.
2326
expect(() => expect(valueElement).not.toBeInTheDOM()).toThrowError()
2427

28+
expect(() => expect(svgElement).not.toBeInTheDOM()).toThrowError()
29+
2530
expect(() => expect(nonExistantElement).toBeInTheDOM()).toThrowError()
2631

2732
expect(() => expect(fakeElement).toBeInTheDOM()).toThrowError()
2833

2934
// Testing toBeInTheDOM with container
3035
expect(valueElement).toBeInTheDOM(containerElement)
36+
expect(svgElement).toBeInTheDOM(containerElement)
3137
expect(containerElement).not.toBeInTheDOM(valueElement)
3238

3339
expect(() =>
3440
expect(valueElement).not.toBeInTheDOM(containerElement),
3541
).toThrowError()
3642

43+
expect(() =>
44+
expect(svgElement).not.toBeInTheDOM(containerElement),
45+
).toThrowError()
46+
3747
expect(() =>
3848
expect(nonExistantElement).toBeInTheDOM(containerElement),
3949
).toThrowError()
@@ -53,21 +63,26 @@ test('.toContainElement', () => {
5363
<span data-testid="parent">
5464
<span data-testid="child"></span>
5565
</span>
66+
<svg data-testid="svg-element"></svg>
5667
</span>
5768
`)
5869

5970
const grandparent = queryByTestId('grandparent')
6071
const parent = queryByTestId('parent')
6172
const child = queryByTestId('child')
73+
const svgElement = queryByTestId('svg-element')
6274
const nonExistantElement = queryByTestId('not-exists')
6375
const fakeElement = {thisIsNot: 'an html element'}
6476

6577
expect(grandparent).toContainElement(parent)
6678
expect(grandparent).toContainElement(child)
79+
expect(grandparent).toContainElement(svgElement)
6780
expect(parent).toContainElement(child)
6881
expect(parent).not.toContainElement(grandparent)
82+
expect(parent).not.toContainElement(svgElement)
6983
expect(child).not.toContainElement(parent)
7084
expect(child).not.toContainElement(grandparent)
85+
expect(child).not.toContainElement(svgElement)
7186

7287
// negative test cases wrapped in throwError assertions for coverage.
7388
expect(() =>
@@ -96,25 +111,33 @@ test('.toContainElement', () => {
96111
expect(() => expect(grandparent).toContainElement(fakeElement)).toThrowError()
97112
expect(() => expect(fakeElement).toContainElement(fakeElement)).toThrowError()
98113
expect(() => expect(grandparent).not.toContainElement(child)).toThrowError()
114+
expect(() =>
115+
expect(grandparent).not.toContainElement(svgElement),
116+
).toThrowError()
99117
})
100118

101119
test('.toBeEmpty', () => {
102120
const {queryByTestId} = render(`
103121
<span data-testid="not-empty">
104122
<span data-testid="empty"></span>
123+
<svg data-testid="svg-empty"></svg>
105124
</span>`)
106125

107126
const empty = queryByTestId('empty')
108127
const notEmpty = queryByTestId('not-empty')
128+
const svgEmpty = queryByTestId('svg-empty')
109129
const nonExistantElement = queryByTestId('not-exists')
110130
const fakeElement = {thisIsNot: 'an html element'}
111131

112132
expect(empty).toBeEmpty()
133+
expect(svgEmpty).toBeEmpty()
113134
expect(notEmpty).not.toBeEmpty()
114135

115136
// negative test cases wrapped in throwError assertions for coverage.
116137
expect(() => expect(empty).not.toBeEmpty()).toThrowError()
117138

139+
expect(() => expect(svgEmpty).not.toBeEmpty()).toThrowError()
140+
118141
expect(() => expect(notEmpty).toBeEmpty()).toThrowError()
119142

120143
expect(() => expect(fakeElement).toBeEmpty()).toThrowError()
@@ -148,13 +171,17 @@ test('.toHaveAttribute', () => {
148171
<button data-testid="ok-button" type="submit" disabled>
149172
OK
150173
</button>
174+
<svg data-testid="svg-element" width="12"></svg>
151175
`)
152176

153177
expect(queryByTestId('ok-button')).toHaveAttribute('disabled')
154178
expect(queryByTestId('ok-button')).toHaveAttribute('type')
155179
expect(queryByTestId('ok-button')).not.toHaveAttribute('class')
156180
expect(queryByTestId('ok-button')).toHaveAttribute('type', 'submit')
157181
expect(queryByTestId('ok-button')).not.toHaveAttribute('type', 'button')
182+
expect(queryByTestId('svg-element')).toHaveAttribute('width')
183+
expect(queryByTestId('svg-element')).toHaveAttribute('width', '12')
184+
expect(queryByTestId('ok-button')).not.toHaveAttribute('height')
158185

159186
expect(() =>
160187
expect(queryByTestId('ok-button')).not.toHaveAttribute('disabled'),
@@ -171,6 +198,12 @@ test('.toHaveAttribute', () => {
171198
expect(() =>
172199
expect(queryByTestId('ok-button')).toHaveAttribute('type', 'button'),
173200
).toThrowError()
201+
expect(() =>
202+
expect(queryByTestId('svg-element')).not.toHaveAttribute('width'),
203+
).toThrowError()
204+
expect(() =>
205+
expect(queryByTestId('svg-element')).not.toHaveAttribute('width', '12'),
206+
).toThrowError()
174207
expect(() =>
175208
expect({thisIsNot: 'an html element'}).not.toHaveAttribute(),
176209
).toThrowError()
@@ -185,6 +218,9 @@ test('.toHaveClass', () => {
185218
<button data-testid="cancel-button">
186219
Cancel
187220
</button>
221+
<svg data-testid="svg-spinner" class="spinner clockwise">
222+
<path />
223+
</svg>
188224
</div>
189225
`)
190226

@@ -195,6 +231,9 @@ test('.toHaveClass', () => {
195231
expect(queryByTestId('delete-button')).toHaveClass('btn btn-danger')
196232
expect(queryByTestId('delete-button')).not.toHaveClass('btn-link')
197233
expect(queryByTestId('cancel-button')).not.toHaveClass('btn-danger')
234+
expect(queryByTestId('svg-spinner')).toHaveClass('spinner')
235+
expect(queryByTestId('svg-spinner')).toHaveClass('clockwise')
236+
expect(queryByTestId('svg-spinner')).not.toHaveClass('wise')
198237

199238
expect(() =>
200239
expect(queryByTestId('delete-button')).not.toHaveClass('btn'),
@@ -217,6 +256,12 @@ test('.toHaveClass', () => {
217256
expect(() =>
218257
expect(queryByTestId('cancel-button')).toHaveClass('btn-danger'),
219258
).toThrowError()
259+
expect(() =>
260+
expect(queryByTestId('svg-spinner')).not.toHaveClass('spinner'),
261+
).toThrowError()
262+
expect(() =>
263+
expect(queryByTestId('svg-spinner')).toHaveClass('wise'),
264+
).toThrowError()
220265
})
221266

222267
test('.toHaveStyle', () => {

src/utils.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,19 @@ class HtmlElementTypeError extends Error {
2323
'',
2424
),
2525
'',
26-
`${receivedColor('received')} value must be an HTMLElement.`,
26+
`${receivedColor(
27+
'received',
28+
)} value must be an HTMLElement or an SVGElement.`,
2729
printWithType('Received', received, printReceived),
2830
].join('\n')
2931
}
3032
}
3133

3234
function checkHtmlElement(htmlElement, ...args) {
33-
if (!(htmlElement instanceof HTMLElement)) {
35+
if (
36+
!(htmlElement instanceof HTMLElement) &&
37+
!(htmlElement instanceof SVGElement)
38+
) {
3439
throw new HtmlElementTypeError(htmlElement, ...args)
3540
}
3641
}

0 commit comments

Comments
 (0)