Skip to content

Commit f62628e

Browse files
revathskumargnapse
authored andcommitted
feat(toHaveAttribute): support asymetric matchers for value (#93)
Fixes #91
1 parent 3f85527 commit f62628e

File tree

6 files changed

+58
-7
lines changed

6 files changed

+58
-7
lines changed

.all-contributorsrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,15 @@
238238
"bug",
239239
"code"
240240
]
241+
},
242+
{
243+
"login": "revathskumar",
244+
"name": "Revath S Kumar",
245+
"avatar_url": "https://avatars3.githubusercontent.com/u/463904?v=4",
246+
"profile": "https://blog.revathskumar.com",
247+
"contributions": [
248+
"code"
249+
]
241250
}
242251
]
243252
}

README.md

Lines changed: 7 additions & 5 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-23-orange.svg?style=flat-square)](#contributors)
19+
[![All Contributors](https://img.shields.io/badge/all_contributors-24-orange.svg?style=flat-square)](#contributors)
2020
[![PRs Welcome][prs-badge]][prs]
2121
[![Code of Conduct][coc-badge]][coc]
2222

@@ -381,11 +381,11 @@ expect(getByTestId(container, 'parent')).toContainHTML(
381381
### `toHaveAttribute`
382382
383383
```typescript
384-
toHaveAttribute(attr: string, value?: string)
384+
toHaveAttribute(attr: string, value?: any)
385385
```
386386
387387
This allows you to check whether the given element has an attribute or not. You
388-
can also optionally check that the attribute has a specific expected value.
388+
can also optionally check that the attribute has a specific expected value or partial match using [expect.stringContaining](https://jestjs.io/docs/en/expect.html#expectnotstringcontainingstring)/[expect.stringMatching](https://jestjs.io/docs/en/expect.html#expectstringmatchingstring-regexp)
389389
390390
#### Examples
391391
@@ -411,6 +411,9 @@ const button = getByTestId(container, 'ok-button')
411411
expect(button).toHaveAttribute('disabled')
412412
expect(button).toHaveAttribute('type', 'submit')
413413
expect(button).not.toHaveAttribute('type', 'button')
414+
415+
expect(button).toHaveAttribute('type', expect.stringContaining('sub'))
416+
expect(button).toHaveAttribute('type', expect.not.stringContaining('but'))
414417
```
415418
416419
<hr />
@@ -760,8 +763,7 @@ Thanks goes to these people ([emoji key][emojis]):
760763
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
761764
| [<img src="https://avatars1.githubusercontent.com/u/1241511?s=460&v=4" width="100px;" alt="Anto Aravinth"/><br /><sub><b>Anto Aravinth</b></sub>](https://github.com/antoaravinth)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=antoaravinth "Code") [⚠️](https://github.com/testing-library/jest-dom/commits?author=antoaravinth "Tests") [📖](https://github.com/testing-library/jest-dom/commits?author=antoaravinth "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/3462296?v=4" width="100px;" alt="Jonah Moses"/><br /><sub><b>Jonah Moses</b></sub>](https://github.com/JonahMoses)<br />[📖](https://github.com/testing-library/jest-dom/commits?author=JonahMoses "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/4002543?v=4" width="100px;" alt="Łukasz Gandecki"/><br /><sub><b>Łukasz Gandecki</b></sub>](http://team.thebrain.pro)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=lgandecki "Code") [⚠️](https://github.com/testing-library/jest-dom/commits?author=lgandecki "Tests") [📖](https://github.com/testing-library/jest-dom/commits?author=lgandecki "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/498274?v=4" width="100px;" alt="Ivan Babak"/><br /><sub><b>Ivan Babak</b></sub>](https://sompylasar.github.io)<br />[🐛](https://github.com/testing-library/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;" alt="Jesse Day"/><br /><sub><b>Jesse Day</b></sub>](https://github.com/jday3)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=jday3 "Code") | [<img src="https://avatars0.githubusercontent.com/u/15199?v=4" width="100px;" alt="Ernesto García"/><br /><sub><b>Ernesto García</b></sub>](http://gnapse.github.io)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=gnapse "Code") [📖](https://github.com/testing-library/jest-dom/commits?author=gnapse "Documentation") [⚠️](https://github.com/testing-library/jest-dom/commits?author=gnapse "Tests") | [<img src="https://avatars0.githubusercontent.com/u/79312?v=4" width="100px;" alt="Mark Volkmann"/><br /><sub><b>Mark Volkmann</b></sub>](http://ociweb.com/mark/)<br />[🐛](https://github.com/testing-library/jest-dom/issues?q=author%3Amvolkmann "Bug reports") [💻](https://github.com/testing-library/jest-dom/commits?author=mvolkmann "Code") |
762765
| [<img src="https://avatars1.githubusercontent.com/u/1659099?v=4" width="100px;" alt="smacpherson64"/><br /><sub><b>smacpherson64</b></sub>](https://github.com/smacpherson64)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=smacpherson64 "Code") [📖](https://github.com/testing-library/jest-dom/commits?author=smacpherson64 "Documentation") [⚠️](https://github.com/testing-library/jest-dom/commits?author=smacpherson64 "Tests") | [<img src="https://avatars2.githubusercontent.com/u/132233?v=4" width="100px;" alt="John Gozde"/><br /><sub><b>John Gozde</b></sub>](https://github.com/jgoz)<br />[🐛](https://github.com/testing-library/jest-dom/issues?q=author%3Ajgoz "Bug reports") [💻](https://github.com/testing-library/jest-dom/commits?author=jgoz "Code") | [<img src="https://avatars2.githubusercontent.com/u/7830590?v=4" width="100px;" alt="Iwona"/><br /><sub><b>Iwona</b></sub>](https://github.com/callada)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=callada "Code") [📖](https://github.com/testing-library/jest-dom/commits?author=callada "Documentation") [⚠️](https://github.com/testing-library/jest-dom/commits?author=callada "Tests") | [<img src="https://avatars0.githubusercontent.com/u/840609?v=4" width="100px;" alt="Lewis"/><br /><sub><b>Lewis</b></sub>](https://github.com/6ewis)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=6ewis "Code") | [<img src="https://avatars3.githubusercontent.com/u/2339362?v=4" width="100px;" alt="Leandro Lourenci"/><br /><sub><b>Leandro Lourenci</b></sub>](https://blog.lourenci.com/)<br />[🐛](https://github.com/testing-library/jest-dom/issues?q=author%3Alourenci "Bug reports") [📖](https://github.com/testing-library/jest-dom/commits?author=lourenci "Documentation") [💻](https://github.com/testing-library/jest-dom/commits?author=lourenci "Code") [⚠️](https://github.com/testing-library/jest-dom/commits?author=lourenci "Tests") | [<img src="https://avatars1.githubusercontent.com/u/626420?v=4" width="100px;" alt="Shukhrat Mukimov"/><br /><sub><b>Shukhrat Mukimov</b></sub>](https://github.com/mufasa71)<br />[🐛](https://github.com/testing-library/jest-dom/issues?q=author%3Amufasa71 "Bug reports") | [<img src="https://avatars3.githubusercontent.com/u/1481264?v=4" width="100px;" alt="Roman Usherenko"/><br /><sub><b>Roman Usherenko</b></sub>](https://github.com/dreyks)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=dreyks "Code") [⚠️](https://github.com/testing-library/jest-dom/commits?author=dreyks "Tests") |
763-
| [<img src="https://avatars1.githubusercontent.com/u/648?v=4" width="100px;" alt="Joe Hsu"/><br /><sub><b>Joe Hsu</b></sub>](http://josephhsu.com)<br />[📖](https://github.com/testing-library/jest-dom/commits?author=jhsu "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/3068563?v=4" width="100px;" alt="Haz"/><br /><sub><b>Haz</b></sub>](https://twitter.com/diegohaz)<br />[🐛](https://github.com/testing-library/jest-dom/issues?q=author%3Adiegohaz "Bug reports") [💻](https://github.com/testing-library/jest-dom/commits?author=diegohaz "Code") |
764-
766+
| [<img src="https://avatars1.githubusercontent.com/u/648?v=4" width="100px;" alt="Joe Hsu"/><br /><sub><b>Joe Hsu</b></sub>](http://josephhsu.com)<br />[📖](https://github.com/testing-library/jest-dom/commits?author=jhsu "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/3068563?v=4" width="100px;" alt="Haz"/><br /><sub><b>Haz</b></sub>](https://twitter.com/diegohaz)<br />[🐛](https://github.com/testing-library/jest-dom/issues?q=author%3Adiegohaz "Bug reports") [💻](https://github.com/testing-library/jest-dom/commits?author=diegohaz "Code") | [<img src="https://avatars3.githubusercontent.com/u/463904?v=4" width="100px;" alt="Revath S Kumar"/><br /><sub><b>Revath S Kumar</b></sub>](https://blog.revathskumar.com)<br />[💻](https://github.com/testing-library/jest-dom/commits?author=revathskumar "Code") |
765767
<!-- ALL-CONTRIBUTORS-LIST:END -->
766768
767769
This project follows the [all-contributors][all-contributors] specification.

extend-expect.d.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
declare namespace jest {
2+
interface InverseStringAsymmetricMatchers {
3+
stringMatching(str: string | RegExp): any
4+
stringContaining(str: string): any
5+
}
6+
interface Expect {
7+
stringMatching(str: string | RegExp): any
8+
stringContaining(str: string): any
9+
anything(): any
10+
any(classType: any): any
11+
not: InverseStringAsymmetricMatchers
12+
}
13+
14+
type attributeValueType =
15+
| string
16+
| Expect.stringContaining
17+
| Expect.stringMatching
18+
| Expect.any
19+
| Expect.anything
20+
| Expect.not
21+
222
interface Matchers<R> {
323
/**
424
* @deprecated
@@ -11,7 +31,7 @@ declare namespace jest {
1131
toBeEnabled(): R
1232
toContainElement(element: HTMLElement | SVGElement | null): R
1333
toContainHTML(htmlText: string): R
14-
toHaveAttribute(attr: string, value?: string): R
34+
toHaveAttribute(attr: string, value?: attributeValueType): R
1535
toHaveClass(...classNames: string[]): R
1636
toHaveFocus(): R
1737
toHaveFormValues(expectedValues: {[name: string]: any}): R

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"chalk": "^2.4.1",
3737
"css": "^2.2.3",
3838
"css.escape": "^1.5.1",
39+
"expect": "^24.7.1",
3940
"jest-diff": "^24.0.0",
4041
"jest-matcher-utils": "^24.0.0",
4142
"lodash": "^4.17.11",

src/__tests__/to-have-attribute.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,22 @@ test('.toHaveAttribute', () => {
4141
expect(() =>
4242
expect({thisIsNot: 'an html element'}).not.toHaveAttribute(),
4343
).toThrowError()
44+
45+
// Asymettic matchers
46+
expect(queryByTestId('ok-button')).toHaveAttribute(
47+
'type',
48+
expect.stringContaining('sub'),
49+
)
50+
expect(queryByTestId('ok-button')).toHaveAttribute(
51+
'type',
52+
expect.stringMatching(/sub*/),
53+
)
54+
expect(queryByTestId('ok-button')).toHaveAttribute('type', expect.anything())
55+
56+
expect(() =>
57+
expect(queryByTestId('ok-button')).toHaveAttribute(
58+
'type',
59+
expect.not.stringContaining('sub'),
60+
),
61+
).toThrowError()
4462
})

src/to-have-attribute.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {matcherHint, stringify, printExpected} from 'jest-matcher-utils'
2+
import {equals} from 'expect/build/jasmineUtils'
23
import {checkHtmlElement, getMessage} from './utils'
34

45
function printAttribute(name, value) {
@@ -18,7 +19,7 @@ export function toHaveAttribute(htmlElement, name, expectedValue) {
1819
const receivedValue = htmlElement.getAttribute(name)
1920
return {
2021
pass: isExpectedValuePresent
21-
? hasAttribute && receivedValue === expectedValue
22+
? hasAttribute && equals(receivedValue, expectedValue)
2223
: hasAttribute,
2324
message: () => {
2425
const to = this.isNot ? 'not to' : 'to'

0 commit comments

Comments
 (0)