Update checked-in dependencies
This commit is contained in:
parent
3e913ef09d
commit
9660df3fcc
990 changed files with 74805 additions and 60149 deletions
3
node_modules/eslint-plugin-jsx-a11y/.babelrc
generated
vendored
3
node_modules/eslint-plugin-jsx-a11y/.babelrc
generated
vendored
|
|
@ -5,7 +5,8 @@
|
|||
{
|
||||
"targets": {
|
||||
"node": 4
|
||||
}
|
||||
},
|
||||
"transformRuntime": false
|
||||
}
|
||||
]
|
||||
],
|
||||
|
|
|
|||
1
node_modules/eslint-plugin-jsx-a11y/.eslintrc
generated
vendored
1
node_modules/eslint-plugin-jsx-a11y/.eslintrc
generated
vendored
|
|
@ -7,6 +7,7 @@
|
|||
"ignorePatterns": [
|
||||
"lib/",
|
||||
"reports/",
|
||||
"examples/",
|
||||
],
|
||||
"parser": "@babel/eslint-parser",
|
||||
"plugins": [
|
||||
|
|
|
|||
205
node_modules/eslint-plugin-jsx-a11y/CHANGELOG.md
generated
vendored
205
node_modules/eslint-plugin-jsx-a11y/CHANGELOG.md
generated
vendored
|
|
@ -5,57 +5,172 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [v6.7.1](https://github.com/ljharb/eslint-plugin-jsx-a11y/compare/v6.7.0...v6.7.1) - 2023-01-11
|
||||
|
||||
### Commits
|
||||
|
||||
- [Fix] `no-aria-hidden-on-focusable` rule's missing export [`b01219e`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/b01219edc2eb289c7a068b4fa195f2ac04e915fa)
|
||||
|
||||
## [v6.7.0](https://github.com/ljharb/eslint-plugin-jsx-a11y/compare/v6.6.1...v6.7.0) - 2023-01-09
|
||||
|
||||
### Merged
|
||||
|
||||
- New rule: prefer-tag-over-role [`#833`](https://github.com/ljharb/eslint-plugin-jsx-a11y/pull/833)
|
||||
## [v6.10.2](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.10.1...v6.10.2) - 2024-10-25
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Tests] `aria-role`: add now-passing test [`#756`](https://github.com/ljharb/eslint-plugin-jsx-a11y/issues/756)
|
||||
- [Docs] `control-has-associated-label`: fix metadata [`#892`](https://github.com/ljharb/eslint-plugin-jsx-a11y/issues/892)
|
||||
- [New] add `no-aria-hidden-on-focusable` rule [`#881`](https://github.com/ljharb/eslint-plugin-jsx-a11y/issues/881)
|
||||
- [patch] `no-redundandant-roles`: allow `<img src="*.svg" role="img" />` [`#936`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/936)
|
||||
|
||||
### Commits
|
||||
|
||||
- [Docs] automate docs with `eslint-doc-generator` [`6d7a857`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/6d7a857eccceb58dabfa244f6a196ad1697c01a4)
|
||||
- [Refactor] use fromEntries, flatMap, etc; better use iteration methods [`3d77c84`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/3d77c845a98b6fc8cf10c810996278c02e308f35)
|
||||
- [New] add `anchor-ambiguous-text` rule [`7f6463e`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/7f6463e5cffd1faa5cf22e3b0d33465e22bd10e1)
|
||||
- [New] add `getAccessibleChildText` util [`630116b`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/630116b334e22db853a95cd64e20b7df9f2b6dc8)
|
||||
- [New] Add `isFocusable` utils method [`e199d17`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/e199d17db0b6bf1d917dab13a9690876ef6f77e3)
|
||||
- [Docs] update `eslint-doc-generator` to v1.0.0 [`6b9855b`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/6b9855b9c3633308004960594327a10bc2551ad2)
|
||||
- [Fix] `no-noninteractive-element-interactions`: Ignore contenteditable elements in no-noninteractive-element-interactions [`9aa878b`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/9aa878bc39769f6c7b31c72bd1140c1370d202f1)
|
||||
- [New] `anchor-ambiguous-text`: ignore punctuation [`bbae2c4`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/bbae2c46ab4ae94122be6c898f2ef313c6154c27)
|
||||
- [New] `anchor-ambiguous-text`, `getAccessibleChildText`: Implements check for `alt` tags on `<img />` elements [`bb84abc`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/bb84abc793435a25398160242c5f2870b83b72ca)
|
||||
- [meta] use `npmignore` to autogenerate an npmignore file [`6ad2312`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/6ad23124582741385df50e98d5ed0d070f86eafe)
|
||||
- [meta] add `auto-changelog` [`283817b`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/283817b82252ef4a6395c22585d8681f97305ca0)
|
||||
- [Docs] missing descriptions in some rules [`79b975a`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/79b975ab7185cc4fbf6a3adea45c78fac2162d77)
|
||||
- [Deps] update `aria-query`, `axobject-query` [`7b3cda3`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/7b3cda3854451affe20b2e4f2dd57cf317dd7d1b)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types`, `aud`, `object.assign` [`0852947`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/0852947cfd57a34353a97c67f6de28dbcc8be0e3)
|
||||
- [meta] move `.eslintignore` to `ignorePatterns` [`65be35b`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/65be35b0f6c6cf8b79e9a748cb657a64b78c6535)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `aud`, `eslint-doc-generator` [`60c2df5`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/60c2df5388a3f841a7780eafe1a0fbb44056743d)
|
||||
- [Deps] update `@babel/runtime`, `array-includes`, `axe-core` [`4abc751`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/4abc751d87a8491219a9a3d2dacd80ea8adcb79b)
|
||||
- [Deps] update `@babel/runtime`, `axe-core` [`89f766c`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/89f766cd40fd32ada2020856b251ad6e34a6f365)
|
||||
- [meta] run the build in prepack, not prepublish [`e411ce3`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/e411ce35cfa58181d375544ba5204c35db83678c)
|
||||
- [Dev Deps] update `@babel/core`, `minimist` [`cccdb62`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/cccdb625d6237538fb4443349870293e8df818eb)
|
||||
- [Dev Deps] update `markdown-magic` [`3382059`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/3382059feb5367c79e049943772e3a6e27e77609)
|
||||
- [Fix] expose `prefer-tag-over-role` [`38d52f8`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/38d52f856a18d444e6db7d16d373e0d18c5b287d)
|
||||
- [Docs] `label-has-for`: reran generate-list-of-rules [`9a2af01`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/9a2af0172cefad7fdce869401b2df42536812152)
|
||||
- [Deps] pin `language-tags` to `v1.0.5` [`f84bb74`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/f84bb746857cfbc075f8e7104b3a16dddb66be7c)
|
||||
- [Dev Deps] update `@babel/core` [`cf3f8d0`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/cf3f8d0a6bde6dc5ad39a96a6ed1912c1ad80e89)
|
||||
- [Deps] update `axe-core` [`0a73cf4`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/0a73cf4ad0adca0bef0a383a10a14597acef5713)
|
||||
- [Deps] update `@babel/runtime` [`053f04d`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/053f04da8b60d259e4c92f214ffba07a14f3ec61)
|
||||
- [Deps] update `@babel/runtime` [`bccf0ae`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/bccf0aeab8dd337c5f134f892a6d3588fbc29bdf)
|
||||
- [Deps] update `jsx-ast-utils` [`c9687cc`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/c9687cc2a1b7f5f72c8181a9fd6a47f49c373240)
|
||||
- [readme] Preventing code repetition in user's eslint config file [`8b889bf`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/8b889bff2731c9db6988c88c0d76bdbff17bd3c5)
|
||||
- [Docs] `prefer-tag-over-role`: rename docs file [`0bdf95b`](https://github.com/ljharb/eslint-plugin-jsx-a11y/commit/0bdf95b41cce32c8b7916367e7c8c663411d881c)
|
||||
- [meta] fix changelog URLs [`0d01a1a`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0d01a1aff796802bca70183b24978ffebdbef073)
|
||||
- [Refactor] remove no-longer-needed `es-iterator-helpers` [`aa075bd`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/aa075bd1897e0b0bb61683e4da68558f38511dae)
|
||||
- [Refactor] avoid spreading things that are already arrays [`d15d3ab`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/d15d3abace7afe833d0988eaf3fb7cc166c05c06)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types`, `@babel/register` [`5dad7c4`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/5dad7c4fdfdc56c6e488fab54f25f602430dad30)
|
||||
- [Tests] `aria-role`: Add valid test for `<svg role="img" />` [`daba189`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/daba18974473bce1301ffaafb822558a9e1738ae)
|
||||
- [Docs] `label-has-associated-control`: add line breaks for readability [`0bc6378`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0bc63781c8f284ac6bef00321763c13c5bea6b9f)
|
||||
- [Tests] `label-has-associated-control`: add additional test cases [`30d2318`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/30d23189d0b6354750c31a622204a9dc412dc2c1)
|
||||
- [Tests] Add tests to reinforce required attributes for role="heading" [`d92446c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/d92446c6e608617a4c75173e8b0917c06be14dc6)
|
||||
|
||||
## [v6.10.1](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.10.0...v6.10.1) - 2024-10-20
|
||||
|
||||
### Commits
|
||||
|
||||
- [Fix] handle interactive/noninteractive changes from aria-query [`4925ba8`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/4925ba8d0bf80a4b1d8e8645d310590bf1b40b64)
|
||||
- [Docs] Use consistent spelling of 'screen reader' [`cb6788c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/cb6788c56d7108f2faa102d041dfa37dbc0e9f59)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types`, `@babel/register`, `auto-changelog`, `eslint-plugin-import`, `tape` [`518a77e`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/518a77e1e23fb2b1df2e8a97d14bfdd08aded797)
|
||||
- [Deps] update `es-iterator-helpers`, `string.prototype.includes` [`eed03a3`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/eed03a31f313442158cf7d702443723ad4800dec)
|
||||
- [meta] package.json - Update jscodeshift & remove babel-jest [`2ee940c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/2ee940c5ae87bcd0d384b6dc565d630ea70e103a)
|
||||
- [Docs] Remove accidental whitespace in CONTRIBUTING.md [`a262131`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/a26213142854ffe3d931fab35f0ee4e6ae101875)
|
||||
- [Deps] unpin `aria-query` [`e517937`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/e51793729e5e366e30d2f3bf0f253f2bdb9e6523)
|
||||
|
||||
## [v6.10.0](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.9.0...v6.10.0) - 2024-09-03
|
||||
|
||||
### Fixed
|
||||
|
||||
- [New] `label-has-associated-control`: add additional error message [`#1005`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/1005)
|
||||
- [Fix] `label-has-associated-control`: ignore undetermined label text [`#966`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/966)
|
||||
|
||||
### Commits
|
||||
|
||||
- [Tests] switch from jest to tape [`a284cbf`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/a284cbf4eb21292c4cff87f02be0bfb82764757f)
|
||||
- [New] add eslint 9 support [`deac4fd`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/deac4fd06eff4c0f5da27611c2a44a009b7e7fda)
|
||||
- [New] add `attributes` setting [`a1ee7f8`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/a1ee7f8810efafe416eb5d7f6eb0505b52873495)
|
||||
- [New] allow polymorphic linting to be restricted [`6cd1a70`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6cd1a7011446e3925f2b49c51ff26246a21491d1)
|
||||
- [Tests] remove duplicate tests [`74d5dec`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/74d5decb6f2e42c05ce40a45630041fd695a2e7f)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types` [`6eca235`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6eca2359f5457af72dbfba265b73297c9232cb3e)
|
||||
- [readme] remove deprecated travis ci badge; add github actions badge [`0be7ea9`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0be7ea95f560c6afc6817d381054d914ebd0b2ca)
|
||||
- [Tests] use `npm audit` instead of `aud` [`05a5e49`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/05a5e4992900e0d5d61e29e13046c90797b68a7c)
|
||||
- [Deps] update `axobject-query` [`912e98c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/912e98c425ef9fcc2d7d22b45b4f7e3b445112a5)
|
||||
- [Deps] unpin `axobject-query` [`75147aa`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/75147aa68888fc150a4efea5b99809969bdc32b2)
|
||||
- [Deps] update `axe-core` [`27ff7cb`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/27ff7cbf562bf2685fd5a6062e58eb4727cb85c6)
|
||||
- [readme] fix jsxA11y import name [`ce846e0`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/ce846e00414c41676a6a8601022059878bcc0b89)
|
||||
- [readme] fix typo in shareable config section in readme [`cca288b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/cca288b73a39fa0932a57c02a7a88de68fc971fc)
|
||||
|
||||
## [v6.9.0](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.8.0...v6.9.0) - 2024-06-19
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Fix] `img-redundant-alt`: fixed multibyte character support [`#969`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/969)
|
||||
- [meta] fix changelog links [`#960`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/960)
|
||||
|
||||
### Commits
|
||||
|
||||
- [New] add support for Flat Config [`6b5f096`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6b5f096f10b47326d68e2893152a48a79c8555b4)
|
||||
- Revert "[Fix] `isNonInteractiveElement`: Upgrade aria-query to 5.3.0 and axobject-query to 3.2.1" [`75d5dd7`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/75d5dd722bd67186d97afa7b151fd6fee5885c70)
|
||||
- [Robustness] use `safe-regex-test` [`4c7e781`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/4c7e7815c12a797587bb8e3cdced7f3003848964)
|
||||
- [actions] update actions/checkout [`51a1ca7`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/51a1ca7b4d83d4fbd1ea62888f7f2dc21ece6788)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types`, `@babel/register`, `eslint-doc-generator`, `object.entries` [`1271ac1`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/1271ac1d6e5dcf9a2bc2c086faaf062335629171)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/register`, `aud`, `eslint-plugin-import`, `npmignore`, `object.assign` [`540cb7a`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/540cb7aefead582f237071d55a40f098d0885478)
|
||||
- [Deps] update `@babel/runtime`, `array-includes`, `es-iterator-helpers`, `hasown`, `object.fromentries`, `safe-regex-test` [`5d14408`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/5d1440825a8838ae10dc94cc3a4a7e1e967644b4)
|
||||
- [Deps] pin `aria-query` and `axobject-query`, add `ls-engines` test to CI [`32fd82c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/32fd82c628d7f3e4ec8c06a1994f4eca1be2be4f)
|
||||
- [Dev Deps] update `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types`, `eslint-doc-generator` [`d1b4114`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/d1b41142248a7cca45bb5f0b96ff23ee87fb9411)
|
||||
- [Fix] ensure `summary` remains non-interactive [`6a048da`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6a048dacf2b98eaa204e2a5a70dc7e3d48d9463a)
|
||||
- [Deps] remove `@babel/runtime` [`0a98ad8`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0a98ad83ffa7f4b66458cc1c39db2ef32bb2c480)
|
||||
- [New] `no-noninteractive-element-to-interactive-role`: allow `menuitemradio` and `menuitemcheckbox` on <li> [`c0733f9`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/c0733f94031fe3eec6b4d54176afe47929bb0a84)
|
||||
- [Deps] update `@babel/runtime`, `safe-regex-test` [`0d5321a`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0d5321a5457c5f0da0ca216053cc5b4f571b53ae)
|
||||
- [actions] pin codecov to v3.1.5 [`961817f`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/961817f61fa56cd7815c6940c27ef08469b1516b)
|
||||
- [Deps] unpin `axe-core` [`b3559cf`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/b3559cf89be6b5352cd77ffa025831b3d793d565)
|
||||
- [Deps] move `object.entries` to dev deps [`1be7b70`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/1be7b709eececd83f1d5f67a60b2c97cfe9a561d)
|
||||
- [Deps] update `@babel/runtime` [`2a48abb`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/2a48abb5effa911e7d1a8575e1c9768c947a33f1)
|
||||
- [Deps] update `@babel/runtime` [`1adec35`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/1adec3517fc2c9797212ca4d38858deed917e7be)
|
||||
|
||||
## [v6.8.0](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.7.1...v6.8.0) - 2023-11-01
|
||||
|
||||
### Merged
|
||||
|
||||
- Allow `title` attribute or `aria-label` attribute instead of accessible child in the "anchor-has-content" rule [`#727`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/pull/727)
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Docs] `aria-activedescendant-has-tabindex`: align with changes from #708 [`#924`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/924)
|
||||
- [Fix] `control-has-associated-label`: don't accept whitespace as an accessible label [`#918`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/918)
|
||||
|
||||
### Commits
|
||||
|
||||
- [Tests] migrate helper parsers function from `eslint-plugin-react` [`ce4d57f`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/ce4d57f853ce7f71bd31edaa524eeb3ff1d27cf1)
|
||||
- [Refactor] use `es-iterator-helpers` [`52de824`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/52de82403752bb2ccbcac3379925650a0112d4af)
|
||||
- [New] `mouse-events-have-key-events`: add `hoverInHandlers`/`hoverOutHandlers` config [`db64898`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/db64898fa591f17827053ad3c2ddeafdf7297dd6)
|
||||
- [New] add `polymorphicPropName` setting for polymorphic components [`fffb05b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/fffb05b38c8eee926ee758e9ceb9eae4e697fbdd)
|
||||
- [Fix] `isNonInteractiveElement`: Upgrade aria-query to 5.3.0 and axobject-query to 3.2.1 [`64bfea6`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/64bfea6352a704470a760fa6ea25cfc5a50414db)
|
||||
- [Refactor] use `hasown` instead of `has` [`9a8edde`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/9a8edde7f2e80b7d104dd576f91526c6c4cbebb9)
|
||||
- [actions] update used actions [`10c061a`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/10c061a70cac067641e3a084d0fb464960544505)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types`, `@babel/register`, `aud`, `eslint-doc-generator`, `eslint-plugin-import`, `minimist` [`6d5022d`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6d5022d4894fa88d3c15c8b858114e8b2a8a440f)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/register`, `eslint-doc-generator`, `eslint-plugin-import` [`4dc7f1e`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/4dc7f1e5c611aeea2f81dc50d4ec0b206566181a)
|
||||
- [New] `anchor-has-content`: Allow title attribute OR aria-label attribute [`e6bfd5c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/e6bfd5cb7c060fcaf54ede85a1be74ebe2f60d1e)
|
||||
- [patch] `mouse-events-have-key-events`: rport the attribute, not the node [`eadd70c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/eadd70cb1d0478c24538ee7604cf5493a96c0715)
|
||||
- [Deps] update `@babel/runtime`, `array-includes`, `array.prototype.flatmap`, `object.entries`, `object.fromentries` [`46ffbc3`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/46ffbc38512be4ed3db2f0fcd7d21af830574f63)
|
||||
- [Deps] update `@babel/runtime`, `axobject-query`, `jsx-ast-utils`, `semver` [`5999555`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/5999555714f594c0fccfeeab2063c2658d9e4392)
|
||||
- [Fix] pin `aria-query` and `axe-core` to fix failing tests on main [`8d8f016`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/8d8f0169dbaaa28143cf936cba3046c6e53fa134)
|
||||
- [patch] move `semver` from Deps to Dev Deps [`4da13e7`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/4da13e79743ad2e1073fc2bb682197e1ba6dbea3)
|
||||
- [Deps] update `ast-types-flow` [`b755318`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/b755318e675e73a33b1bb7ee809abc88c1927408)
|
||||
- [Dev Deps] update `eslint-plugin-import` [`f1c976b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/f1c976b6af2d4f5237b481348868a5216e169296)
|
||||
- [Deps] unpin `language-tags` [`3d1d26d`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/3d1d26d89d492947cbf69f439deec9e7cfaf9867)
|
||||
- [Docs] `no-static-element-interactions`: tabIndex is written tabindex [`1271153`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/1271153653ada3f8d95b8e39f0164d5b255abea0)
|
||||
- [Deps] Upgrade ast-types-flow to mitigate Docker user namespacing problems [`f0d2ddb`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/f0d2ddb65f21278ad29be43fb167a1092287b4b1)
|
||||
- [Dev Deps] pin `jackspeak` since 2.1.2+ depends on npm aliases, which kill the install process in npm < 6 [`0c278f4`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0c278f4805ec18d8ee4d3e8dfa2f603a28d7e113)
|
||||
|
||||
## [v6.7.1](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.7.0...v6.7.1) - 2023-01-11
|
||||
|
||||
### Commits
|
||||
|
||||
- [Fix] `no-aria-hidden-on-focusable` rule's missing export [`b01219e`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/b01219edc2eb289c7a068b4fa195f2ac04e915fa)
|
||||
|
||||
## [v6.7.0](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.6.1...v6.7.0) - 2023-01-09
|
||||
|
||||
### Merged
|
||||
|
||||
- New rule: prefer-tag-over-role [`#833`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/pull/833)
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Tests] `aria-role`: add now-passing test [`#756`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/756)
|
||||
- [Docs] `control-has-associated-label`: fix metadata [`#892`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/892)
|
||||
- [New] add `no-aria-hidden-on-focusable` rule [`#881`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/881)
|
||||
|
||||
### Commits
|
||||
|
||||
- [Docs] automate docs with `eslint-doc-generator` [`6d7a857`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6d7a857eccceb58dabfa244f6a196ad1697c01a4)
|
||||
- [Refactor] use fromEntries, flatMap, etc; better use iteration methods [`3d77c84`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/3d77c845a98b6fc8cf10c810996278c02e308f35)
|
||||
- [New] add `anchor-ambiguous-text` rule [`7f6463e`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/7f6463e5cffd1faa5cf22e3b0d33465e22bd10e1)
|
||||
- [New] add `getAccessibleChildText` util [`630116b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/630116b334e22db853a95cd64e20b7df9f2b6dc8)
|
||||
- [New] Add `isFocusable` utils method [`e199d17`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/e199d17db0b6bf1d917dab13a9690876ef6f77e3)
|
||||
- [Docs] update `eslint-doc-generator` to v1.0.0 [`6b9855b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6b9855b9c3633308004960594327a10bc2551ad2)
|
||||
- [Fix] `no-noninteractive-element-interactions`: Ignore contenteditable elements in no-noninteractive-element-interactions [`9aa878b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/9aa878bc39769f6c7b31c72bd1140c1370d202f1)
|
||||
- [New] `anchor-ambiguous-text`: ignore punctuation [`bbae2c4`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/bbae2c46ab4ae94122be6c898f2ef313c6154c27)
|
||||
- [New] `anchor-ambiguous-text`, `getAccessibleChildText`: Implements check for `alt` tags on `<img />` elements [`bb84abc`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/bb84abc793435a25398160242c5f2870b83b72ca)
|
||||
- [meta] use `npmignore` to autogenerate an npmignore file [`6ad2312`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/6ad23124582741385df50e98d5ed0d070f86eafe)
|
||||
- [meta] add `auto-changelog` [`283817b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/283817b82252ef4a6395c22585d8681f97305ca0)
|
||||
- [Docs] missing descriptions in some rules [`79b975a`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/79b975ab7185cc4fbf6a3adea45c78fac2162d77)
|
||||
- [Deps] update `aria-query`, `axobject-query` [`7b3cda3`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/7b3cda3854451affe20b2e4f2dd57cf317dd7d1b)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `@babel/eslint-parser`, `@babel/plugin-transform-flow-strip-types`, `aud`, `object.assign` [`0852947`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0852947cfd57a34353a97c67f6de28dbcc8be0e3)
|
||||
- [meta] move `.eslintignore` to `ignorePatterns` [`65be35b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/65be35b0f6c6cf8b79e9a748cb657a64b78c6535)
|
||||
- [Dev Deps] update `@babel/cli`, `@babel/core`, `aud`, `eslint-doc-generator` [`60c2df5`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/60c2df5388a3f841a7780eafe1a0fbb44056743d)
|
||||
- [Deps] update `@babel/runtime`, `array-includes`, `axe-core` [`4abc751`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/4abc751d87a8491219a9a3d2dacd80ea8adcb79b)
|
||||
- [Deps] update `@babel/runtime`, `axe-core` [`89f766c`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/89f766cd40fd32ada2020856b251ad6e34a6f365)
|
||||
- [meta] run the build in prepack, not prepublish [`e411ce3`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/e411ce35cfa58181d375544ba5204c35db83678c)
|
||||
- [Dev Deps] update `@babel/core`, `minimist` [`cccdb62`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/cccdb625d6237538fb4443349870293e8df818eb)
|
||||
- [Dev Deps] update `markdown-magic` [`3382059`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/3382059feb5367c79e049943772e3a6e27e77609)
|
||||
- [Fix] expose `prefer-tag-over-role` [`38d52f8`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/38d52f856a18d444e6db7d16d373e0d18c5b287d)
|
||||
- [Docs] `label-has-for`: reran generate-list-of-rules [`9a2af01`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/9a2af0172cefad7fdce869401b2df42536812152)
|
||||
- [Deps] pin `language-tags` to `v1.0.5` [`f84bb74`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/f84bb746857cfbc075f8e7104b3a16dddb66be7c)
|
||||
- [Dev Deps] update `@babel/core` [`cf3f8d0`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/cf3f8d0a6bde6dc5ad39a96a6ed1912c1ad80e89)
|
||||
- [Deps] update `axe-core` [`0a73cf4`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0a73cf4ad0adca0bef0a383a10a14597acef5713)
|
||||
- [Deps] update `@babel/runtime` [`053f04d`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/053f04da8b60d259e4c92f214ffba07a14f3ec61)
|
||||
- [Deps] update `@babel/runtime` [`bccf0ae`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/bccf0aeab8dd337c5f134f892a6d3588fbc29bdf)
|
||||
- [Deps] update `jsx-ast-utils` [`c9687cc`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/c9687cc2a1b7f5f72c8181a9fd6a47f49c373240)
|
||||
- [readme] Preventing code repetition in user's eslint config file [`8b889bf`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/8b889bff2731c9db6988c88c0d76bdbff17bd3c5)
|
||||
- [Docs] `prefer-tag-over-role`: rename docs file [`0bdf95b`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/commit/0bdf95b41cce32c8b7916367e7c8c663411d881c)
|
||||
|
||||
<!-- auto-changelog-above -->
|
||||
|
||||
|
|
|
|||
212
node_modules/eslint-plugin-jsx-a11y/README.md
generated
vendored
212
node_modules/eslint-plugin-jsx-a11y/README.md
generated
vendored
|
|
@ -1,7 +1,7 @@
|
|||
<p align="center">
|
||||
<a href="https://travis-ci.com/github/jsx-eslint/eslint-plugin-jsx-a11y">
|
||||
<img src="https://travis-ci.com/jsx-eslint/eslint-plugin-jsx-a11y.svg?branch=master"
|
||||
alt="build status">
|
||||
<a href="https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/actions">
|
||||
<img src="https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/jsx-eslint/eslint-plugin-jsx-a11y"
|
||||
alt="CI status" />
|
||||
</a>
|
||||
<a href="https://npmjs.org/package/eslint-plugin-jsx-a11y">
|
||||
<img src="https://img.shields.io/npm/v/eslint-plugin-jsx-a11y.svg"
|
||||
|
|
@ -60,7 +60,8 @@ yarn add eslint-plugin-jsx-a11y --dev
|
|||
|
||||
**Note:** If you installed ESLint globally (using the `-g` flag in npm, or the `global` prefix in yarn) then you must also install `eslint-plugin-jsx-a11y` globally.
|
||||
|
||||
## Usage
|
||||
<a id="usage"></a>
|
||||
## Usage - Legacy Config (`.eslintrc`)
|
||||
|
||||
Add `jsx-a11y` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
|
||||
|
||||
|
|
@ -89,26 +90,141 @@ Add `plugin:jsx-a11y/recommended` or `plugin:jsx-a11y/strict` in `extends`:
|
|||
}
|
||||
```
|
||||
|
||||
> As you are extending our configuration, you can omit `"plugins": ["jsx-a11y"]` from your `.eslintrc` configuration file.
|
||||
### Configurations
|
||||
|
||||
To enable your custom components to be checked as DOM elements, you can set global settings in your
|
||||
configuration file by mapping each custom component name to a DOM element type.
|
||||
> As you are extending our configuration, you can omit `"plugins": ["jsx-a11y"]` from your `.eslintrc` configuration file.
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": {
|
||||
"jsx-a11y": {
|
||||
"polymorphicPropName": "as",
|
||||
"components": {
|
||||
"CityInput": "input",
|
||||
"CustomButton": "button",
|
||||
"MyButton": "button",
|
||||
"RoundButton": "button"
|
||||
},
|
||||
"attributes": {
|
||||
"for": ["htmlFor", "for"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage - Flat Config (`eslint.config.js`)
|
||||
|
||||
The default export of `eslint-plugin-jsx-a11y` is a plugin object.
|
||||
|
||||
```js
|
||||
const jsxA11y = require('eslint-plugin-jsx-a11y');
|
||||
|
||||
module.exports = [
|
||||
…
|
||||
{
|
||||
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
|
||||
plugins: {
|
||||
'jsx-a11y': jsxA11y,
|
||||
},
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// ... any rules you want
|
||||
'jsx-a11y/alt-text': 'error',
|
||||
},
|
||||
// ... others are omitted for brevity
|
||||
},
|
||||
…
|
||||
];
|
||||
```
|
||||
|
||||
### Shareable Configs
|
||||
|
||||
There are two shareable configs, provided by the plugin.
|
||||
|
||||
- `flatConfigs.recommended`
|
||||
- `flatConfigs.strict`
|
||||
|
||||
#### CJS
|
||||
|
||||
```js
|
||||
const jsxA11y = require('eslint-plugin-jsx-a11y');
|
||||
|
||||
export default [
|
||||
jsxA11y.flatConfigs.recommended,
|
||||
{
|
||||
// Your additional configs and overrides
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
#### ESM
|
||||
|
||||
```js
|
||||
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
||||
|
||||
export default [
|
||||
jsxA11y.flatConfigs.recommended,
|
||||
{
|
||||
// Your additional configs and overrides
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
**Note**: Our shareable configs do NOT configure `files` or [`languageOptions.globals`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects).
|
||||
For most of the cases, you probably want to configure some of these properties yourself.
|
||||
|
||||
```js
|
||||
const jsxA11y = require('eslint-plugin-jsx-a11y');
|
||||
const globals = require('globals');
|
||||
|
||||
module.exports = [
|
||||
…
|
||||
{
|
||||
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
|
||||
...jsxA11y.flatConfigs.recommended,
|
||||
languageOptions: {
|
||||
...jsxA11y.flatConfigs.recommended.languageOptions,
|
||||
globals: {
|
||||
...globals.serviceworker,
|
||||
...globals.browser,
|
||||
},
|
||||
},
|
||||
},
|
||||
…
|
||||
];
|
||||
```
|
||||
|
||||
#### Component Mapping
|
||||
|
||||
To enable your custom components to be checked as DOM elements, you can set global settings in your configuration file by mapping each custom component name to a DOM element type.
|
||||
|
||||
#### Attribute Mapping
|
||||
|
||||
To configure the JSX property to use for attribute checking, you can set global settings in your configuration file by mapping each DOM attribute to the JSX property you want to check.
|
||||
For example, you may want to allow the `for` attribute in addition to the `htmlFor` attribute for checking label associations.
|
||||
|
||||
#### Polymorphic Components
|
||||
|
||||
You can optionally use the `polymorphicPropName` setting to define the prop your code uses to create polymorphic components.
|
||||
This setting will be used determine the element type in rules that require semantic context.
|
||||
|
||||
For example, if you set the `polymorphicPropName` setting to `as` then this element:
|
||||
|
||||
`<Box as="h3">Configurations </Box>`
|
||||
|
||||
will be evaluated as an `h3`. If no `polymorphicPropName` is set, then the component will be evaluated as `Box`.
|
||||
|
||||
To restrict polymorphic linting to specified components, additionally set `polymorphicAllowList` to an array of component names.
|
||||
|
||||
⚠️ Polymorphic components can make code harder to maintain; please use this feature with caution.
|
||||
|
||||
## Supported Rules
|
||||
|
||||
<!-- begin auto-generated rules list -->
|
||||
|
|
@ -119,47 +235,47 @@ configuration file by mapping each custom component name to a DOM element type.
|
|||
🔒 Set in the `strict` configuration.\
|
||||
❌ Deprecated.
|
||||
|
||||
| Name | Description | 💼 | 🚫 | ❌ |
|
||||
| :----------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :---- | :---- | :- |
|
||||
| [accessible-emoji](docs/rules/accessible-emoji.md) | Enforce emojis are wrapped in `<span>` and provide screenreader access. | | | ❌ |
|
||||
| [alt-text](docs/rules/alt-text.md) | Enforce all elements that require alternative text have meaningful information to relay back to end user. | ☑️ 🔒 | | |
|
||||
| [anchor-ambiguous-text](docs/rules/anchor-ambiguous-text.md) | Enforce `<a>` text to not exactly match "click here", "here", "link", or "a link". | | ☑️ | |
|
||||
| [anchor-has-content](docs/rules/anchor-has-content.md) | Enforce all anchors to contain accessible content. | ☑️ 🔒 | | |
|
||||
| [anchor-is-valid](docs/rules/anchor-is-valid.md) | Enforce all anchors are valid, navigable elements. | ☑️ 🔒 | | |
|
||||
| [aria-activedescendant-has-tabindex](docs/rules/aria-activedescendant-has-tabindex.md) | Enforce elements with aria-activedescendant are tabbable. | ☑️ 🔒 | | |
|
||||
| [aria-props](docs/rules/aria-props.md) | Enforce all `aria-*` props are valid. | ☑️ 🔒 | | |
|
||||
| [aria-proptypes](docs/rules/aria-proptypes.md) | Enforce ARIA state and property values are valid. | ☑️ 🔒 | | |
|
||||
| [aria-role](docs/rules/aria-role.md) | Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role. | ☑️ 🔒 | | |
|
||||
| [aria-unsupported-elements](docs/rules/aria-unsupported-elements.md) | Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes. | ☑️ 🔒 | | |
|
||||
| [autocomplete-valid](docs/rules/autocomplete-valid.md) | Enforce that autocomplete attributes are used correctly. | ☑️ 🔒 | | |
|
||||
| [click-events-have-key-events](docs/rules/click-events-have-key-events.md) | Enforce a clickable non-interactive element has at least one keyboard event listener. | ☑️ 🔒 | | |
|
||||
| [control-has-associated-label](docs/rules/control-has-associated-label.md) | Enforce that a control (an interactive element) has a text label. | | ☑️ 🔒 | |
|
||||
| [heading-has-content](docs/rules/heading-has-content.md) | Enforce heading (`h1`, `h2`, etc) elements contain accessible content. | ☑️ 🔒 | | |
|
||||
| [html-has-lang](docs/rules/html-has-lang.md) | Enforce `<html>` element has `lang` prop. | ☑️ 🔒 | | |
|
||||
| [iframe-has-title](docs/rules/iframe-has-title.md) | Enforce iframe elements have a title attribute. | ☑️ 🔒 | | |
|
||||
| [img-redundant-alt](docs/rules/img-redundant-alt.md) | Enforce `<img>` alt prop does not contain the word "image", "picture", or "photo". | ☑️ 🔒 | | |
|
||||
| [interactive-supports-focus](docs/rules/interactive-supports-focus.md) | Enforce that elements with interactive handlers like `onClick` must be focusable. | ☑️ 🔒 | | |
|
||||
| [label-has-associated-control](docs/rules/label-has-associated-control.md) | Enforce that a `label` tag has a text label and an associated control. | ☑️ 🔒 | | |
|
||||
| [label-has-for](docs/rules/label-has-for.md) | Enforce that `<label>` elements have the `htmlFor` prop. | | ☑️ 🔒 | ❌ |
|
||||
| [lang](docs/rules/lang.md) | Enforce lang attribute has a valid value. | | | |
|
||||
| [media-has-caption](docs/rules/media-has-caption.md) | Enforces that `<audio>` and `<video>` elements must have a `<track>` for captions. | ☑️ 🔒 | | |
|
||||
| [mouse-events-have-key-events](docs/rules/mouse-events-have-key-events.md) | Enforce that `onMouseOver`/`onMouseOut` are accompanied by `onFocus`/`onBlur` for keyboard-only users. | ☑️ 🔒 | | |
|
||||
| [no-access-key](docs/rules/no-access-key.md) | Enforce that the `accessKey` prop is not used on any element to avoid complications with keyboard commands used by a screenreader. | ☑️ 🔒 | | |
|
||||
| [no-aria-hidden-on-focusable](docs/rules/no-aria-hidden-on-focusable.md) | Disallow `aria-hidden="true"` from being set on focusable elements. | | | |
|
||||
| [no-autofocus](docs/rules/no-autofocus.md) | Enforce autoFocus prop is not used. | ☑️ 🔒 | | |
|
||||
| [no-distracting-elements](docs/rules/no-distracting-elements.md) | Enforce distracting elements are not used. | ☑️ 🔒 | | |
|
||||
| [no-interactive-element-to-noninteractive-role](docs/rules/no-interactive-element-to-noninteractive-role.md) | Interactive elements should not be assigned non-interactive roles. | ☑️ 🔒 | | |
|
||||
| [no-noninteractive-element-interactions](docs/rules/no-noninteractive-element-interactions.md) | Non-interactive elements should not be assigned mouse or keyboard event listeners. | ☑️ 🔒 | | |
|
||||
| [no-noninteractive-element-to-interactive-role](docs/rules/no-noninteractive-element-to-interactive-role.md) | Non-interactive elements should not be assigned interactive roles. | ☑️ 🔒 | | |
|
||||
| [no-noninteractive-tabindex](docs/rules/no-noninteractive-tabindex.md) | `tabIndex` should only be declared on interactive elements. | ☑️ 🔒 | | |
|
||||
| [no-onchange](docs/rules/no-onchange.md) | Enforce usage of `onBlur` over `onChange` on select menus for accessibility. | | | ❌ |
|
||||
| [no-redundant-roles](docs/rules/no-redundant-roles.md) | Enforce explicit role property is not the same as implicit/default role property on element. | ☑️ 🔒 | | |
|
||||
| [no-static-element-interactions](docs/rules/no-static-element-interactions.md) | Enforce that non-interactive, visible elements (such as `<div>`) that have click handlers use the role attribute. | ☑️ 🔒 | | |
|
||||
| [prefer-tag-over-role](docs/rules/prefer-tag-over-role.md) | Enforces using semantic DOM elements over the ARIA `role` property. | | | |
|
||||
| [role-has-required-aria-props](docs/rules/role-has-required-aria-props.md) | Enforce that elements with ARIA roles must have all required attributes for that role. | ☑️ 🔒 | | |
|
||||
| [role-supports-aria-props](docs/rules/role-supports-aria-props.md) | Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`. | ☑️ 🔒 | | |
|
||||
| [scope](docs/rules/scope.md) | Enforce `scope` prop is only used on `<th>` elements. | ☑️ 🔒 | | |
|
||||
| [tabindex-no-positive](docs/rules/tabindex-no-positive.md) | Enforce `tabIndex` value is not greater than zero. | ☑️ 🔒 | | |
|
||||
| Name | Description | 💼 | 🚫 | ❌ |
|
||||
| :----------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- | :---- | :---- | :- |
|
||||
| [accessible-emoji](docs/rules/accessible-emoji.md) | Enforce emojis are wrapped in `<span>` and provide screen reader access. | | | ❌ |
|
||||
| [alt-text](docs/rules/alt-text.md) | Enforce all elements that require alternative text have meaningful information to relay back to end user. | ☑️ 🔒 | | |
|
||||
| [anchor-ambiguous-text](docs/rules/anchor-ambiguous-text.md) | Enforce `<a>` text to not exactly match "click here", "here", "link", or "a link". | | ☑️ | |
|
||||
| [anchor-has-content](docs/rules/anchor-has-content.md) | Enforce all anchors to contain accessible content. | ☑️ 🔒 | | |
|
||||
| [anchor-is-valid](docs/rules/anchor-is-valid.md) | Enforce all anchors are valid, navigable elements. | ☑️ 🔒 | | |
|
||||
| [aria-activedescendant-has-tabindex](docs/rules/aria-activedescendant-has-tabindex.md) | Enforce elements with aria-activedescendant are tabbable. | ☑️ 🔒 | | |
|
||||
| [aria-props](docs/rules/aria-props.md) | Enforce all `aria-*` props are valid. | ☑️ 🔒 | | |
|
||||
| [aria-proptypes](docs/rules/aria-proptypes.md) | Enforce ARIA state and property values are valid. | ☑️ 🔒 | | |
|
||||
| [aria-role](docs/rules/aria-role.md) | Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role. | ☑️ 🔒 | | |
|
||||
| [aria-unsupported-elements](docs/rules/aria-unsupported-elements.md) | Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes. | ☑️ 🔒 | | |
|
||||
| [autocomplete-valid](docs/rules/autocomplete-valid.md) | Enforce that autocomplete attributes are used correctly. | ☑️ 🔒 | | |
|
||||
| [click-events-have-key-events](docs/rules/click-events-have-key-events.md) | Enforce a clickable non-interactive element has at least one keyboard event listener. | ☑️ 🔒 | | |
|
||||
| [control-has-associated-label](docs/rules/control-has-associated-label.md) | Enforce that a control (an interactive element) has a text label. | | ☑️ 🔒 | |
|
||||
| [heading-has-content](docs/rules/heading-has-content.md) | Enforce heading (`h1`, `h2`, etc) elements contain accessible content. | ☑️ 🔒 | | |
|
||||
| [html-has-lang](docs/rules/html-has-lang.md) | Enforce `<html>` element has `lang` prop. | ☑️ 🔒 | | |
|
||||
| [iframe-has-title](docs/rules/iframe-has-title.md) | Enforce iframe elements have a title attribute. | ☑️ 🔒 | | |
|
||||
| [img-redundant-alt](docs/rules/img-redundant-alt.md) | Enforce `<img>` alt prop does not contain the word "image", "picture", or "photo". | ☑️ 🔒 | | |
|
||||
| [interactive-supports-focus](docs/rules/interactive-supports-focus.md) | Enforce that elements with interactive handlers like `onClick` must be focusable. | ☑️ 🔒 | | |
|
||||
| [label-has-associated-control](docs/rules/label-has-associated-control.md) | Enforce that a `label` tag has a text label and an associated control. | ☑️ 🔒 | | |
|
||||
| [label-has-for](docs/rules/label-has-for.md) | Enforce that `<label>` elements have the `htmlFor` prop. | | ☑️ 🔒 | ❌ |
|
||||
| [lang](docs/rules/lang.md) | Enforce lang attribute has a valid value. | | | |
|
||||
| [media-has-caption](docs/rules/media-has-caption.md) | Enforces that `<audio>` and `<video>` elements must have a `<track>` for captions. | ☑️ 🔒 | | |
|
||||
| [mouse-events-have-key-events](docs/rules/mouse-events-have-key-events.md) | Enforce that `onMouseOver`/`onMouseOut` are accompanied by `onFocus`/`onBlur` for keyboard-only users. | ☑️ 🔒 | | |
|
||||
| [no-access-key](docs/rules/no-access-key.md) | Enforce that the `accessKey` prop is not used on any element to avoid complications with keyboard commands used by a screen reader. | ☑️ 🔒 | | |
|
||||
| [no-aria-hidden-on-focusable](docs/rules/no-aria-hidden-on-focusable.md) | Disallow `aria-hidden="true"` from being set on focusable elements. | | | |
|
||||
| [no-autofocus](docs/rules/no-autofocus.md) | Enforce autoFocus prop is not used. | ☑️ 🔒 | | |
|
||||
| [no-distracting-elements](docs/rules/no-distracting-elements.md) | Enforce distracting elements are not used. | ☑️ 🔒 | | |
|
||||
| [no-interactive-element-to-noninteractive-role](docs/rules/no-interactive-element-to-noninteractive-role.md) | Interactive elements should not be assigned non-interactive roles. | ☑️ 🔒 | | |
|
||||
| [no-noninteractive-element-interactions](docs/rules/no-noninteractive-element-interactions.md) | Non-interactive elements should not be assigned mouse or keyboard event listeners. | ☑️ 🔒 | | |
|
||||
| [no-noninteractive-element-to-interactive-role](docs/rules/no-noninteractive-element-to-interactive-role.md) | Non-interactive elements should not be assigned interactive roles. | ☑️ 🔒 | | |
|
||||
| [no-noninteractive-tabindex](docs/rules/no-noninteractive-tabindex.md) | `tabIndex` should only be declared on interactive elements. | ☑️ 🔒 | | |
|
||||
| [no-onchange](docs/rules/no-onchange.md) | Enforce usage of `onBlur` over `onChange` on select menus for accessibility. | | | ❌ |
|
||||
| [no-redundant-roles](docs/rules/no-redundant-roles.md) | Enforce explicit role property is not the same as implicit/default role property on element. | ☑️ 🔒 | | |
|
||||
| [no-static-element-interactions](docs/rules/no-static-element-interactions.md) | Enforce that non-interactive, visible elements (such as `<div>`) that have click handlers use the role attribute. | ☑️ 🔒 | | |
|
||||
| [prefer-tag-over-role](docs/rules/prefer-tag-over-role.md) | Enforces using semantic DOM elements over the ARIA `role` property. | | | |
|
||||
| [role-has-required-aria-props](docs/rules/role-has-required-aria-props.md) | Enforce that elements with ARIA roles must have all required attributes for that role. | ☑️ 🔒 | | |
|
||||
| [role-supports-aria-props](docs/rules/role-supports-aria-props.md) | Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`. | ☑️ 🔒 | | |
|
||||
| [scope](docs/rules/scope.md) | Enforce `scope` prop is only used on `<th>` elements. | ☑️ 🔒 | | |
|
||||
| [tabindex-no-positive](docs/rules/tabindex-no-positive.md) | Enforce `tabIndex` value is not greater than zero. | ☑️ 🔒 | | |
|
||||
|
||||
<!-- end auto-generated rules list -->
|
||||
|
||||
|
|
|
|||
25
node_modules/eslint-plugin-jsx-a11y/__mocks__/genInteractives.js
generated
vendored
25
node_modules/eslint-plugin-jsx-a11y/__mocks__/genInteractives.js
generated
vendored
|
|
@ -12,8 +12,8 @@ import JSXElementMock from './JSXElementMock';
|
|||
import type { JSXAttributeMockType } from './JSXAttributeMock';
|
||||
import type { JSXElementMockType } from './JSXElementMock';
|
||||
|
||||
const domElements = [...dom.keys()];
|
||||
const roleNames = [...roles.keys()];
|
||||
const domElements = dom.keys();
|
||||
const roleNames = roles.keys();
|
||||
|
||||
const interactiveElementsMap = {
|
||||
a: [{ prop: 'href', value: '#' }],
|
||||
|
|
@ -45,7 +45,6 @@ const interactiveElementsMap = {
|
|||
'input[type="time"]': [{ prop: 'type', value: 'time' }],
|
||||
'input[type="url"]': [{ prop: 'type', value: 'url' }],
|
||||
'input[type="week"]': [{ prop: 'type', value: 'week' }],
|
||||
link: [{ prop: 'href', value: '#' }],
|
||||
menuitem: [],
|
||||
option: [],
|
||||
select: [],
|
||||
|
|
@ -53,7 +52,7 @@ const interactiveElementsMap = {
|
|||
// Whereas ARIA makes a distinction between cell and gridcell, the AXObject
|
||||
// treats them both as CellRole and since gridcell is interactive, we consider
|
||||
// cell interactive as well.
|
||||
// td: [],
|
||||
td: [],
|
||||
th: [],
|
||||
tr: [],
|
||||
textarea: [],
|
||||
|
|
@ -62,25 +61,27 @@ const interactiveElementsMap = {
|
|||
|
||||
const nonInteractiveElementsMap: {[string]: Array<{[string]: string}>} = {
|
||||
abbr: [],
|
||||
aside: [],
|
||||
address: [],
|
||||
article: [],
|
||||
aside: [],
|
||||
blockquote: [],
|
||||
body: [],
|
||||
br: [],
|
||||
caption: [],
|
||||
code: [],
|
||||
dd: [],
|
||||
del: [],
|
||||
details: [],
|
||||
dfn: [],
|
||||
dialog: [],
|
||||
dir: [],
|
||||
dl: [],
|
||||
dt: [],
|
||||
em: [],
|
||||
fieldset: [],
|
||||
figcaption: [],
|
||||
figure: [],
|
||||
footer: [],
|
||||
form: [],
|
||||
frame: [],
|
||||
h1: [],
|
||||
h2: [],
|
||||
h3: [],
|
||||
|
|
@ -88,8 +89,10 @@ const nonInteractiveElementsMap: {[string]: Array<{[string]: string}>} = {
|
|||
h5: [],
|
||||
h6: [],
|
||||
hr: [],
|
||||
html: [],
|
||||
iframe: [],
|
||||
img: [],
|
||||
ins: [],
|
||||
label: [],
|
||||
legend: [],
|
||||
li: [],
|
||||
|
|
@ -108,20 +111,22 @@ const nonInteractiveElementsMap: {[string]: Array<{[string]: string}>} = {
|
|||
ruby: [],
|
||||
'section[aria-label]': [{ prop: 'aria-label' }],
|
||||
'section[aria-labelledby]': [{ prop: 'aria-labelledby' }],
|
||||
strong: [],
|
||||
sub: [],
|
||||
sup: [],
|
||||
table: [],
|
||||
tbody: [],
|
||||
td: [],
|
||||
tfoot: [],
|
||||
thead: [],
|
||||
time: [],
|
||||
ul: [],
|
||||
};
|
||||
|
||||
const indeterminantInteractiveElementsMap: { [key: string]: Array<any> } = fromEntries(domElements.map((name: string) => [name, []]));
|
||||
const indeterminantInteractiveElementsMap: { [key: string]: Array<any> } = fromEntries(domElements.map((name) => [name, []]));
|
||||
|
||||
Object.keys(interactiveElementsMap)
|
||||
.concat(Object.keys(nonInteractiveElementsMap))
|
||||
.forEach((name: string) => delete indeterminantInteractiveElementsMap[name]);
|
||||
.forEach((name) => delete indeterminantInteractiveElementsMap[name]);
|
||||
|
||||
const abstractRoles = roleNames.filter((role) => roles.get(role).abstract);
|
||||
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/__util__/helpers/getESLintCoreRule.js
generated
vendored
Normal file
9
node_modules/eslint-plugin-jsx-a11y/__tests__/__util__/helpers/getESLintCoreRule.js
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { version } from 'eslint/package.json';
|
||||
import semver from 'semver';
|
||||
|
||||
const isESLintV8 = semver.major(version) >= 8;
|
||||
|
||||
// eslint-disable-next-line global-require, import/no-dynamic-require, import/no-unresolved
|
||||
const getESLintCoreRule = (ruleId) => (isESLintV8 ? require('eslint/use-at-your-own-risk').builtinRules.get(ruleId) : require(`eslint/lib/rules/${ruleId}`));
|
||||
|
||||
export default getESLintCoreRule;
|
||||
186
node_modules/eslint-plugin-jsx-a11y/__tests__/__util__/helpers/parsers.js
generated
vendored
Normal file
186
node_modules/eslint-plugin-jsx-a11y/__tests__/__util__/helpers/parsers.js
generated
vendored
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
import entries from 'object.entries';
|
||||
import { version } from 'eslint/package.json';
|
||||
import flatMap from 'array.prototype.flatmap';
|
||||
|
||||
let tsParserVersion;
|
||||
try {
|
||||
// eslint-disable-next-line import/no-unresolved, global-require
|
||||
tsParserVersion = require('@typescript-eslint/parser/package.json').version;
|
||||
} catch (e) { /**/ }
|
||||
|
||||
const disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is not useful on v4.1+ of the TS parser
|
||||
? (x) => ({ ...x, features: [].concat(x.features, 'no-ts-new') })
|
||||
: (x) => x;
|
||||
|
||||
function minEcmaVersion(features, parserOptions) {
|
||||
const minEcmaVersionForFeatures = {
|
||||
'class fields': 2022,
|
||||
'optional chaining': 2020,
|
||||
'nullish coalescing': 2020,
|
||||
};
|
||||
const result = Math.max(
|
||||
...[].concat(
|
||||
(parserOptions && parserOptions.ecmaVersion) || [],
|
||||
flatMap(entries(minEcmaVersionForFeatures), (entry) => {
|
||||
const f = entry[0];
|
||||
const y = entry[1];
|
||||
return features.has(f) ? y : [];
|
||||
}),
|
||||
).map((y) => (y > 5 && y < 2015 ? y + 2009 : y)), // normalize editions to years
|
||||
);
|
||||
return Number.isFinite(result) ? result : undefined;
|
||||
}
|
||||
|
||||
const NODE_MODULES = '../../node_modules';
|
||||
|
||||
const parsers = {
|
||||
BABEL_ESLINT: path.join(__dirname, NODE_MODULES, 'babel-eslint'),
|
||||
'@BABEL_ESLINT': path.join(__dirname, NODE_MODULES, '@babel/eslint-parser'),
|
||||
TYPESCRIPT_ESLINT: path.join(__dirname, NODE_MODULES, 'typescript-eslint-parser'),
|
||||
'@TYPESCRIPT_ESLINT': path.join(__dirname, NODE_MODULES, '@typescript-eslint/parser'),
|
||||
disableNewTS,
|
||||
babelParserOptions: function parserOptions(test, features) {
|
||||
return {
|
||||
...test.parserOptions,
|
||||
requireConfigFile: false,
|
||||
babelOptions: {
|
||||
presets: [
|
||||
'@babel/preset-react',
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-syntax-do-expressions',
|
||||
'@babel/plugin-syntax-function-bind',
|
||||
['@babel/plugin-syntax-decorators', { legacy: true }],
|
||||
],
|
||||
parserOpts: {
|
||||
allowSuperOutsideMethod: false,
|
||||
allowReturnOutsideFunction: false,
|
||||
},
|
||||
},
|
||||
ecmaFeatures: {
|
||||
|
||||
...test.parserOptions && test.parserOptions.ecmaFeatures,
|
||||
jsx: true,
|
||||
modules: true,
|
||||
legacyDecorators: features.has('decorators'),
|
||||
},
|
||||
};
|
||||
},
|
||||
all: function all(tests) {
|
||||
const t = flatMap(tests, (test) => {
|
||||
/* eslint no-param-reassign: 0 */
|
||||
if (typeof test === 'string') {
|
||||
test = { code: test };
|
||||
}
|
||||
if ('parser' in test) {
|
||||
delete test.features;
|
||||
return test;
|
||||
}
|
||||
const features = new Set([].concat(test.features || []));
|
||||
delete test.features;
|
||||
|
||||
const es = minEcmaVersion(features, test.parserOptions);
|
||||
|
||||
function addComment(testObject, parser) {
|
||||
const extras = [].concat(
|
||||
`features: [${Array.from(features).join(',')}]`,
|
||||
`parser: ${parser}`,
|
||||
testObject.parserOptions ? `parserOptions: ${JSON.stringify(testObject.parserOptions)}` : [],
|
||||
testObject.options ? `options: ${JSON.stringify(testObject.options)}` : [],
|
||||
testObject.settings ? `settings: ${JSON.stringify(testObject.settings)}` : [],
|
||||
);
|
||||
|
||||
const extraComment = `\n// ${extras.join(', ')}`;
|
||||
|
||||
// Augment expected fix code output with extraComment
|
||||
const nextCode = { code: testObject.code + extraComment };
|
||||
const nextOutput = testObject.output && { output: testObject.output + extraComment };
|
||||
|
||||
// Augment expected suggestion outputs with extraComment
|
||||
// `errors` may be a number (expected number of errors) or an array of
|
||||
// error objects.
|
||||
const nextErrors = testObject.errors
|
||||
&& typeof testObject.errors !== 'number'
|
||||
&& {
|
||||
errors: testObject.errors.map(
|
||||
(errorObject) => {
|
||||
const nextSuggestions = errorObject.suggestions && {
|
||||
suggestions: errorObject.suggestions.map((suggestion) => ({ ...suggestion, output: suggestion.output + extraComment })),
|
||||
};
|
||||
|
||||
return { ...errorObject, ...nextSuggestions };
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
...testObject,
|
||||
...nextCode,
|
||||
...nextOutput,
|
||||
...nextErrors,
|
||||
};
|
||||
}
|
||||
|
||||
const skipBase = (features.has('class fields') && semver.satisfies(version, '< 8'))
|
||||
|| (es >= 2020 && semver.satisfies(version, '< 6'))
|
||||
|| features.has('no-default')
|
||||
|| features.has('bind operator')
|
||||
|| features.has('do expressions')
|
||||
|| features.has('decorators')
|
||||
|| features.has('flow')
|
||||
|| features.has('ts')
|
||||
|| features.has('types')
|
||||
|| (features.has('fragment') && semver.satisfies(version, '< 5'));
|
||||
|
||||
const skipBabel = features.has('no-babel');
|
||||
const skipOldBabel = skipBabel
|
||||
|| features.has('no-babel-old')
|
||||
|| features.has('optional chaining')
|
||||
|| semver.satisfies(version, '>= 8');
|
||||
const skipNewBabel = skipBabel
|
||||
|| features.has('no-babel-new')
|
||||
|| !semver.satisfies(version, '^7.5.0') // require('@babel/eslint-parser/package.json').peerDependencies.eslint
|
||||
|| features.has('flow')
|
||||
|| features.has('types')
|
||||
|| features.has('ts');
|
||||
const skipTS = semver.satisfies(version, '<= 5') // TODO: make these pass on eslint 5
|
||||
|| features.has('no-ts')
|
||||
|| features.has('flow')
|
||||
|| features.has('jsx namespace')
|
||||
|| features.has('bind operator')
|
||||
|| features.has('do expressions');
|
||||
const tsOld = !skipTS && !features.has('no-ts-old');
|
||||
const tsNew = !skipTS && !features.has('no-ts-new');
|
||||
|
||||
return [].concat(
|
||||
skipBase ? [] : addComment(
|
||||
{
|
||||
...test,
|
||||
...typeof es === 'number' && {
|
||||
parserOptions: { ...test.parserOptions, ecmaVersion: es },
|
||||
},
|
||||
},
|
||||
'default',
|
||||
),
|
||||
skipOldBabel ? [] : addComment({
|
||||
...test,
|
||||
parser: parsers.BABEL_ESLINT,
|
||||
parserOptions: parsers.babelParserOptions(test, features),
|
||||
}, 'babel-eslint'),
|
||||
skipNewBabel ? [] : addComment({
|
||||
...test,
|
||||
parser: parsers['@BABEL_ESLINT'],
|
||||
parserOptions: parsers.babelParserOptions(test, features),
|
||||
}, '@babel/eslint-parser'),
|
||||
tsOld ? addComment({ ...test, parser: parsers.TYPESCRIPT_ESLINT }, 'typescript-eslint') : [],
|
||||
tsNew ? addComment({ ...test, parser: parsers['@TYPESCRIPT_ESLINT'] }, '@typescript-eslint/parser') : [],
|
||||
);
|
||||
});
|
||||
return t;
|
||||
},
|
||||
};
|
||||
|
||||
export default parsers;
|
||||
53
node_modules/eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper.js
generated
vendored
53
node_modules/eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper.js
generated
vendored
|
|
@ -1,26 +1,53 @@
|
|||
import { version as eslintVersion } from 'eslint/package.json';
|
||||
import semver from 'semver';
|
||||
|
||||
const usingLegacy = semver.major(eslintVersion) < 9;
|
||||
|
||||
const defaultParserOptions = {
|
||||
ecmaVersion: 2018,
|
||||
ecmaFeatures: {
|
||||
experimentalObjectRestSpread: true,
|
||||
jsx: true,
|
||||
},
|
||||
};
|
||||
|
||||
const defaultLegacyParserOptions = {
|
||||
...defaultParserOptions,
|
||||
ecmaVersion: 2018,
|
||||
};
|
||||
|
||||
const defaultLanguageOptions = {
|
||||
ecmaVersion: 'latest',
|
||||
parserOptions: {
|
||||
...defaultParserOptions,
|
||||
},
|
||||
};
|
||||
|
||||
export default function parserOptionsMapper({
|
||||
code,
|
||||
errors,
|
||||
options = [],
|
||||
parserOptions = {},
|
||||
settings,
|
||||
languageOptions = {},
|
||||
settings = {},
|
||||
}) {
|
||||
return {
|
||||
code,
|
||||
errors,
|
||||
options,
|
||||
parserOptions: {
|
||||
...defaultParserOptions,
|
||||
...parserOptions,
|
||||
},
|
||||
settings,
|
||||
};
|
||||
return usingLegacy
|
||||
? {
|
||||
code,
|
||||
errors,
|
||||
options,
|
||||
parserOptions: {
|
||||
...defaultLegacyParserOptions,
|
||||
...languageOptions,
|
||||
},
|
||||
settings,
|
||||
}
|
||||
: {
|
||||
code,
|
||||
errors,
|
||||
options,
|
||||
languageOptions: {
|
||||
...defaultLanguageOptions,
|
||||
...languageOptions,
|
||||
},
|
||||
settings,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
39
node_modules/eslint-plugin-jsx-a11y/__tests__/index-test.js
generated
vendored
39
node_modules/eslint-plugin-jsx-a11y/__tests__/index-test.js
generated
vendored
|
|
@ -2,36 +2,39 @@
|
|||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import plugin from '../src';
|
||||
|
||||
const rules = fs.readdirSync(path.resolve(__dirname, '../src/rules/'))
|
||||
.map((f) => path.basename(f, '.js'));
|
||||
|
||||
describe('all rule files should be exported by the plugin', () => {
|
||||
test('all rule files should be exported by the plugin', (t) => {
|
||||
rules.forEach((ruleName) => {
|
||||
it(`should export ${ruleName}`, () => {
|
||||
expect(plugin.rules[ruleName]).toEqual(
|
||||
require(path.join('../src/rules', ruleName)) // eslint-disable-line
|
||||
);
|
||||
});
|
||||
t.equal(
|
||||
plugin.rules[ruleName],
|
||||
require(path.join('../src/rules', ruleName)), // eslint-disable-line import/no-dynamic-require
|
||||
`exports ${ruleName}`,
|
||||
);
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
describe('configurations', () => {
|
||||
it('should export a \'recommended\' configuration', () => {
|
||||
expect(plugin.configs.recommended).toBeDefined();
|
||||
});
|
||||
test('configurations', (t) => {
|
||||
t.notEqual(plugin.configs.recommended, undefined, 'exports a \'recommended\' configuration');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
describe('schemas', () => {
|
||||
test('schemas', (t) => {
|
||||
rules.forEach((ruleName) => {
|
||||
it(`${ruleName} should export a schema with type object`, () => {
|
||||
const rule = require(path.join('../src/rules', ruleName)); // eslint-disable-line
|
||||
const schema = rule.meta && rule.meta.schema && rule.meta.schema[0];
|
||||
const { type } = schema;
|
||||
const rule = require(path.join('../src/rules', ruleName)); // eslint-disable-line import/no-dynamic-require
|
||||
const schema = rule.meta && rule.meta.schema && rule.meta.schema[0];
|
||||
const { type } = schema;
|
||||
|
||||
expect(type).toEqual('object');
|
||||
});
|
||||
t.equal(type, 'object', `${ruleName} exports a schema with type object`);
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
18
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test.js
generated
vendored
18
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test.js
generated
vendored
|
|
@ -10,6 +10,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import rule from '../../../src/rules/accessible-emoji';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Tests
|
||||
|
|
@ -23,7 +24,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('accessible-emoji', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<span />' },
|
||||
{ code: '<span>No emoji here!</span>' },
|
||||
|
|
@ -42,8 +43,12 @@ ruleTester.run('accessible-emoji', rule, {
|
|||
code: '<CustomInput type="hidden">🐼</CustomInput>',
|
||||
settings: { 'jsx-a11y': { components: { CustomInput: 'input' } } },
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
{
|
||||
code: '<Box as="input" type="hidden">🐼</Box>',
|
||||
settings: { 'jsx-a11y': { polymorphicPropName: 'as' } },
|
||||
},
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<span>🐼</span>', errors: [expectedError] },
|
||||
{ code: '<span>foo🐼bar</span>', errors: [expectedError] },
|
||||
{ code: '<span>foo 🐼 bar</span>', errors: [expectedError] },
|
||||
|
|
@ -52,5 +57,10 @@ ruleTester.run('accessible-emoji', rule, {
|
|||
{ code: '<Foo>🐼</Foo>', errors: [expectedError] },
|
||||
{ code: '<span aria-hidden="false">🐼</span>', errors: [expectedError] },
|
||||
{ code: '<CustomInput type="hidden">🐼</CustomInput>', errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
{
|
||||
code: '<Box as="span">🐼</Box>',
|
||||
settings: { 'jsx-a11y': { polymorphicPropName: 'as' } },
|
||||
errors: [expectedError],
|
||||
},
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
32
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/alt-text-test.js
generated
vendored
32
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/alt-text-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/alt-text';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -28,22 +29,33 @@ Use alt="" for presentational images.`,
|
|||
type: 'JSXOpeningElement',
|
||||
});
|
||||
|
||||
const ariaLabelValueError = 'The aria-label attribute must have a value. The alt attribute is preferred over aria-label for images.';
|
||||
const ariaLabelledbyValueError = 'The aria-labelledby attribute must have a value. The alt attribute is preferred over aria-labelledby for images.';
|
||||
const ariaLabelValueError = {
|
||||
message: 'The aria-label attribute must have a value. The alt attribute is preferred over aria-label for images.',
|
||||
};
|
||||
const ariaLabelledbyValueError = {
|
||||
message: 'The aria-labelledby attribute must have a value. The alt attribute is preferred over aria-labelledby for images.',
|
||||
};
|
||||
|
||||
const preferAltError = () => ({
|
||||
message: 'Prefer alt="" over a presentational role. First rule of aria is to not use aria if it can be achieved via native HTML.',
|
||||
type: 'JSXOpeningElement',
|
||||
});
|
||||
|
||||
const objectError = 'Embedded <object> elements must have alternative text by providing inner text, aria-label or aria-labelledby props.';
|
||||
const objectError = {
|
||||
message: 'Embedded <object> elements must have alternative text by providing inner text, aria-label or aria-labelledby props.',
|
||||
};
|
||||
|
||||
const areaError = 'Each area of an image map must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.';
|
||||
const areaError = {
|
||||
message: 'Each area of an image map must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.',
|
||||
};
|
||||
|
||||
const inputImageError = '<input> elements with type="image" must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.';
|
||||
const inputImageError = {
|
||||
message: '<input> elements with type="image" must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.',
|
||||
};
|
||||
|
||||
const componentsSettings = {
|
||||
'jsx-a11y': {
|
||||
polymorphicPropName: 'as',
|
||||
components: {
|
||||
Input: 'input',
|
||||
},
|
||||
|
|
@ -58,7 +70,7 @@ const array = [{
|
|||
}];
|
||||
|
||||
ruleTester.run('alt-text', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT 'img' TESTS
|
||||
{ code: '<img alt="foo" />;' },
|
||||
{ code: '<img alt={"foo"} />;' },
|
||||
|
|
@ -121,6 +133,7 @@ ruleTester.run('alt-text', rule, {
|
|||
{ code: '<input type="image" alt={altText} />' },
|
||||
{ code: '<InputImage />' },
|
||||
{ code: '<Input type="image" alt="" />', settings: componentsSettings },
|
||||
{ code: '<SomeComponent as="input" type="image" alt="" />', settings: componentsSettings },
|
||||
|
||||
// CUSTOM ELEMENT TESTS FOR ARRAY OPTION TESTS
|
||||
{ code: '<Thumbnail alt="foo" />;', options: array },
|
||||
|
|
@ -166,8 +179,8 @@ ruleTester.run('alt-text', rule, {
|
|||
{ code: '<InputImage alt="" />', options: array },
|
||||
{ code: '<InputImage alt="This is descriptive!" />', options: array },
|
||||
{ code: '<InputImage alt={altText} />', options: array },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT 'img' TESTS
|
||||
{ code: '<img />;', errors: [missingPropError('img')] },
|
||||
{ code: '<img alt />;', errors: [altValueError('img')] },
|
||||
|
|
@ -184,6 +197,7 @@ ruleTester.run('alt-text', rule, {
|
|||
{ code: '<img aria-labelledby={undefined} />', errors: [ariaLabelledbyValueError] },
|
||||
{ code: '<img aria-label="" />', errors: [ariaLabelValueError] },
|
||||
{ code: '<img aria-labelledby="" />', errors: [ariaLabelledbyValueError] },
|
||||
{ code: '<SomeComponent as="img" aria-label="" />', settings: componentsSettings, errors: [ariaLabelValueError] },
|
||||
|
||||
// DEFAULT ELEMENT 'object' TESTS
|
||||
{ code: '<object />', errors: [objectError] },
|
||||
|
|
@ -273,5 +287,5 @@ ruleTester.run('alt-text', rule, {
|
|||
{ code: '<InputImage>Foo</InputImage>', errors: [inputImageError], options: array },
|
||||
{ code: '<InputImage {...this.props} />', errors: [inputImageError], options: array },
|
||||
{ code: '<Input type="image" />', errors: [inputImageError], settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
12
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-ambiguous-text-test.js
generated
vendored
12
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-ambiguous-text-test.js
generated
vendored
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-env jest */
|
||||
/**
|
||||
* @fileoverview Enforce `<a>` text to not exactly match "click here", "here", "link", or "a link".
|
||||
* @author Matt Wang
|
||||
|
|
@ -10,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/anchor-ambiguous-text';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -27,14 +27,14 @@ const DEFAULT_AMBIGUOUS_WORDS = [
|
|||
];
|
||||
|
||||
const expectedErrorGenerator = (words) => ({
|
||||
message: `Ambiguous text within anchor. Screenreader users rely on link text for context; the words "${words.join('", "')}" are ambiguous and do not provide enough context.`,
|
||||
message: `Ambiguous text within anchor. Screen reader users rely on link text for context; the words "${words.join('", "')}" are ambiguous and do not provide enough context.`,
|
||||
type: 'JSXOpeningElement',
|
||||
});
|
||||
|
||||
const expectedError = expectedErrorGenerator(DEFAULT_AMBIGUOUS_WORDS);
|
||||
|
||||
ruleTester.run('anchor-ambiguous-text', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<a>documentation</a>;' },
|
||||
{ code: '<a>${here}</a>;' },
|
||||
{ code: '<a aria-label="tutorial on using eslint-plugin-jsx-a11y">click here</a>;' },
|
||||
|
|
@ -69,8 +69,8 @@ ruleTester.run('anchor-ambiguous-text', rule, {
|
|||
}],
|
||||
settings: { 'jsx-a11y': { components: { Link: 'a' } } },
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<a>here</a>;', errors: [expectedError] },
|
||||
{ code: '<a>HERE</a>;', errors: [expectedError] },
|
||||
{ code: '<a>click here</a>;', errors: [expectedError] },
|
||||
|
|
@ -113,5 +113,5 @@ ruleTester.run('anchor-ambiguous-text', rule, {
|
|||
words: ['a disallowed word'],
|
||||
}],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
12
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test.js
generated
vendored
12
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/anchor-has-content';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -23,7 +24,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('anchor-has-content', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<a>Foo</a>' },
|
||||
{ code: '<a><Bar /></a>' },
|
||||
|
|
@ -36,8 +37,11 @@ ruleTester.run('anchor-has-content', rule, {
|
|||
code: '<Link>foo</Link>',
|
||||
settings: { 'jsx-a11y': { components: { Link: 'a' } } },
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
{ code: '<a title={title} />' },
|
||||
{ code: '<a aria-label={ariaLabel} />' },
|
||||
{ code: '<a title={title} aria-label={ariaLabel} />' },
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<a />', errors: [expectedError] },
|
||||
{ code: '<a><Bar aria-hidden /></a>', errors: [expectedError] },
|
||||
{ code: '<a>{undefined}</a>', errors: [expectedError] },
|
||||
|
|
@ -46,5 +50,5 @@ ruleTester.run('anchor-has-content', rule, {
|
|||
errors: [expectedError],
|
||||
settings: { 'jsx-a11y': { components: { Link: 'a' } } },
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
152
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-is-valid-test.js
generated
vendored
152
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-is-valid-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/anchor-is-valid';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -88,7 +89,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('anchor-is-valid', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT 'a' TESTS
|
||||
{ code: '<Anchor />' },
|
||||
{ code: '<a {...props} />' },
|
||||
|
|
@ -271,16 +272,11 @@ ruleTester.run('anchor-is-valid', rule, {
|
|||
options: noHrefAspect,
|
||||
},
|
||||
|
||||
// CUSTOM COMPONENTS AND SPECIALLINK AND ASPECT
|
||||
// CUSTOM COMPONENTS AND SPECIAL LINK AND ASPECT
|
||||
{ code: '<Anchor hrefLeft={undefined} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
|
||||
{ code: '<Anchor hrefLeft={null} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
|
||||
{ code: '<Anchor hrefLeft={undefined} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
|
||||
{ code: '<Anchor hrefLeft={null} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
|
||||
{ code: '<Anchor hrefLeft={undefined} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
|
||||
{ code: '<Anchor hrefLeft={null} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
|
||||
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT 'a' TESTS
|
||||
// NO HREF
|
||||
{ code: '<a />', errors: [noHrefexpectedError] },
|
||||
|
|
@ -288,8 +284,8 @@ ruleTester.run('anchor-is-valid', rule, {
|
|||
{ code: '<a href={null} />', errors: [noHrefexpectedError] },
|
||||
// INVALID HREF
|
||||
{ code: '<a href="" />;', errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="#" />', errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href={"#"} />', errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="#" />', errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href={"#"} />', errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="javascript:void(0)" />', errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href={"javascript:void(0)"} />', errors: [invalidHrefexpectedError] },
|
||||
// SHOULD BE BUTTON
|
||||
|
|
@ -308,13 +304,13 @@ ruleTester.run('anchor-is-valid', rule, {
|
|||
{ code: '<Link href={null} />', errors: [noHrefexpectedError], options: components },
|
||||
// INVALID HREF
|
||||
{ code: '<Link href="" />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Link href="#" />', errors: [invalidHrefErrorMessage], options: components },
|
||||
{ code: '<Link href={"#"} />', errors: [invalidHrefErrorMessage], options: components },
|
||||
{ code: '<Link href="#" />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Link href={"#"} />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Link href="javascript:void(0)" />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Link href={"javascript:void(0)"} />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Anchor href="" />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Anchor href="#" />', errors: [invalidHrefErrorMessage], options: components },
|
||||
{ code: '<Anchor href={"#"} />', errors: [invalidHrefErrorMessage], options: components },
|
||||
{ code: '<Anchor href="#" />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Anchor href={"#"} />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Anchor href="javascript:void(0)" />', errors: [invalidHrefexpectedError], options: components },
|
||||
{ code: '<Anchor href={"javascript:void(0)"} />', errors: [invalidHrefexpectedError], options: components },
|
||||
// SHOULD BE BUTTON
|
||||
|
|
@ -354,8 +350,8 @@ ruleTester.run('anchor-is-valid', rule, {
|
|||
{ code: '<a hrefLeft={null} />', errors: [noHrefexpectedError], options: specialLink },
|
||||
// INVALID HREF
|
||||
{ code: '<a hrefLeft="" />;', errors: [invalidHrefexpectedError], options: specialLink },
|
||||
{ code: '<a hrefLeft="#" />', errors: [invalidHrefErrorMessage], options: specialLink },
|
||||
{ code: '<a hrefLeft={"#"} />', errors: [invalidHrefErrorMessage], options: specialLink },
|
||||
{ code: '<a hrefLeft="#" />', errors: [invalidHrefexpectedError], options: specialLink },
|
||||
{ code: '<a hrefLeft={"#"} />', errors: [invalidHrefexpectedError], options: specialLink },
|
||||
{ code: '<a hrefLeft="javascript:void(0)" />', errors: [invalidHrefexpectedError], options: specialLink },
|
||||
{ code: '<a hrefLeft={"javascript:void(0)"} />', errors: [invalidHrefexpectedError], options: specialLink },
|
||||
// SHOULD BE BUTTON
|
||||
|
|
@ -371,14 +367,14 @@ ruleTester.run('anchor-is-valid', rule, {
|
|||
options: specialLink,
|
||||
},
|
||||
|
||||
// CUSTOM BOTH COMPONENTS AND SPECIALLINK TESTS
|
||||
// CUSTOM BOTH COMPONENTS AND SPECIAL LINK TESTS
|
||||
// NO HREF
|
||||
{ code: '<Anchor Anchor={undefined} />', errors: [noHrefexpectedError], options: componentsAndSpecialLink },
|
||||
{ code: '<Anchor hrefLeft={null} />', errors: [noHrefexpectedError], options: componentsAndSpecialLink },
|
||||
// INVALID HREF
|
||||
{ code: '<Anchor hrefLeft="" />;', errors: [invalidHrefexpectedError], options: componentsAndSpecialLink },
|
||||
{ code: '<Anchor hrefLeft="#" />', errors: [invalidHrefErrorMessage], options: componentsAndSpecialLink },
|
||||
{ code: '<Anchor hrefLeft={"#"} />', errors: [invalidHrefErrorMessage], options: componentsAndSpecialLink },
|
||||
{ code: '<Anchor hrefLeft="#" />', errors: [invalidHrefexpectedError], options: componentsAndSpecialLink },
|
||||
{ code: '<Anchor hrefLeft={"#"} />', errors: [invalidHrefexpectedError], options: componentsAndSpecialLink },
|
||||
{
|
||||
code: '<Anchor hrefLeft="javascript:void(0)" />',
|
||||
errors: [invalidHrefexpectedError],
|
||||
|
|
@ -408,149 +404,129 @@ ruleTester.run('anchor-is-valid', rule, {
|
|||
|
||||
// WITH ASPECTS TESTS
|
||||
// NO HREF
|
||||
{ code: '<a />', options: noHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a />', options: noHrefPreferButtonAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a />', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a href={undefined} />', options: noHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a href={undefined} />', options: noHrefPreferButtonAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a href={undefined} />', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a href={null} />', options: noHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a href={null} />', options: noHrefPreferButtonAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a href={null} />', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a />', options: noHrefAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a />', options: noHrefPreferButtonAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a />', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a href={undefined} />', options: noHrefAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a href={undefined} />', options: noHrefPreferButtonAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a href={undefined} />', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a href={null} />', options: noHrefAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a href={null} />', options: noHrefPreferButtonAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a href={null} />', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
|
||||
|
||||
// INVALID HREF
|
||||
{ code: '<a href="" />;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="" />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="" />;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="#" />;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="#" />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="#" />;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href={"#"} />;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href={"#"} />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href={"#"} />;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="javascript:void(0)" />;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="javascript:void(0)" />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="" />;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="" />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="" />;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="#" />;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="#" />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="#" />;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href={"#"} />;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href={"#"} />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href={"#"} />;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="javascript:void(0)" />;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href="javascript:void(0)" />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{
|
||||
code: '<a href="javascript:void(0)" />;',
|
||||
options: preferButtonInvalidHrefAspect,
|
||||
errors: [invalidHrefErrorMessage],
|
||||
errors: [invalidHrefexpectedError],
|
||||
},
|
||||
{ code: '<a href={"javascript:void(0)"} />;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href={"javascript:void(0)"} />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href={"javascript:void(0)"} />;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{ code: '<a href={"javascript:void(0)"} />;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{
|
||||
code: '<a href={"javascript:void(0)"} />;',
|
||||
options: preferButtonInvalidHrefAspect,
|
||||
errors: [invalidHrefErrorMessage],
|
||||
errors: [invalidHrefexpectedError],
|
||||
},
|
||||
|
||||
// SHOULD BE BUTTON
|
||||
{ code: '<a onClick={() => void 0} />', options: preferButtonAspect, errors: [preferButtonErrorMessage] },
|
||||
{ code: '<a onClick={() => void 0} />', options: preferButtonAspect, errors: [preferButtonexpectedError] },
|
||||
{
|
||||
code: '<a onClick={() => void 0} />',
|
||||
options: preferButtonInvalidHrefAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{ code: '<a onClick={() => void 0} />', options: noHrefPreferButtonAspect, errors: [preferButtonErrorMessage] },
|
||||
{ code: '<a onClick={() => void 0} />', options: noHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a onClick={() => void 0} />', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
|
||||
{ code: '<a href="#" onClick={() => void 0} />', options: preferButtonAspect, errors: [preferButtonErrorMessage] },
|
||||
{ code: '<a onClick={() => void 0} />', options: noHrefPreferButtonAspect, errors: [preferButtonexpectedError] },
|
||||
{ code: '<a onClick={() => void 0} />', options: noHrefAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a onClick={() => void 0} />', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
|
||||
{ code: '<a href="#" onClick={() => void 0} />', options: preferButtonAspect, errors: [preferButtonexpectedError] },
|
||||
{
|
||||
code: '<a href="#" onClick={() => void 0} />',
|
||||
options: noHrefPreferButtonAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href="#" onClick={() => void 0} />',
|
||||
options: preferButtonInvalidHrefAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{ code: '<a href="#" onClick={() => void 0} />', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
|
||||
{ code: '<a href="#" onClick={() => void 0} />', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
|
||||
{
|
||||
code: '<a href="#" onClick={() => void 0} />',
|
||||
options: noHrefInvalidHrefAspect,
|
||||
errors: [invalidHrefErrorMessage],
|
||||
errors: [invalidHrefexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href="javascript:void(0)" onClick={() => void 0} />',
|
||||
options: preferButtonAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href="javascript:void(0)" onClick={() => void 0} />',
|
||||
options: noHrefPreferButtonAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href="javascript:void(0)" onClick={() => void 0} />',
|
||||
options: preferButtonInvalidHrefAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href="javascript:void(0)" onClick={() => void 0} />',
|
||||
options: invalidHrefAspect,
|
||||
errors: [invalidHrefErrorMessage],
|
||||
errors: [invalidHrefexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href="javascript:void(0)" onClick={() => void 0} />',
|
||||
options: noHrefInvalidHrefAspect,
|
||||
errors: [invalidHrefErrorMessage],
|
||||
errors: [invalidHrefexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href={"javascript:void(0)"} onClick={() => void 0} />',
|
||||
options: preferButtonAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href={"javascript:void(0)"} onClick={() => void 0} />',
|
||||
options: noHrefPreferButtonAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href={"javascript:void(0)"} onClick={() => void 0} />',
|
||||
options: preferButtonInvalidHrefAspect,
|
||||
errors: [preferButtonErrorMessage],
|
||||
errors: [preferButtonexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href={"javascript:void(0)"} onClick={() => void 0} />',
|
||||
options: invalidHrefAspect,
|
||||
errors: [invalidHrefErrorMessage],
|
||||
errors: [invalidHrefexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<a href={"javascript:void(0)"} onClick={() => void 0} />',
|
||||
options: noHrefInvalidHrefAspect,
|
||||
errors: [invalidHrefErrorMessage],
|
||||
errors: [invalidHrefexpectedError],
|
||||
},
|
||||
|
||||
// CUSTOM COMPONENTS AND SPECIALLINK AND ASPECT
|
||||
// CUSTOM COMPONENTS AND SPECIAL LINK AND ASPECT
|
||||
{
|
||||
code: '<Anchor hrefLeft={undefined} />',
|
||||
options: componentsAndSpecialLinkAndNoHrefAspect,
|
||||
errors: [noHrefErrorMessage],
|
||||
errors: [noHrefexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<Anchor hrefLeft={null} />',
|
||||
options: componentsAndSpecialLinkAndNoHrefAspect,
|
||||
errors: [noHrefErrorMessage],
|
||||
errors: [noHrefexpectedError],
|
||||
},
|
||||
{
|
||||
code: '<Anchor hrefLeft={undefined} />',
|
||||
options: componentsAndSpecialLinkAndNoHrefAspect,
|
||||
errors: [noHrefErrorMessage],
|
||||
},
|
||||
{
|
||||
code: '<Anchor hrefLeft={null} />',
|
||||
options: componentsAndSpecialLinkAndNoHrefAspect,
|
||||
errors: [noHrefErrorMessage],
|
||||
},
|
||||
{
|
||||
code: '<Anchor hrefLeft={undefined} />',
|
||||
options: componentsAndSpecialLinkAndNoHrefAspect,
|
||||
errors: [noHrefErrorMessage],
|
||||
},
|
||||
{
|
||||
code: '<Anchor hrefLeft={null} />',
|
||||
options: componentsAndSpecialLinkAndNoHrefAspect,
|
||||
errors: [noHrefErrorMessage],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/aria-activedescendant-has-tabindex';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -23,7 +24,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('aria-activedescendant-has-tabindex', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{
|
||||
code: '<CustomComponent />;',
|
||||
},
|
||||
|
|
@ -79,8 +80,8 @@ ruleTester.run('aria-activedescendant-has-tabindex', rule, {
|
|||
{
|
||||
code: '<input aria-activedescendant={someID} tabIndex={-1} />;',
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{
|
||||
code: '<div aria-activedescendant={someID} />;',
|
||||
errors: [expectedError],
|
||||
|
|
@ -90,5 +91,5 @@ ruleTester.run('aria-activedescendant-has-tabindex', rule, {
|
|||
errors: [expectedError],
|
||||
settings: { 'jsx-a11y': { components: { CustomComponent: 'div' } } },
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
11
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test.js
generated
vendored
11
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test.js
generated
vendored
|
|
@ -10,6 +10,7 @@
|
|||
import { aria } from 'aria-query';
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/aria-props';
|
||||
import getSuggestion from '../../../src/util/getSuggestion';
|
||||
|
||||
|
|
@ -18,7 +19,7 @@ import getSuggestion from '../../../src/util/getSuggestion';
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
const ariaAttributes = [...aria.keys()];
|
||||
const ariaAttributes = aria.keys();
|
||||
|
||||
const errorMessage = (name) => {
|
||||
const suggestions = getSuggestion(name, ariaAttributes);
|
||||
|
|
@ -43,7 +44,7 @@ const basicValidityTests = ariaAttributes.map((prop) => ({
|
|||
}));
|
||||
|
||||
ruleTester.run('aria-props', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// Variables should pass, as we are only testing literals.
|
||||
{ code: '<div />' },
|
||||
{ code: '<div></div>' },
|
||||
|
|
@ -53,8 +54,8 @@ ruleTester.run('aria-props', rule, {
|
|||
{ code: '<div fooaria-hidden="true"></div>' },
|
||||
{ code: '<Bar baz />' },
|
||||
{ code: '<input type="text" aria-errormessage="foobar" />' },
|
||||
].concat(basicValidityTests).map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).concat(basicValidityTests).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div aria-="foobar" />', errors: [errorMessage('aria-')] },
|
||||
{
|
||||
code: '<div aria-labeledby="foobar" />',
|
||||
|
|
@ -64,5 +65,5 @@ ruleTester.run('aria-props', rule, {
|
|||
code: '<div aria-skldjfaria-klajsd="foobar" />',
|
||||
errors: [errorMessage('aria-skldjfaria-klajsd')],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
43
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test.js
generated
vendored
43
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test.js
generated
vendored
|
|
@ -9,8 +9,10 @@
|
|||
|
||||
import { aria } from 'aria-query';
|
||||
import { RuleTester } from 'eslint';
|
||||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/aria-proptypes';
|
||||
|
||||
const { validityCheck } = rule;
|
||||
|
|
@ -29,36 +31,39 @@ const errorMessage = (name) => {
|
|||
|
||||
switch (type) {
|
||||
case 'tristate':
|
||||
return `The value for ${name} must be a boolean or the string "mixed".`;
|
||||
return { message: `The value for ${name} must be a boolean or the string "mixed".` };
|
||||
case 'token':
|
||||
return `The value for ${name} must be a single token from the following: ${permittedValues}.`;
|
||||
return { message: `The value for ${name} must be a single token from the following: ${permittedValues}.` };
|
||||
case 'tokenlist':
|
||||
return `The value for ${name} must be a list of one or more \
|
||||
tokens from the following: ${permittedValues}.`;
|
||||
return {
|
||||
message: `The value for ${name} must be a list of one or more \
|
||||
tokens from the following: ${permittedValues}.`,
|
||||
};
|
||||
case 'idlist':
|
||||
return `The value for ${name} must be a list of strings that represent DOM element IDs (idlist)`;
|
||||
return { message: `The value for ${name} must be a list of strings that represent DOM element IDs (idlist)` };
|
||||
case 'id':
|
||||
return `The value for ${name} must be a string that represents a DOM element ID`;
|
||||
return { message: `The value for ${name} must be a string that represents a DOM element ID` };
|
||||
case 'boolean':
|
||||
case 'string':
|
||||
case 'integer':
|
||||
case 'number':
|
||||
default:
|
||||
return `The value for ${name} must be a ${type}.`;
|
||||
return { message: `The value for ${name} must be a ${type}.` };
|
||||
}
|
||||
};
|
||||
|
||||
describe('validityCheck', () => {
|
||||
it('should false for an unknown expected type', () => {
|
||||
expect(validityCheck(
|
||||
null,
|
||||
null,
|
||||
)).toBe(false);
|
||||
});
|
||||
test('validityCheck', (t) => {
|
||||
t.equal(
|
||||
validityCheck(null, null),
|
||||
false,
|
||||
'is false for an unknown expected type',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
ruleTester.run('aria-proptypes', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// DON'T TEST INVALID ARIA-* PROPS
|
||||
{ code: '<div aria-foo="true" />' },
|
||||
{ code: '<div abcaria-foo="true" />' },
|
||||
|
|
@ -211,8 +216,8 @@ ruleTester.run('aria-proptypes', rule, {
|
|||
{ code: '<div aria-labelledby={foo.bar} />' },
|
||||
{ code: '<div aria-labelledby={null} />' },
|
||||
{ code: '<div aria-labelledby={undefined} />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
// BOOLEAN
|
||||
{ code: '<div aria-hidden="yes" />', errors: [errorMessage('aria-hidden')] },
|
||||
{ code: '<div aria-hidden="no" />', errors: [errorMessage('aria-hidden')] },
|
||||
|
|
@ -302,5 +307,5 @@ ruleTester.run('aria-proptypes', rule, {
|
|||
code: '<div aria-relevant="additions removalss " />',
|
||||
errors: [errorMessage('aria-relevant')],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
22
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test.js
generated
vendored
22
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test.js
generated
vendored
|
|
@ -10,6 +10,7 @@
|
|||
import { roles } from 'aria-query';
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/aria-role';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -23,7 +24,7 @@ const errorMessage = {
|
|||
type: 'JSXAttribute',
|
||||
};
|
||||
|
||||
const roleKeys = [...roles.keys()];
|
||||
const roleKeys = roles.keys();
|
||||
|
||||
const validRoles = roleKeys.filter((role) => roles.get(role).abstract === false);
|
||||
const invalidRoles = roleKeys.filter((role) => roles.get(role).abstract === true);
|
||||
|
|
@ -49,6 +50,7 @@ const ignoreNonDOMSchema = [{
|
|||
|
||||
const customDivSettings = {
|
||||
'jsx-a11y': {
|
||||
polymorphicPropName: 'asChild',
|
||||
components: {
|
||||
Div: 'div',
|
||||
},
|
||||
|
|
@ -56,7 +58,7 @@ const customDivSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('aria-role', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// Variables should pass, as we are only testing literals.
|
||||
{ code: '<div />' },
|
||||
{ code: '<div></div>' },
|
||||
|
|
@ -79,11 +81,14 @@ ruleTester.run('aria-role', rule, {
|
|||
settings: customDivSettings,
|
||||
},
|
||||
{
|
||||
code: '<svg role="graphics-document document" />',
|
||||
code: '<Box asChild="div" role="button" />',
|
||||
settings: customDivSettings,
|
||||
},
|
||||
].concat(validTests).map(parserOptionsMapper),
|
||||
{ code: '<svg role="graphics-document document" />' },
|
||||
{ code: '<svg role="img" />' },
|
||||
)).concat(validTests).map(parserOptionsMapper),
|
||||
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div role="foobar" />', errors: [errorMessage] },
|
||||
{ code: '<div role="datepicker"></div>', errors: [errorMessage] },
|
||||
{ code: '<div role="range"></div>', errors: [errorMessage] },
|
||||
|
|
@ -104,5 +109,10 @@ ruleTester.run('aria-role', rule, {
|
|||
options: ignoreNonDOMSchema,
|
||||
settings: customDivSettings,
|
||||
},
|
||||
].concat(invalidTests).map(parserOptionsMapper),
|
||||
{
|
||||
code: '<Box asChild="div" role="Button" />',
|
||||
settings: customDivSettings,
|
||||
errors: [errorMessage],
|
||||
},
|
||||
)).concat(invalidTests).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
import { dom } from 'aria-query';
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/aria-unsupported-elements';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -25,7 +26,7 @@ Try removing the prop '${invalidProp}'.`,
|
|||
type: 'JSXOpeningElement',
|
||||
});
|
||||
|
||||
const domElements = [...dom.keys()];
|
||||
const domElements = dom.keys();
|
||||
// Generate valid test cases
|
||||
const roleValidityTests = domElements.map((element) => {
|
||||
const isReserved = dom.get(element).reserved || false;
|
||||
|
|
@ -68,7 +69,7 @@ const invalidAriaValidityTests = domElements
|
|||
}));
|
||||
|
||||
ruleTester.run('aria-unsupported-elements', rule, {
|
||||
valid: roleValidityTests.concat(ariaValidityTests).map(parserOptionsMapper),
|
||||
invalid: invalidRoleValidityTests.concat(invalidAriaValidityTests)
|
||||
valid: parsers.all([].concat(roleValidityTests, ariaValidityTests)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(invalidRoleValidityTests, invalidAriaValidityTests))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/autocomplete-valid-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/autocomplete-valid-test.js
generated
vendored
|
|
@ -10,6 +10,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import { axeFailMessage } from '../../__util__/axeMapping';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/autocomplete-valid';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -37,7 +38,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('autocomplete-valid', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// INAPPLICABLE
|
||||
{ code: '<input type="text" />;' },
|
||||
// // PASSED AUTOCOMPLETE
|
||||
|
|
@ -63,8 +64,8 @@ ruleTester.run('autocomplete-valid', rule, {
|
|||
{ code: '<input type="number" autocomplete="url" />;', errors: inappropriateAutocomplete },
|
||||
{ code: '<input type="month" autocomplete="tel" />;', errors: inappropriateAutocomplete },
|
||||
{ code: '<Foo type="month" autocomplete="tel"></Foo>;', errors: inappropriateAutocomplete, options: [{ inputComponents: ['Foo'] }] },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
// FAILED "autocomplete-valid"
|
||||
{ code: '<input type="text" autocomplete="foo" />;', errors: invalidAutocomplete },
|
||||
{ code: '<input type="text" autocomplete="name invalid" />;', errors: invalidAutocomplete },
|
||||
|
|
@ -72,5 +73,5 @@ ruleTester.run('autocomplete-valid', rule, {
|
|||
{ code: '<input type="text" autocomplete="home url" />;', errors: invalidAutocomplete },
|
||||
{ code: '<Bar autocomplete="baz"></Bar>;', errors: invalidAutocomplete, options: [{ inputComponents: ['Bar'] }] },
|
||||
{ code: '<Input type="text" autocomplete="baz" />', errors: invalidAutocomplete, settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/click-events-have-key-events';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -25,7 +26,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('click-events-have-key-events', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div onClick={() => void 0} onKeyDown={foo}/>;' },
|
||||
{ code: '<div onClick={() => void 0} onKeyUp={foo} />;' },
|
||||
{ code: '<div onClick={() => void 0} onKeyPress={foo}/>;' },
|
||||
|
|
@ -52,8 +53,8 @@ ruleTester.run('click-events-have-key-events', rule, {
|
|||
{ code: '<TestComponent onClick={doFoo} />' },
|
||||
{ code: '<Button onClick={doFoo} />' },
|
||||
{ code: '<Footer onClick={doFoo} />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div onClick={() => void 0} />;', errors: [expectedError] },
|
||||
{
|
||||
code: '<div onClick={() => void 0} role={undefined} />;',
|
||||
|
|
@ -72,5 +73,5 @@ ruleTester.run('click-events-have-key-events', rule, {
|
|||
{ code: '<a onClick={() => void 0} />', errors: [expectedError] },
|
||||
{ code: '<a tabIndex="0" onClick={() => void 0} />', errors: [expectedError] },
|
||||
{ code: '<Footer onClick={doFoo} />', errors: [expectedError], settings: { 'jsx-a11y': { components: { Footer: 'footer' } } } },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import { configs } from '../../../src/index';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
import rule from '../../../src/rules/control-has-associated-label';
|
||||
|
||||
|
|
@ -156,7 +157,6 @@ const alwaysValid = [
|
|||
{ code: '<section />' },
|
||||
{ code: '<table />' },
|
||||
{ code: '<tbody />' },
|
||||
{ code: '<td />' },
|
||||
{ code: '<tfoot />' },
|
||||
{ code: '<thead />' },
|
||||
{ code: '<time />' },
|
||||
|
|
@ -262,6 +262,7 @@ const neverValid = [
|
|||
{ code: '<menuitem />', errors: [expectedError] },
|
||||
{ code: '<option />', errors: [expectedError] },
|
||||
{ code: '<th />', errors: [expectedError] },
|
||||
{ code: '<td />', errors: [expectedError] },
|
||||
// Interactive Roles
|
||||
{ code: '<div role="button" />', errors: [expectedError] },
|
||||
{ code: '<div role="checkbox" />', errors: [expectedError] },
|
||||
|
|
@ -287,40 +288,40 @@ const neverValid = [
|
|||
|
||||
const recommendedOptions = (configs.recommended.rules[ruleName][1] || {});
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
const strictOptions = (configs.strict.rules[ruleName][1] || {});
|
||||
ruleTester.run(`${ruleName}:strict`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(strictOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(strictOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
ruleTester.run(`${ruleName}:no-config`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<input type="hidden" />' },
|
||||
{ code: '<input type="text" aria-hidden="true" />' },
|
||||
]
|
||||
))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<input type="text" />', errors: [expectedError] },
|
||||
]
|
||||
))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/heading-has-content';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -37,7 +38,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('heading-has-content', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT TESTS
|
||||
{ code: '<div />;' },
|
||||
{ code: '<h1>Foo</h1>' },
|
||||
|
|
@ -64,8 +65,8 @@ ruleTester.run('heading-has-content', rule, {
|
|||
// CUSTOM ELEMENT TESTS FOR COMPONENTS SETTINGS
|
||||
{ code: '<Heading>Foo</Heading>', settings: componentsSettings },
|
||||
{ code: '<h1><CustomInput type="hidden" /></h1>' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT TESTS
|
||||
{ code: '<h1 />', errors: [expectedError] },
|
||||
{ code: '<h1><Bar aria-hidden /></h1>', errors: [expectedError] },
|
||||
|
|
@ -80,5 +81,5 @@ ruleTester.run('heading-has-content', rule, {
|
|||
// CUSTOM ELEMENT TESTS FOR COMPONENTS SETTINGS
|
||||
{ code: '<Heading />', errors: [expectedError], settings: componentsSettings },
|
||||
{ code: '<h1><CustomInput type="hidden" /></h1>', errors: [expectedError], settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/html-has-lang';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -23,7 +24,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('html-has-lang', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<html lang="en" />' },
|
||||
{ code: '<html lang="en-US" />' },
|
||||
|
|
@ -31,11 +32,11 @@ ruleTester.run('html-has-lang', rule, {
|
|||
{ code: '<html lang />' },
|
||||
{ code: '<HTML />' },
|
||||
{ code: '<HTMLTop lang="en" />', errors: [expectedError], settings: { 'jsx-a11y': { components: { HTMLTop: 'html' } } } },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<html />', errors: [expectedError] },
|
||||
{ code: '<html {...props} />', errors: [expectedError] },
|
||||
{ code: '<html lang={undefined} />', errors: [expectedError] },
|
||||
{ code: '<HTMLTop />', errors: [expectedError], settings: { 'jsx-a11y': { components: { HTMLTop: 'html' } } } },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/iframe-has-title';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -31,14 +32,14 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('html-has-lang', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<iframe title="Unique title" />' },
|
||||
{ code: '<iframe title={foo} />' },
|
||||
{ code: '<FooComponent />' },
|
||||
{ code: '<FooComponent title="Unique title" />', settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<iframe />', errors: [expectedError] },
|
||||
{ code: '<iframe {...props} />', errors: [expectedError] },
|
||||
{ code: '<iframe title={undefined} />', errors: [expectedError] },
|
||||
|
|
@ -50,5 +51,5 @@ ruleTester.run('html-has-lang', rule, {
|
|||
{ code: '<iframe title={""} />', errors: [expectedError] },
|
||||
{ code: '<iframe title={42} />', errors: [expectedError] },
|
||||
{ code: '<FooComponent />', errors: [expectedError], settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
17
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test.js
generated
vendored
17
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test.js
generated
vendored
|
|
@ -11,6 +11,7 @@ import { RuleTester } from 'eslint';
|
|||
import semver from 'semver';
|
||||
import { version as eslintVersion } from 'eslint/package.json';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/img-redundant-alt';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -38,7 +39,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('img-redundant-alt', rule, {
|
||||
valid: [].concat(
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<img alt="foo" />;' },
|
||||
{ code: '<img alt="picture of me taking a photo of an image" aria-hidden />' },
|
||||
{ code: '<img aria-hidden alt="photo of image" />' },
|
||||
|
|
@ -66,15 +67,16 @@ ruleTester.run('img-redundant-alt', rule, {
|
|||
{ code: '<img alt={imageAlt} />' },
|
||||
{ code: '<img alt={imageAlt.name} />' },
|
||||
semver.satisfies(eslintVersion, '>= 6') ? [
|
||||
{ code: '<img alt={imageAlt?.name} />', parserOptions: { ecmaVersion: 2020 } },
|
||||
{ code: '<img alt="Doing cool things" aria-hidden={foo?.bar}/>', parserOptions: { ecmaVersion: 2020 } },
|
||||
{ code: '<img alt={imageAlt?.name} />', languageOptions: { ecmaVersion: 2020 } },
|
||||
{ code: '<img alt="Doing cool things" aria-hidden={foo?.bar}/>', languageOptions: { ecmaVersion: 2020 } },
|
||||
] : [],
|
||||
{ code: '<img alt="Photography" />;' },
|
||||
{ code: '<img alt="ImageMagick" />;' },
|
||||
{ code: '<Image alt="Photo of a friend" />' },
|
||||
{ code: '<Image alt="Foo" />', settings: componentsSettings },
|
||||
).map(parserOptionsMapper),
|
||||
invalid: [
|
||||
{ code: '<img alt="画像" />', options: [{ words: ['イメージ'] }] },
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<img alt="Photo of friend." />;', errors: [expectedError] },
|
||||
{ code: '<img alt="Picture of friend." />;', errors: [expectedError] },
|
||||
{ code: '<img alt="Image of friend." />;', errors: [expectedError] },
|
||||
|
|
@ -128,5 +130,8 @@ ruleTester.run('img-redundant-alt', rule, {
|
|||
{ code: '<img alt="Word2" />;', options: array, errors: [expectedError] },
|
||||
{ code: '<Image alt="Word1" />;', options: array, errors: [expectedError] },
|
||||
{ code: '<Image alt="Word2" />;', options: array, errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
|
||||
{ code: '<img alt="イメージ" />', options: [{ words: ['イメージ'] }], errors: [expectedError] },
|
||||
{ code: '<img alt="イメージです" />', options: [{ words: ['イメージ'] }], errors: [expectedError] },
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
} from 'jsx-ast-utils';
|
||||
import { configs } from '../../../src/index';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/interactive-supports-focus';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -208,7 +209,7 @@ const failReducer = (roles, handlers, messageTemplate) => (
|
|||
);
|
||||
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
...passReducer(
|
||||
interactiveRoles,
|
||||
|
|
@ -220,10 +221,10 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
|
|||
eventHandlers.filter((handler) => includes(triggeringHandlers, handler)),
|
||||
tabindexTemplate,
|
||||
),
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
...failReducer(recommendedRoles, triggeringHandlers, tabbableTemplate),
|
||||
...failReducer(
|
||||
|
|
@ -231,13 +232,13 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
|
|||
triggeringHandlers,
|
||||
focusableTemplate,
|
||||
),
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
ruleTester.run(`${ruleName}:strict`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
...passReducer(
|
||||
interactiveRoles,
|
||||
|
|
@ -249,10 +250,10 @@ ruleTester.run(`${ruleName}:strict`, rule, {
|
|||
eventHandlers.filter((handler) => includes(triggeringHandlers, handler)),
|
||||
tabindexTemplate,
|
||||
),
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(strictOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
...failReducer(strictRoles, triggeringHandlers, tabbableTemplate),
|
||||
...failReducer(
|
||||
|
|
@ -260,7 +261,7 @@ ruleTester.run(`${ruleName}:strict`, rule, {
|
|||
triggeringHandlers,
|
||||
focusableTemplate,
|
||||
),
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(strictOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/label-has-associated-control';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -25,6 +26,11 @@ const expectedError = {
|
|||
type: 'JSXOpeningElement',
|
||||
};
|
||||
|
||||
const expectedErrorNoLabel = {
|
||||
message: 'A form label must have accessible text.',
|
||||
type: 'JSXOpeningElement',
|
||||
};
|
||||
|
||||
const componentsSettings = {
|
||||
'jsx-a11y': {
|
||||
components: {
|
||||
|
|
@ -34,11 +40,23 @@ const componentsSettings = {
|
|||
},
|
||||
};
|
||||
|
||||
const attributesSettings = {
|
||||
'jsx-a11y': {
|
||||
attributes: {
|
||||
for: ['htmlFor', 'for'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const htmlForValid = [
|
||||
{ code: '<label htmlFor="js_id"><span><span><span>A label</span></span></span></label>', options: [{ depth: 4 }] },
|
||||
{ code: '<label htmlFor="js_id" aria-label="A label" />' },
|
||||
{ code: '<label htmlFor="js_id" aria-labelledby="A label" />' },
|
||||
{ code: '<div><label htmlFor="js_id">A label</label><input id="js_id" /></div>' },
|
||||
{ code: '<label for="js_id"><span><span><span>A label</span></span></span></label>', options: [{ depth: 4 }], settings: attributesSettings },
|
||||
{ code: '<label for="js_id" aria-label="A label" />', settings: attributesSettings },
|
||||
{ code: '<label for="js_id" aria-labelledby="A label" />', settings: attributesSettings },
|
||||
{ code: '<div><label for="js_id">A label</label><input id="js_id" /></div>', settings: attributesSettings },
|
||||
// Custom label component.
|
||||
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ labelComponents: ['CustomLabel'] }] },
|
||||
{ code: '<CustomLabel htmlFor="js_id" label="A label" />', options: [{ labelAttributes: ['label'], labelComponents: ['CustomLabel'] }] },
|
||||
|
|
@ -48,6 +66,8 @@ const htmlForValid = [
|
|||
// Glob support for controlComponents option.
|
||||
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ controlComponents: ['Custom*'] }] },
|
||||
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ controlComponents: ['*Label'] }] },
|
||||
// Rule does not error if presence of accessible label cannot be determined
|
||||
{ code: '<div><label htmlFor="js_id"><CustomText /></label><input id="js_id" /></div>' },
|
||||
];
|
||||
const nestingValid = [
|
||||
{ code: '<label>A label<input /></label>' },
|
||||
|
|
@ -66,6 +86,7 @@ const nestingValid = [
|
|||
{ code: '<label>foo<progress /></label>' },
|
||||
{ code: '<label>foo<textarea /></label>' },
|
||||
// Custom controlComponents.
|
||||
{ code: '<label>A label<CustomInput /></label>', options: [{ controlComponents: ['CustomInput'] }] },
|
||||
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['CustomInput'] }] },
|
||||
{ code: '<label><span>A label<CustomInput /></span></label>', settings: componentsSettings },
|
||||
{ code: '<CustomLabel><span>A label<CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'] }] },
|
||||
|
|
@ -73,6 +94,8 @@ const nestingValid = [
|
|||
// Glob support for controlComponents option.
|
||||
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['Custom*'] }] },
|
||||
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['*Input'] }] },
|
||||
// Rule does not error if presence of accessible label cannot be determined
|
||||
{ code: '<label><CustomText /><input /></label>' },
|
||||
];
|
||||
|
||||
const bothValid = [
|
||||
|
|
@ -119,6 +142,7 @@ const nestingInvalid = [
|
|||
{ code: '<label><span><span><span><span aria-label="A label" /><input /></span></span></span></label>', options: [{ depth: 5 }], errors: [expectedError] },
|
||||
{ code: '<label><span><span><span><input aria-label="A label" /></span></span></span></label>', options: [{ depth: 5 }], errors: [expectedError] },
|
||||
// Custom controlComponents.
|
||||
{ code: '<label>A label<OtherCustomInput /></label>', options: [{ controlComponents: ['CustomInput'] }], errors: [expectedError] },
|
||||
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['CustomInput'] }], errors: [expectedError] },
|
||||
{ code: '<CustomLabel><span>A label<CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'] }], errors: [expectedError] },
|
||||
{ code: '<CustomLabel><span label="A label"><CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'], labelAttributes: ['label'] }], errors: [expectedError] },
|
||||
|
|
@ -127,12 +151,12 @@ const nestingInvalid = [
|
|||
];
|
||||
|
||||
const neverValid = [
|
||||
{ code: '<label htmlFor="js_id" />', errors: [expectedError] },
|
||||
{ code: '<label htmlFor="js_id"><input /></label>', errors: [expectedError] },
|
||||
{ code: '<label htmlFor="js_id"><textarea /></label>', errors: [expectedError] },
|
||||
{ code: '<label></label>', errors: [expectedError] },
|
||||
{ code: '<label htmlFor="js_id" />', errors: [expectedErrorNoLabel] },
|
||||
{ code: '<label htmlFor="js_id"><input /></label>', errors: [expectedErrorNoLabel] },
|
||||
{ code: '<label htmlFor="js_id"><textarea /></label>', errors: [expectedErrorNoLabel] },
|
||||
{ code: '<label></label>', errors: [expectedErrorNoLabel] },
|
||||
{ code: '<label>A label</label>', errors: [expectedError] },
|
||||
{ code: '<div><label /><input /></div>', errors: [expectedError] },
|
||||
{ code: '<div><label /><input /></div>', errors: [expectedErrorNoLabel] },
|
||||
{ code: '<div><label>A label</label><input /></div>', errors: [expectedError] },
|
||||
// Custom label component.
|
||||
{ code: '<CustomLabel aria-label="A label" />', options: [{ labelComponents: ['CustomLabel'] }], errors: [expectedError] },
|
||||
|
|
@ -141,26 +165,26 @@ const neverValid = [
|
|||
// Custom label attributes.
|
||||
{ code: '<label label="A label" />', options: [{ labelAttributes: ['label'] }], errors: [expectedError] },
|
||||
// Custom controlComponents.
|
||||
{ code: '<label><span><CustomInput /></span></label>', options: [{ controlComponents: ['CustomInput'] }], errors: [expectedError] },
|
||||
{ code: '<CustomLabel><span><CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'] }], errors: [expectedError] },
|
||||
{ code: '<CustomLabel><span><CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'], labelAttributes: ['label'] }], errors: [expectedError] },
|
||||
{ code: '<label><span><CustomInput /></span></label>', settings: componentsSettings, errors: [expectedError] },
|
||||
{ code: '<CustomLabel><span><CustomInput /></span></CustomLabel>', settings: componentsSettings, errors: [expectedError] },
|
||||
{ code: '<label><span><CustomInput /></span></label>', options: [{ controlComponents: ['CustomInput'] }], errors: [expectedErrorNoLabel] },
|
||||
{ code: '<CustomLabel><span><CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'] }], errors: [expectedErrorNoLabel] },
|
||||
{ code: '<CustomLabel><span><CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'], labelAttributes: ['label'] }], errors: [expectedErrorNoLabel] },
|
||||
{ code: '<label><span><CustomInput /></span></label>', settings: componentsSettings, errors: [expectedErrorNoLabel] },
|
||||
{ code: '<CustomLabel><span><CustomInput /></span></CustomLabel>', settings: componentsSettings, errors: [expectedErrorNoLabel] },
|
||||
];
|
||||
// htmlFor valid
|
||||
ruleTester.run(ruleName, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
...htmlForValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory({
|
||||
assert: 'htmlFor',
|
||||
}))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
...nestingInvalid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory({
|
||||
assert: 'htmlFor',
|
||||
}))
|
||||
|
|
@ -169,18 +193,18 @@ ruleTester.run(ruleName, rule, {
|
|||
|
||||
// nesting valid
|
||||
ruleTester.run(ruleName, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
...nestingValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory({
|
||||
assert: 'nesting',
|
||||
}))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
...htmlForInvalid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory({
|
||||
assert: 'nesting',
|
||||
}))
|
||||
|
|
@ -189,31 +213,31 @@ ruleTester.run(ruleName, rule, {
|
|||
|
||||
// either valid
|
||||
ruleTester.run(ruleName, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
...htmlForValid,
|
||||
...nestingValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory({
|
||||
assert: 'either',
|
||||
}))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
// both valid
|
||||
ruleTester.run(ruleName, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
...bothValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory({
|
||||
assert: 'both',
|
||||
}))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
21
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test.js
generated
vendored
21
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test.js
generated
vendored
|
|
@ -10,6 +10,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import assign from 'object.assign';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/label-has-for';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -49,16 +50,28 @@ const optionsChildrenAllowed = [{
|
|||
allowChildren: true,
|
||||
}];
|
||||
|
||||
const attributesSettings = {
|
||||
'jsx-a11y': {
|
||||
attributes: {
|
||||
for: ['htmlFor', 'for'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
ruleTester.run('label-has-for', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT 'label' TESTS
|
||||
{ code: '<div />' },
|
||||
{ code: '<label htmlFor="foo"><input /></label>' },
|
||||
{ code: '<label htmlFor="foo"><textarea /></label>' },
|
||||
{ code: '<label for="foo"><input /></label>', settings: attributesSettings },
|
||||
{ code: '<label for="foo"><textarea /></label>', settings: attributesSettings },
|
||||
{ code: '<Label />' }, // lower-case convention refers to real HTML elements.
|
||||
{ code: '<Label htmlFor="foo" />' },
|
||||
{ code: '<Label for="foo" />', settings: attributesSettings },
|
||||
{ code: '<Descriptor />' },
|
||||
{ code: '<Descriptor htmlFor="foo">Test!</Descriptor>' },
|
||||
{ code: '<Descriptor for="foo">Test!</Descriptor>', settings: attributesSettings },
|
||||
{ code: '<UX.Layout>test</UX.Layout>' },
|
||||
|
||||
// CUSTOM ELEMENT ARRAY OPTION TESTS
|
||||
|
|
@ -90,8 +103,8 @@ ruleTester.run('label-has-for', rule, {
|
|||
{ code: '<label htmlFor="children">{children}</label>', options: optionsChildrenAllowed },
|
||||
{ code: '<label htmlFor={id}>{ labelText }<div><input id={id} type="checkbox" name={id} value={value} /></div></label>', options: optionsRequiredEvery },
|
||||
{ code: '<label htmlFor={id}>{ labelText }<div><div><div><div><input id={id} type="checkbox" name={id} value={value} /></div></div></div></div></label>', options: optionsRequiredEvery },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
// DEFAULT ELEMENT 'label' TESTS
|
||||
{ code: '<label id="foo" />', errors: [expectedEveryError], options: optionsRequiredEvery },
|
||||
{ code: '<label htmlFor={undefined} />', errors: [expectedEveryError], options: optionsRequiredEvery },
|
||||
|
|
@ -218,5 +231,5 @@ ruleTester.run('label-has-for', rule, {
|
|||
errors: [expectedEveryError],
|
||||
options: optionsRequiredEvery,
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
12
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test.js
generated
vendored
12
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/lang';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -24,6 +25,7 @@ const expectedError = {
|
|||
|
||||
const componentsSettings = {
|
||||
'jsx-a11y': {
|
||||
polymorphicPropName: 'as',
|
||||
components: {
|
||||
Foo: 'html',
|
||||
},
|
||||
|
|
@ -31,7 +33,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('lang', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<div foo="bar" />;' },
|
||||
{ code: '<div lang="foo" />;' },
|
||||
|
|
@ -45,11 +47,13 @@ ruleTester.run('lang', rule, {
|
|||
{ code: '<HTML lang="foo" />' },
|
||||
{ code: '<Foo lang={undefined} />' },
|
||||
{ code: '<Foo lang="en" />', settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
{ code: '<Box as="html" lang="en" />', settings: componentsSettings },
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<html lang="foo" />', errors: [expectedError] },
|
||||
{ code: '<html lang="zz-LL" />', errors: [expectedError] },
|
||||
{ code: '<html lang={undefined} />', errors: [expectedError] },
|
||||
{ code: '<Foo lang={undefined} />', settings: componentsSettings, errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
{ code: '<Box as="html" lang="foo" />', settings: componentsSettings, errors: [expectedError] },
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
19
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/media-has-caption-test.js
generated
vendored
19
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/media-has-caption-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/media-has-caption';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -32,6 +33,7 @@ const customSchema = [
|
|||
|
||||
const componentsSettings = {
|
||||
'jsx-a11y': {
|
||||
polymorphicPropName: 'as',
|
||||
components: {
|
||||
Audio: 'audio',
|
||||
Video: 'video',
|
||||
|
|
@ -41,7 +43,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('media-has-caption', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<MyDiv />;' },
|
||||
{ code: '<audio><track kind="captions" /></audio>' },
|
||||
|
|
@ -143,8 +145,12 @@ ruleTester.run('media-has-caption', rule, {
|
|||
code: '<Audio muted={true}></Audio>',
|
||||
settings: componentsSettings,
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
{
|
||||
code: '<Box as="audio" muted={true}></Box>',
|
||||
settings: componentsSettings,
|
||||
},
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<audio><track /></audio>', errors: [expectedError] },
|
||||
{
|
||||
code: '<audio><track kind="subtitles" /></audio>',
|
||||
|
|
@ -205,5 +211,10 @@ ruleTester.run('media-has-caption', rule, {
|
|||
settings: componentsSettings,
|
||||
errors: [expectedError],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
{
|
||||
code: '<Box as="audio"><Track kind="subtitles" /></Box>',
|
||||
settings: componentsSettings,
|
||||
errors: [expectedError],
|
||||
},
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/mouse-events-have-key-events';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -20,15 +21,23 @@ const ruleTester = new RuleTester();
|
|||
|
||||
const mouseOverError = {
|
||||
message: 'onMouseOver must be accompanied by onFocus for accessibility.',
|
||||
type: 'JSXOpeningElement',
|
||||
type: 'JSXAttribute',
|
||||
};
|
||||
const pointerEnterError = {
|
||||
message: 'onPointerEnter must be accompanied by onFocus for accessibility.',
|
||||
type: 'JSXAttribute',
|
||||
};
|
||||
const mouseOutError = {
|
||||
message: 'onMouseOut must be accompanied by onBlur for accessibility.',
|
||||
type: 'JSXOpeningElement',
|
||||
type: 'JSXAttribute',
|
||||
};
|
||||
const pointerLeaveError = {
|
||||
message: 'onPointerLeave must be accompanied by onBlur for accessibility.',
|
||||
type: 'JSXAttribute',
|
||||
};
|
||||
|
||||
ruleTester.run('mouse-events-have-key-events', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div onMouseOver={() => void 0} onFocus={() => void 0} />;' },
|
||||
{
|
||||
code: '<div onMouseOver={() => void 0} onFocus={() => void 0} {...props} />;',
|
||||
|
|
@ -53,8 +62,41 @@ ruleTester.run('mouse-events-have-key-events', rule, {
|
|||
{ code: '<MyElement onMouseOut={() => {}} {...props} />' },
|
||||
{ code: '<MyElement onBlur={() => {}} {...props} />' },
|
||||
{ code: '<MyElement onFocus={() => {}} {...props} />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
/* Passing in empty options doesn't check any event handlers */
|
||||
{
|
||||
code: '<div onMouseOver={() => {}} onMouseOut={() => {}} />',
|
||||
options: [{ hoverInHandlers: [], hoverOutHandlers: [] }],
|
||||
},
|
||||
/* Passing in custom handlers */
|
||||
{
|
||||
code: '<div onMouseOver={() => {}} onFocus={() => {}} />',
|
||||
options: [{ hoverInHandlers: ['onMouseOver'] }],
|
||||
},
|
||||
{
|
||||
code: '<div onMouseEnter={() => {}} onFocus={() => {}} />',
|
||||
options: [{ hoverInHandlers: ['onMouseEnter'] }],
|
||||
},
|
||||
{
|
||||
code: '<div onMouseOut={() => {}} onBlur={() => {}} />',
|
||||
options: [{ hoverOutHandlers: ['onMouseOut'] }],
|
||||
},
|
||||
{
|
||||
code: '<div onMouseLeave={() => {}} onBlur={() => {}} />',
|
||||
options: [{ hoverOutHandlers: ['onMouseLeave'] }],
|
||||
},
|
||||
{
|
||||
code: '<div onMouseOver={() => {}} onMouseOut={() => {}} />',
|
||||
options: [
|
||||
{ hoverInHandlers: ['onPointerEnter'], hoverOutHandlers: ['onPointerLeave'] },
|
||||
],
|
||||
},
|
||||
/* Custom options only checks the handlers passed in */
|
||||
{
|
||||
code: '<div onMouseLeave={() => {}} />',
|
||||
options: [{ hoverOutHandlers: ['onPointerLeave'] }],
|
||||
},
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div onMouseOver={() => void 0} />;', errors: [mouseOverError] },
|
||||
{ code: '<div onMouseOut={() => void 0} />', errors: [mouseOutError] },
|
||||
{
|
||||
|
|
@ -73,5 +115,40 @@ ruleTester.run('mouse-events-have-key-events', rule, {
|
|||
code: '<div onMouseOut={() => void 0} {...props} />',
|
||||
errors: [mouseOutError],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
/* Custom options */
|
||||
{
|
||||
code: '<div onMouseOver={() => {}} onMouseOut={() => {}} />',
|
||||
options: [
|
||||
{ hoverInHandlers: ['onMouseOver'], hoverOutHandlers: ['onMouseOut'] },
|
||||
],
|
||||
errors: [mouseOverError, mouseOutError],
|
||||
},
|
||||
{
|
||||
code: '<div onPointerEnter={() => {}} onPointerLeave={() => {}} />',
|
||||
options: [
|
||||
{ hoverInHandlers: ['onPointerEnter'], hoverOutHandlers: ['onPointerLeave'] },
|
||||
],
|
||||
errors: [pointerEnterError, pointerLeaveError],
|
||||
},
|
||||
{
|
||||
code: '<div onMouseOver={() => {}} />',
|
||||
options: [{ hoverInHandlers: ['onMouseOver'] }],
|
||||
errors: [mouseOverError],
|
||||
},
|
||||
{
|
||||
code: '<div onPointerEnter={() => {}} />',
|
||||
options: [{ hoverInHandlers: ['onPointerEnter'] }],
|
||||
errors: [pointerEnterError],
|
||||
},
|
||||
{
|
||||
code: '<div onMouseOut={() => {}} />',
|
||||
options: [{ hoverOutHandlers: ['onMouseOut'] }],
|
||||
errors: [mouseOutError],
|
||||
},
|
||||
{
|
||||
code: '<div onPointerLeave={() => {}} />',
|
||||
options: [{ hoverOutHandlers: ['onPointerLeave'] }],
|
||||
errors: [pointerLeaveError],
|
||||
},
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
11
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test.js
generated
vendored
11
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-access-key';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -18,17 +19,17 @@ import rule from '../../../src/rules/no-access-key';
|
|||
const ruleTester = new RuleTester();
|
||||
|
||||
const expectedError = {
|
||||
message: 'No access key attribute allowed. Inconsistencies between keyboard shortcuts and keyboard commands used by screenreaders and keyboard-only users create a11y complications.',
|
||||
message: 'No access key attribute allowed. Inconsistencies between keyboard shortcuts and keyboard commands used by screen readers and keyboard-only users create a11y complications.',
|
||||
type: 'JSXOpeningElement',
|
||||
};
|
||||
|
||||
ruleTester.run('no-access-key', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<div {...props} />' },
|
||||
{ code: '<div accessKey={undefined} />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div accesskey="h" />', errors: [expectedError] },
|
||||
{ code: '<div accessKey="h" />', errors: [expectedError] },
|
||||
{ code: '<div accessKey="h" {...props} />', errors: [expectedError] },
|
||||
|
|
@ -43,5 +44,5 @@ ruleTester.run('no-access-key', rule, {
|
|||
{ code: '<div accessKey={accessKey} />', errors: [expectedError] },
|
||||
{ code: '<div accessKey={`${undefined}`} />', errors: [expectedError] },
|
||||
{ code: '<div accessKey={`${undefined}${undefined}`} />', errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-aria-hidden-on-focusable';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Tests
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -22,7 +24,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('no-aria-hidden-on-focusable', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div aria-hidden="true" />;' },
|
||||
{ code: '<div onClick={() => void 0} aria-hidden="true" />;' },
|
||||
{ code: '<img aria-hidden="true" />' },
|
||||
|
|
@ -30,13 +32,13 @@ ruleTester.run('no-aria-hidden-on-focusable', rule, {
|
|||
{ code: '<button aria-hidden="true" tabIndex="-1" />' },
|
||||
{ code: '<button />' },
|
||||
{ code: '<a href="/" />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div aria-hidden="true" tabIndex="0" />;', errors: [expectedError] },
|
||||
{ code: '<input aria-hidden="true" />;', errors: [expectedError] },
|
||||
{ code: '<a href="/" aria-hidden="true" />', errors: [expectedError] },
|
||||
{ code: '<button aria-hidden="true" />', errors: [expectedError] },
|
||||
{ code: '<textarea aria-hidden="true" />', errors: [expectedError] },
|
||||
{ code: '<p tabindex="0" aria-hidden="true">text</p>;', errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-autofocus';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -37,7 +38,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('no-autofocus', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<div autofocus />;' },
|
||||
{ code: '<input autofocus="true" />;' },
|
||||
|
|
@ -46,8 +47,8 @@ ruleTester.run('no-autofocus', rule, {
|
|||
{ code: '<div><div autofocus /></div>', options: ignoreNonDOMSchema },
|
||||
{ code: '<Button />', settings: componentsSettings },
|
||||
{ code: '<Button />', options: ignoreNonDOMSchema, settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div autoFocus />', errors: [expectedError] },
|
||||
{ code: '<div autoFocus={true} />', errors: [expectedError] },
|
||||
{ code: '<div autoFocus={false} />', errors: [expectedError] },
|
||||
|
|
@ -63,5 +64,5 @@ ruleTester.run('no-autofocus', rule, {
|
|||
options: ignoreNonDOMSchema,
|
||||
settings: componentsSettings,
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-distracting-elements';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -31,14 +32,14 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('no-marquee', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<Marquee />' },
|
||||
{ code: '<div marquee />' },
|
||||
{ code: '<Blink />' },
|
||||
{ code: '<div blink />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<marquee />', errors: [expectedError('marquee')] },
|
||||
{ code: '<marquee {...props} />', errors: [expectedError('marquee')] },
|
||||
{ code: '<marquee lang={undefined} />', errors: [expectedError('marquee')] },
|
||||
|
|
@ -46,5 +47,5 @@ ruleTester.run('no-marquee', rule, {
|
|||
{ code: '<blink {...props} />', errors: [expectedError('blink')] },
|
||||
{ code: '<blink foo={undefined} />', errors: [expectedError('blink')] },
|
||||
{ code: '<Blink />', settings: componentsSettings, errors: [expectedError('blink')] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import { configs } from '../../../src/index';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-interactive-element-to-noninteractive-role';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -369,7 +370,6 @@ const neverValid = [
|
|||
{ code: '<menuitem role="listitem" />;', errors: [expectedError] },
|
||||
{ code: '<option className="foo" role="listitem" />', errors: [expectedError] },
|
||||
{ code: '<select className="foo" role="listitem" />', errors: [expectedError] },
|
||||
{ code: '<summary role="listitem" />;', errors: [expectedError] },
|
||||
{ code: '<textarea className="foo" role="listitem" />', errors: [expectedError] },
|
||||
{ code: '<tr role="listitem" />;', errors: [expectedError] },
|
||||
/* Custom elements */
|
||||
|
|
@ -378,28 +378,28 @@ const neverValid = [
|
|||
|
||||
const recommendedOptions = (configs.recommended.rules[ruleName][1] || {});
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
{ code: '<tr role="presentation" />;' },
|
||||
{ code: '<canvas role="img" />;' },
|
||||
{ code: '<Component role="presentation" />;' },
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
ruleTester.run(`${ruleName}:strict`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
{ code: '<tr role="presentation" />;', errors: [expectedError] },
|
||||
{ code: '<canvas role="img" />;', errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import { configs } from '../../../src/index';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-noninteractive-element-interactions';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -68,6 +69,7 @@ const alwaysValid = [
|
|||
{ code: '<a onClick={() => void 0} href="http://x.y.z" />' },
|
||||
{ code: '<a onClick={() => void 0} href="http://x.y.z" tabIndex="0" />' },
|
||||
{ code: '<area onClick={() => {}} />;' },
|
||||
{ code: '<body onClick={() => {}} />;' },
|
||||
{ code: '<button onClick={() => void 0} className="foo" />' },
|
||||
{ code: '<menuitem onClick={() => {}} />;' },
|
||||
{ code: '<option onClick={() => void 0} className="foo" />' },
|
||||
|
|
@ -76,7 +78,6 @@ const alwaysValid = [
|
|||
{ code: '<tr onClick={() => {}} />;' },
|
||||
/* HTML elements with neither an interactive or non-interactive valence (static) */
|
||||
{ code: '<acronym onClick={() => {}} />;' },
|
||||
{ code: '<address onClick={() => {}} />;' },
|
||||
{ code: '<applet onClick={() => {}} />;' },
|
||||
{ code: '<audio onClick={() => {}} />;' },
|
||||
{ code: '<b onClick={() => {}} />;' },
|
||||
|
|
@ -89,13 +90,11 @@ const alwaysValid = [
|
|||
{ code: '<canvas onClick={() => {}} />;' },
|
||||
{ code: '<center onClick={() => {}} />;' },
|
||||
{ code: '<cite onClick={() => {}} />;' },
|
||||
{ code: '<code onClick={() => {}} />;' },
|
||||
{ code: '<col onClick={() => {}} />;' },
|
||||
{ code: '<colgroup onClick={() => {}} />;' },
|
||||
{ code: '<content onClick={() => {}} />;' },
|
||||
{ code: '<data onClick={() => {}} />;' },
|
||||
{ code: '<datalist onClick={() => {}} />;' },
|
||||
{ code: '<del onClick={() => {}} />;' },
|
||||
{ code: '<div />;' },
|
||||
{ code: '<div className="foo" />;' },
|
||||
{ code: '<div className="foo" {...props} />;' },
|
||||
|
|
@ -106,7 +105,6 @@ const alwaysValid = [
|
|||
{ code: '<div onClick={() => void 0} {...props} />;' },
|
||||
{ code: '<div onClick={null} />;' },
|
||||
{ code: '<div onKeyUp={() => void 0} aria-hidden={false} />;' },
|
||||
{ code: '<em onClick={() => {}} />;' },
|
||||
{ code: '<embed onClick={() => {}} />;' },
|
||||
{ code: '<font onClick={() => {}} />;' },
|
||||
{ code: '<font onSubmit={() => {}} />;' },
|
||||
|
|
@ -120,11 +118,11 @@ const alwaysValid = [
|
|||
</form>
|
||||
`,
|
||||
},
|
||||
{ code: '<frame onClick={() => {}} />;' },
|
||||
{ code: '<frameset onClick={() => {}} />;' },
|
||||
{ code: '<head onClick={() => {}} />;' },
|
||||
{ code: '<header onClick={() => {}} />;' },
|
||||
{ code: '<hgroup onClick={() => {}} />;' },
|
||||
{ code: '<html onClick={() => {}} />;' },
|
||||
{ code: '<i onClick={() => {}} />;' },
|
||||
{ code: '<iframe onLoad={() => {}} />;' },
|
||||
{
|
||||
|
|
@ -152,7 +150,6 @@ const alwaysValid = [
|
|||
/>
|
||||
`,
|
||||
},
|
||||
{ code: '<ins onClick={() => {}} />;' },
|
||||
{ code: '<kbd onClick={() => {}} />;' },
|
||||
{ code: '<keygen onClick={() => {}} />;' },
|
||||
{ code: '<link onClick={() => {}} />;' },
|
||||
|
|
@ -177,14 +174,12 @@ const alwaysValid = [
|
|||
{ code: '<spacer onClick={() => {}} />;' },
|
||||
{ code: '<span onClick={() => {}} />;' },
|
||||
{ code: '<strike onClick={() => {}} />;' },
|
||||
{ code: '<strong onClick={() => {}} />;' },
|
||||
{ code: '<style onClick={() => {}} />;' },
|
||||
{ code: '<sub onClick={() => {}} />;' },
|
||||
{ code: '<summary onClick={() => {}} />;' },
|
||||
{ code: '<sup onClick={() => {}} />;' },
|
||||
{ code: '<th onClick={() => {}} />;' },
|
||||
{ code: '<title onClick={() => {}} />;' },
|
||||
{ code: '<track onClick={() => {}} />;' },
|
||||
{ code: '<td onClick={() => {}} />;' },
|
||||
{ code: '<tt onClick={() => {}} />;' },
|
||||
{ code: '<u onClick={() => {}} />;' },
|
||||
{ code: '<var onClick={() => {}} />;' },
|
||||
|
|
@ -285,24 +280,26 @@ const alwaysValid = [
|
|||
const neverValid = [
|
||||
/* HTML elements with an inherent, non-interactive role */
|
||||
{ code: '<main onClick={() => void 0} />;', errors: [expectedError] },
|
||||
{ code: '<address onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<article onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<aside onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<blockquote onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<body onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<br onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<caption onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<code onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<dd onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<del onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<details onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<dfn onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<dl onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<dir onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<dt onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<em onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<fieldset onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<figcaption onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<figure onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<footer onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<form onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<frame onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<h1 onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<h2 onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<h3 onClick={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -310,8 +307,10 @@ const neverValid = [
|
|||
{ code: '<h5 onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<h6 onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<hr onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<html onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<iframe onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<img onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<ins onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<label onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<legend onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<li onClick={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -329,13 +328,14 @@ const neverValid = [
|
|||
{ code: '<ruby onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<section onClick={() => {}} aria-label="Aardvark" />;', errors: [expectedError] },
|
||||
{ code: '<section onClick={() => {}} aria-labelledby="js_1" />;', errors: [expectedError] },
|
||||
{ code: '<strong onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<sub onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<sup onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<table onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<tbody onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<td onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<tfoot onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<thead onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<time onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<ol onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<ul onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<ul contentEditable="false" onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<article contentEditable onClick={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -344,7 +344,6 @@ const neverValid = [
|
|||
{ code: '<div role="alert" onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="alertdialog" onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="application" onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="article" onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="banner" onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="cell" onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="complementary" onClick={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -396,7 +395,7 @@ const neverValid = [
|
|||
|
||||
const recommendedOptions = configs.recommended.rules[`jsx-a11y/${ruleName}`][1] || {};
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
// All the possible handlers
|
||||
{ code: '<div role="article" onCopy={() => {}} />;' },
|
||||
|
|
@ -459,24 +458,24 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
|
|||
{ code: '<div role="article" onAnimationEnd={() => {}} />;' },
|
||||
{ code: '<div role="article" onAnimationIteration={() => {}} />;' },
|
||||
{ code: '<div role="article" onTransitionEnd={() => {}} />;' },
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
const strictOptions = configs.strict.rules[`jsx-a11y/${ruleName}`][1] || {};
|
||||
ruleTester.run(`${ruleName}:strict`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(strictOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
// All the possible handlers
|
||||
{ code: '<div role="article" onFocus={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -497,7 +496,7 @@ ruleTester.run(`${ruleName}:strict`, rule, {
|
|||
{ code: '<div role="article" onMouseMove={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="article" onMouseOut={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div role="article" onMouseOver={() => {}} />;', errors: [expectedError] },
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(strictOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import { configs } from '../../../src/index';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-noninteractive-element-to-interactive-role';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -49,6 +50,11 @@ const alwaysValid = [
|
|||
{ code: '<area role="button" />;' },
|
||||
{ code: '<area role="menuitem" />;' },
|
||||
{ code: '<button className="foo" role="button" />' },
|
||||
{ code: '<body role="button" />;' },
|
||||
{ code: '<frame role="button" />;' },
|
||||
{ code: '<td role="button" />;' },
|
||||
{ code: '<frame role="menuitem" />;' },
|
||||
{ code: '<td role="menuitem" />;' },
|
||||
/* All flavors of input */
|
||||
{ code: '<input role="button" />' },
|
||||
{ code: '<input type="button" role="button" />' },
|
||||
|
|
@ -153,7 +159,6 @@ const alwaysValid = [
|
|||
{ code: '<tr role="listitem" />;' },
|
||||
/* HTML elements with neither an interactive or non-interactive valence (static) */
|
||||
{ code: '<acronym role="button" />;' },
|
||||
{ code: '<address role="button" />;' },
|
||||
{ code: '<applet role="button" />;' },
|
||||
{ code: '<audio role="button" />;' },
|
||||
{ code: '<b role="button" />;' },
|
||||
|
|
@ -165,13 +170,11 @@ const alwaysValid = [
|
|||
{ code: '<canvas role="button" />;' },
|
||||
{ code: '<center role="button" />;' },
|
||||
{ code: '<cite role="button" />;' },
|
||||
{ code: '<code role="button" />;' },
|
||||
{ code: '<col role="button" />;' },
|
||||
{ code: '<colgroup role="button" />;' },
|
||||
{ code: '<content role="button" />;' },
|
||||
{ code: '<data role="button" />;' },
|
||||
{ code: '<datalist role="button" />;' },
|
||||
{ code: '<del role="button" />;' },
|
||||
{ code: '<div role="button" />;' },
|
||||
{ code: '<div className="foo" role="button" />;' },
|
||||
{ code: '<div className="foo" {...props} role="button" />;' },
|
||||
|
|
@ -181,16 +184,13 @@ const alwaysValid = [
|
|||
{ code: '<div role={undefined} role="button" />;' },
|
||||
{ code: '<div {...props} role="button" />;' },
|
||||
{ code: '<div onKeyUp={() => void 0} aria-hidden={false} role="button" />;' },
|
||||
{ code: '<em role="button" />;' },
|
||||
{ code: '<embed role="button" />;' },
|
||||
{ code: '<font role="button" />;' },
|
||||
{ code: '<frameset role="button" />;' },
|
||||
{ code: '<head role="button" />;' },
|
||||
{ code: '<header role="button" />;' },
|
||||
{ code: '<hgroup role="button" />;' },
|
||||
{ code: '<html role="button" />;' },
|
||||
{ code: '<i role="button" />;' },
|
||||
{ code: '<ins role="button" />;' },
|
||||
{ code: '<kbd role="button" />;' },
|
||||
{ code: '<keygen role="button" />;' },
|
||||
{ code: '<link role="button" />;' },
|
||||
|
|
@ -213,11 +213,8 @@ const alwaysValid = [
|
|||
{ code: '<spacer role="button" />;' },
|
||||
{ code: '<span role="button" />;' },
|
||||
{ code: '<strike role="button" />;' },
|
||||
{ code: '<strong role="button" />;' },
|
||||
{ code: '<style role="button" />;' },
|
||||
{ code: '<sub role="button" />;' },
|
||||
{ code: '<summary role="button" />;' },
|
||||
{ code: '<sup role="button" />;' },
|
||||
{ code: '<th role="button" />;' },
|
||||
{ code: '<title role="button" />;' },
|
||||
{ code: '<track role="button" />;' },
|
||||
|
|
@ -357,26 +354,26 @@ const alwaysValid = [
|
|||
const neverValid = [
|
||||
/* HTML elements with an inherent non-interactive role, assigned an
|
||||
* interactive role. */
|
||||
{ code: '<main role="button" />;', errors: [expectedError] },
|
||||
{ code: '<article role="button" />;', errors: [expectedError] },
|
||||
{ code: '<address role="button" />;', errors: [expectedError] },
|
||||
{ code: '<article role="button" />;', errors: [expectedError] },
|
||||
{ code: '<aside role="button" />;', errors: [expectedError] },
|
||||
{ code: '<blockquote role="button" />;', errors: [expectedError] },
|
||||
{ code: '<body role="button" />;', errors: [expectedError] },
|
||||
{ code: '<br role="button" />;', errors: [expectedError] },
|
||||
{ code: '<caption role="button" />;', errors: [expectedError] },
|
||||
{ code: '<code role="button" />;', errors: [expectedError] },
|
||||
{ code: '<dd role="button" />;', errors: [expectedError] },
|
||||
{ code: '<del role="button" />;', errors: [expectedError] },
|
||||
{ code: '<details role="button" />;', errors: [expectedError] },
|
||||
{ code: '<dfn role="button" />;', errors: [expectedError] },
|
||||
{ code: '<dir role="button" />;', errors: [expectedError] },
|
||||
{ code: '<dl role="button" />;', errors: [expectedError] },
|
||||
{ code: '<dfn role="button" />;', errors: [expectedError] },
|
||||
{ code: '<dt role="button" />;', errors: [expectedError] },
|
||||
{ code: '<em role="button" />;', errors: [expectedError] },
|
||||
{ code: '<fieldset role="button" />;', errors: [expectedError] },
|
||||
{ code: '<figcaption role="button" />;', errors: [expectedError] },
|
||||
{ code: '<figure role="button" />;', errors: [expectedError] },
|
||||
{ code: '<footer role="button" />;', errors: [expectedError] },
|
||||
{ code: '<form role="button" />;', errors: [expectedError] },
|
||||
{ code: '<frame role="button" />;', errors: [expectedError] },
|
||||
{ code: '<h1 role="button" />;', errors: [expectedError] },
|
||||
{ code: '<h2 role="button" />;', errors: [expectedError] },
|
||||
{ code: '<h3 role="button" />;', errors: [expectedError] },
|
||||
|
|
@ -384,11 +381,14 @@ const neverValid = [
|
|||
{ code: '<h5 role="button" />;', errors: [expectedError] },
|
||||
{ code: '<h6 role="button" />;', errors: [expectedError] },
|
||||
{ code: '<hr role="button" />;', errors: [expectedError] },
|
||||
{ code: '<html role="button" />;', errors: [expectedError] },
|
||||
{ code: '<iframe role="button" />;', errors: [expectedError] },
|
||||
{ code: '<img role="button" />;', errors: [expectedError] },
|
||||
{ code: '<ins role="button" />;', errors: [expectedError] },
|
||||
{ code: '<label role="button" />;', errors: [expectedError] },
|
||||
{ code: '<legend role="button" />;', errors: [expectedError] },
|
||||
{ code: '<li role="button" />;', errors: [expectedError] },
|
||||
{ code: '<main role="button" />;', errors: [expectedError] },
|
||||
{ code: '<mark role="button" />;', errors: [expectedError] },
|
||||
{ code: '<marquee role="button" />;', errors: [expectedError] },
|
||||
{ code: '<menu role="button" />;', errors: [expectedError] },
|
||||
|
|
@ -400,9 +400,11 @@ const neverValid = [
|
|||
{ code: '<pre role="button" />;', errors: [expectedError] },
|
||||
{ code: '<progress role="button" />;', errors: [expectedError] },
|
||||
{ code: '<ruby role="button" />;', errors: [expectedError] },
|
||||
{ code: '<strong role="button" />;', errors: [expectedError] },
|
||||
{ code: '<sub role="button" />;', errors: [expectedError] },
|
||||
{ code: '<sup role="button" />;', errors: [expectedError] },
|
||||
{ code: '<table role="button" />;', errors: [expectedError] },
|
||||
{ code: '<tbody role="button" />;', errors: [expectedError] },
|
||||
{ code: '<td role="button" />;', errors: [expectedError] },
|
||||
{ code: '<tfoot role="button" />;', errors: [expectedError] },
|
||||
{ code: '<thead role="button" />;', errors: [expectedError] },
|
||||
{ code: '<time role="button" />;', errors: [expectedError] },
|
||||
|
|
@ -411,14 +413,12 @@ const neverValid = [
|
|||
* interactive role. */
|
||||
{ code: '<main role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<article role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<article role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<dd role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<dfn role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<dt role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<fieldset role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<figure role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<form role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<frame role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<h1 role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<h2 role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<h3 role="menuitem" />;', errors: [expectedError] },
|
||||
|
|
@ -433,7 +433,6 @@ const neverValid = [
|
|||
{ code: '<section role="button" aria-label="Aardvark" />;', errors: [expectedError] },
|
||||
{ code: '<table role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<tbody role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<td role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<tfoot role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<thead role="menuitem" />;', errors: [expectedError] },
|
||||
/* Custom components */
|
||||
|
|
@ -442,7 +441,7 @@ const neverValid = [
|
|||
|
||||
const recommendedOptions = (configs.recommended.rules[ruleName][1] || {});
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
{ code: '<ul role="menu" />;' },
|
||||
{ code: '<ul role="menubar" />;' },
|
||||
|
|
@ -458,26 +457,28 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
|
|||
{ code: '<ol role="treegrid" />;' },
|
||||
{ code: '<li role="tab" />;' },
|
||||
{ code: '<li role="menuitem" />;' },
|
||||
{ code: '<li role="menuitemcheckbox" />;' },
|
||||
{ code: '<li role="menuitemradio" />;' },
|
||||
{ code: '<li role="row" />;' },
|
||||
{ code: '<li role="treeitem" />;' },
|
||||
{ code: '<Component role="treeitem" />;' },
|
||||
{ code: '<fieldset role="radiogroup" />;' },
|
||||
{ code: '<fieldset role="presentation" />;' },
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
ruleTester.run(`${ruleName}:strict`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
{ code: '<ul role="menu" />;', errors: [expectedError] },
|
||||
{ code: '<ul role="menubar" />;', errors: [expectedError] },
|
||||
|
|
@ -495,5 +496,5 @@ ruleTester.run(`${ruleName}:strict`, rule, {
|
|||
{ code: '<li role="menuitem" />;', errors: [expectedError] },
|
||||
{ code: '<li role="row" />;', errors: [expectedError] },
|
||||
{ code: '<li role="treeitem" />;', errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import { configs } from '../../../src/index';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-noninteractive-tabindex';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ const recommendedOptions = (
|
|||
);
|
||||
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
{ code: '<div role="tabpanel" tabIndex="0" />' },
|
||||
// Expressions should pass in recommended mode
|
||||
|
|
@ -87,21 +88,21 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
|
|||
options: [{ allowExpressionValues: true }],
|
||||
errors: [expectedError],
|
||||
},
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
ruleTester.run(`${ruleName}:strict`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
{ code: '<div role="tabpanel" tabIndex="0" />', errors: [expectedError] },
|
||||
// Expressions should fail in strict mode
|
||||
|
|
@ -118,5 +119,5 @@ ruleTester.run(`${ruleName}:strict`, rule, {
|
|||
options: [{ allowExpressionValues: false }],
|
||||
errors: [expectedError],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-onchange';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -32,7 +33,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('no-onchange', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<select onBlur={() => {}} />;' },
|
||||
{ code: '<select onBlur={handleOnBlur} />;' },
|
||||
{ code: '<option />;' },
|
||||
|
|
@ -45,12 +46,12 @@ ruleTester.run('no-onchange', rule, {
|
|||
{ code: '<input {...props} />' },
|
||||
{ code: '<Input onChange={() => {}} />;', settings: componentsSettings },
|
||||
{ code: '<CustomOption onChange={() => {}} />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<select onChange={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<select onChange={handleOnChange} />;', errors: [expectedError] },
|
||||
{ code: '<option onChange={() => {}} />', errors: [expectedError] },
|
||||
{ code: '<option onChange={() => {}} {...props} />', errors: [expectedError] },
|
||||
{ code: '<CustomOption onChange={() => {}} />;', errors: [expectedError], settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
31
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test.js
generated
vendored
31
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test.js
generated
vendored
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-redundant-roles';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -49,12 +50,14 @@ const neverValid = [
|
|||
];
|
||||
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
...alwaysValid,
|
||||
{ code: '<nav role="navigation" />' },
|
||||
]
|
||||
))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: neverValid
|
||||
invalid: parsers.all([].concat(
|
||||
neverValid,
|
||||
))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
|
|
@ -62,28 +65,34 @@ const noNavExceptionsOptions = { nav: [] };
|
|||
const listException = { ul: ['list'], ol: ['list'] };
|
||||
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: alwaysValid
|
||||
.map(ruleOptionsMapperFactory(noNavExceptionsOptions))
|
||||
valid: parsers.all([].concat(
|
||||
alwaysValid
|
||||
.map(ruleOptionsMapperFactory(noNavExceptionsOptions)),
|
||||
))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
...neverValid,
|
||||
{ code: '<nav role="navigation" />', errors: [expectedError('nav', 'navigation')] },
|
||||
]
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(noNavExceptionsOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
ruleTester.run(`${ruleName}:recommended (valid list role override)`, rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<ul role="list" />' },
|
||||
{ code: '<ol role="list" />' },
|
||||
{ code: '<dl role="list" />' },
|
||||
]
|
||||
{ code: '<img src="example.svg" role="img" />' },
|
||||
{ code: '<svg role="img" />' },
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(listException))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<ul role="list" />', errors: [expectedError('ul', 'list')] },
|
||||
{ code: '<ol role="list" />', errors: [expectedError('ol', 'list')] },
|
||||
]
|
||||
{ code: '<img role="img" />', errors: [expectedError('img', 'img')] },
|
||||
{ code: '<img src={someVariable} role="img" />', errors: [expectedError('img', 'img')] },
|
||||
))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import { configs } from '../../../src/index';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/no-static-element-interactions';
|
||||
import ruleOptionsMapperFactory from '../../__util__/ruleOptionsMapperFactory';
|
||||
|
||||
|
|
@ -84,7 +85,7 @@ const alwaysValid = [
|
|||
{ code: '<audio onClick={() => {}} />;' },
|
||||
{ code: '<form onClick={() => {}} />;' },
|
||||
{ code: '<form onSubmit={() => {}} />;' },
|
||||
{ code: '<link onClick={() => {}} href="#" />;' },
|
||||
// { code: '<link onClick={() => {}} href="#" />;' },
|
||||
/* HTML elements attributed with an interactive role */
|
||||
{ code: '<div role="button" onClick={() => {}} />;' },
|
||||
{ code: '<div role="checkbox" onClick={() => {}} />;' },
|
||||
|
|
@ -110,26 +111,28 @@ const alwaysValid = [
|
|||
{ code: '<div role="presentation" onClick={() => {}} />;' },
|
||||
{ code: '<div role="presentation" onKeyDown={() => {}} />;' },
|
||||
/* HTML elements with an inherent, non-interactive role */
|
||||
{ code: '<address onClick={() => {}} />;' },
|
||||
{ code: '<article onClick={() => {}} />;' },
|
||||
{ code: '<article onDblClick={() => void 0} />;' },
|
||||
{ code: '<aside onClick={() => {}} />;' },
|
||||
{ code: '<blockquote onClick={() => {}} />;' },
|
||||
{ code: '<body onClick={() => {}} />;' },
|
||||
{ code: '<br onClick={() => {}} />;' },
|
||||
{ code: '<canvas onClick={() => {}} />;' },
|
||||
{ code: '<caption onClick={() => {}} />;' },
|
||||
{ code: '<details onClick={() => {}} />;' },
|
||||
{ code: '<code onClick={() => {}} />;' },
|
||||
{ code: '<dd onClick={() => {}} />;' },
|
||||
{ code: '<del onClick={() => {}} />;' },
|
||||
{ code: '<details onClick={() => {}} />;' },
|
||||
{ code: '<dfn onClick={() => {}} />;' },
|
||||
{ code: '<dir onClick={() => {}} />;' },
|
||||
{ code: '<dl onClick={() => {}} />;' },
|
||||
{ code: '<dt onClick={() => {}} />;' },
|
||||
{ code: '<em onClick={() => {}} />;' },
|
||||
{ code: '<embed onClick={() => {}} />;' },
|
||||
{ code: '<fieldset onClick={() => {}} />;' },
|
||||
{ code: '<figcaption onClick={() => {}} />;' },
|
||||
{ code: '<figure onClick={() => {}} />;' },
|
||||
{ code: '<footer onClick={() => {}} />;' },
|
||||
{ code: '<frame onClick={() => {}} />;' },
|
||||
{ code: '<h1 onClick={() => {}} />;' },
|
||||
{ code: '<h2 onClick={() => {}} />;' },
|
||||
{ code: '<h3 onClick={() => {}} />;' },
|
||||
|
|
@ -137,8 +140,10 @@ const alwaysValid = [
|
|||
{ code: '<h5 onClick={() => {}} />;' },
|
||||
{ code: '<h6 onClick={() => {}} />;' },
|
||||
{ code: '<hr onClick={() => {}} />;' },
|
||||
{ code: '<html onClick={() => {}} />;' },
|
||||
{ code: '<iframe onClick={() => {}} />;' },
|
||||
{ code: '<img onClick={() => {}} />;' },
|
||||
{ code: '<ins onClick={() => {}} />;' },
|
||||
{ code: '<label onClick={() => {}} />;' },
|
||||
{ code: '<legend onClick={() => {}} />;' },
|
||||
{ code: '<li onClick={() => {}} />;' },
|
||||
|
|
@ -157,7 +162,10 @@ const alwaysValid = [
|
|||
{ code: '<ruby onClick={() => {}} />;' },
|
||||
{ code: '<section onClick={() => {}} aria-label="Aa" />;' },
|
||||
{ code: '<section onClick={() => {}} aria-labelledby="js_1" />;' },
|
||||
{ code: '<strong onClick={() => {}} />;' },
|
||||
{ code: '<sub onClick={() => {}} />;' },
|
||||
{ code: '<summary onClick={() => {}} />;' },
|
||||
{ code: '<sup onClick={() => {}} />;' },
|
||||
{ code: '<table onClick={() => {}} />;' },
|
||||
{ code: '<tbody onClick={() => {}} />;' },
|
||||
{ code: '<tfoot onClick={() => {}} />;' },
|
||||
|
|
@ -222,7 +230,7 @@ const alwaysValid = [
|
|||
{ code: '<div role="table" onClick={() => {}} />;' },
|
||||
{ code: '<div role="tablist" onClick={() => {}} />;' },
|
||||
{ code: '<div role="tabpanel" onClick={() => {}} />;' },
|
||||
{ code: '<td onClick={() => {}} />;' },
|
||||
// { code: '<td onClick={() => {}} />;' },
|
||||
{ code: '<div role="term" onClick={() => {}} />;' },
|
||||
{ code: '<div role="timer" onClick={() => {}} />;' },
|
||||
{ code: '<div role="toolbar" onClick={() => {}} />;' },
|
||||
|
|
@ -283,37 +291,32 @@ const neverValid = [
|
|||
{ code: '<div onClick={() => void 0} {...props} />;', errors: [expectedError] },
|
||||
{ code: '<div onKeyUp={() => void 0} aria-hidden={false} />;', errors: [expectedError] },
|
||||
/* Static elements; no inherent role */
|
||||
{ code: '<a onClick={() => void 0} />', errors: [expectedError] },
|
||||
{ code: '<a onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<a onClick={() => void 0} />', errors: [expectedError] },
|
||||
{ code: '<a tabIndex="0" onClick={() => void 0} />', errors: [expectedError] },
|
||||
{ code: '<area onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<acronym onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<address onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<applet onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<area onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<b onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<base onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<bdi onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<bdo onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<big onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<blink onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<body onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<center onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<cite onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<code onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<col onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<colgroup onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<content onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<data onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<del onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<div onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<em onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<font onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<frame onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<frameset onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<head onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<header onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<hgroup onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<html onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<i onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<ins onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<kbd onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<keygen onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<map onClick={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -336,10 +339,7 @@ const neverValid = [
|
|||
{ code: '<spacer onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<span onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<strike onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<strong onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<style onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<sub onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<sup onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<title onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<track onClick={() => {}} />;', errors: [expectedError] },
|
||||
{ code: '<tt onClick={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -360,7 +360,7 @@ const neverValid = [
|
|||
|
||||
const recommendedOptions = configs.recommended.rules[`jsx-a11y/${ruleName}`][1] || {};
|
||||
ruleTester.run(`${ruleName}:recommended`, rule, {
|
||||
valid: [].concat(
|
||||
valid: parsers.all([].concat(
|
||||
alwaysValid,
|
||||
// All the possible handlers
|
||||
{ code: '<div onCopy={() => {}} />;' },
|
||||
|
|
@ -449,21 +449,21 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
|
|||
options: [{ allowExpressionValues: true }],
|
||||
errors: [expectedError],
|
||||
},
|
||||
)
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
invalid: [].concat(
|
||||
invalid: parsers.all([].concat(
|
||||
neverValid,
|
||||
)
|
||||
))
|
||||
.map(ruleOptionsMapperFactory(recommendedOptions))
|
||||
.map(parserOptionsMapper),
|
||||
});
|
||||
|
||||
ruleTester.run(`${ruleName}:strict`, rule, {
|
||||
valid: [].concat(
|
||||
valid: parsers.all([].concat(
|
||||
alwaysValid,
|
||||
).map(parserOptionsMapper),
|
||||
invalid: [].concat(
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
neverValid,
|
||||
// All the possible handlers
|
||||
{ code: '<div onContextMenu={() => {}} />;', errors: [expectedError] },
|
||||
|
|
@ -497,5 +497,5 @@ ruleTester.run(`${ruleName}:strict`, rule, {
|
|||
options: [{ allowExpressionValues: false }],
|
||||
errors: [expectedError],
|
||||
},
|
||||
).map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
17
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/prefer-tag-over-role-test.js
generated
vendored
17
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/prefer-tag-over-role-test.js
generated
vendored
|
|
@ -1,5 +1,6 @@
|
|||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/prefer-tag-over-role';
|
||||
|
||||
const ruleTester = new RuleTester();
|
||||
|
|
@ -9,16 +10,16 @@ const expectedError = (role, tag) => ({
|
|||
type: 'JSXOpeningElement',
|
||||
});
|
||||
|
||||
ruleTester.run('element-role', rule, {
|
||||
valid: [
|
||||
ruleTester.run('prefer-tag-over-role', rule, {
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<div role="unknown" />;' },
|
||||
{ code: '<div role="also unknown" />;' },
|
||||
{ code: '<other />' },
|
||||
{ code: '<img role="img" />' },
|
||||
{ code: '<input role="checkbox" />' },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{
|
||||
code: '<div role="checkbox" />',
|
||||
errors: [expectedError('checkbox', '<input type="checkbox">')],
|
||||
|
|
@ -38,7 +39,7 @@ ruleTester.run('element-role', rule, {
|
|||
errors: [
|
||||
expectedError(
|
||||
'link',
|
||||
'<a href=...>, <area href=...>, or <link href=...>',
|
||||
'<a href=...>, or <area href=...>',
|
||||
),
|
||||
],
|
||||
},
|
||||
|
|
@ -54,13 +55,9 @@ ruleTester.run('element-role', rule, {
|
|||
code: '<other role="checkbox" />',
|
||||
errors: [expectedError('checkbox', '<input type="checkbox">')],
|
||||
},
|
||||
{
|
||||
code: '<other role="checkbox" />',
|
||||
errors: [expectedError('checkbox', '<input type="checkbox">')],
|
||||
},
|
||||
{
|
||||
code: '<div role="banner" />',
|
||||
errors: [expectedError('banner', '<header>')],
|
||||
},
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@
|
|||
|
||||
import { roles } from 'aria-query';
|
||||
import { RuleTester } from 'eslint';
|
||||
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/role-has-required-aria-props';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -37,7 +39,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
// Create basic test cases using all valid role types.
|
||||
const basicValidityTests = [...roles.keys()].map((role) => {
|
||||
const basicValidityTests = roles.keys().map((role) => {
|
||||
const {
|
||||
requiredProps: requiredPropKeyValues,
|
||||
} = roles.get(role);
|
||||
|
|
@ -50,7 +52,7 @@ const basicValidityTests = [...roles.keys()].map((role) => {
|
|||
});
|
||||
|
||||
ruleTester.run('role-has-required-aria-props', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<Bar baz />' },
|
||||
{ code: '<MyComponent role="combobox" />' },
|
||||
// Variables should pass, as we are only testing literals.
|
||||
|
|
@ -64,9 +66,11 @@ ruleTester.run('role-has-required-aria-props', rule, {
|
|||
{ code: '<input role="checkbox" aria-checked="false" aria-labelledby="foo" tabindex="0" {...props} type="checkbox" />' },
|
||||
{ code: '<input type="checkbox" role="switch" />' },
|
||||
{ code: '<MyComponent role="checkbox" aria-checked="false" aria-labelledby="foo" tabindex="0" />', settings: componentsSettings },
|
||||
].concat(basicValidityTests).map(parserOptionsMapper),
|
||||
{ code: '<div role="heading" aria-level={2} />' },
|
||||
{ code: '<div role="heading" aria-level="3" />' },
|
||||
)).concat(basicValidityTests).map(parserOptionsMapper),
|
||||
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
// SLIDER
|
||||
{ code: '<div role="slider" />', errors: [errorMessage('slider')] },
|
||||
{
|
||||
|
|
@ -126,5 +130,5 @@ ruleTester.run('role-has-required-aria-props', rule, {
|
|||
},
|
||||
// Custom element
|
||||
{ code: '<MyComponent role="combobox" />', settings: componentsSettings, errors: [errorMessage('combobox')] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
40
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test.js
generated
vendored
40
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test.js
generated
vendored
|
|
@ -14,7 +14,9 @@ import {
|
|||
import { RuleTester } from 'eslint';
|
||||
import { version as eslintVersion } from 'eslint/package.json';
|
||||
import semver from 'semver';
|
||||
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/role-supports-aria-props';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -25,8 +27,7 @@ const ruleTester = new RuleTester();
|
|||
|
||||
const generateErrorMessage = (attr, role, tag, isImplicit) => {
|
||||
if (isImplicit) {
|
||||
return `The attribute ${attr} is not supported by the role ${role}. \
|
||||
This role is implicit on the element ${tag}.`;
|
||||
return `The attribute ${attr} is not supported by the role ${role}. This role is implicit on the element ${tag}.`;
|
||||
}
|
||||
|
||||
return `The attribute ${attr} is not supported by the role ${role}.`;
|
||||
|
|
@ -45,36 +46,33 @@ const componentsSettings = {
|
|||
},
|
||||
};
|
||||
|
||||
const nonAbstractRoles = [...roles.keys()].filter((role) => roles.get(role).abstract === false);
|
||||
const nonAbstractRoles = roles.keys().filter((role) => roles.get(role).abstract === false);
|
||||
|
||||
const createTests = (rolesNames) => rolesNames.reduce((tests, role) => {
|
||||
const {
|
||||
props: propKeyValues,
|
||||
} = roles.get(role);
|
||||
const validPropsForRole = Object.keys(propKeyValues);
|
||||
const invalidPropsForRole = [...aria.keys()]
|
||||
const invalidPropsForRole = aria.keys()
|
||||
.map((attribute) => attribute.toLowerCase())
|
||||
.filter((attribute) => validPropsForRole.indexOf(attribute) === -1);
|
||||
const normalRole = role.toLowerCase();
|
||||
|
||||
const allTests = [];
|
||||
|
||||
allTests[0] = tests[0].concat(validPropsForRole.map((prop) => ({
|
||||
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
|
||||
})));
|
||||
|
||||
allTests[1] = tests[1].concat(invalidPropsForRole.map((prop) => ({
|
||||
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
|
||||
errors: [errorMessage(prop.toLowerCase(), normalRole, 'div', false)],
|
||||
})));
|
||||
|
||||
return allTests;
|
||||
return [
|
||||
tests[0].concat(validPropsForRole.map((prop) => ({
|
||||
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
|
||||
}))),
|
||||
tests[1].concat(invalidPropsForRole.map((prop) => ({
|
||||
code: `<div role="${normalRole}" ${prop.toLowerCase()} />`,
|
||||
errors: [errorMessage(prop.toLowerCase(), normalRole, 'div', false)],
|
||||
}))),
|
||||
];
|
||||
}, [[], []]);
|
||||
|
||||
const [validTests, invalidTests] = createTests(nonAbstractRoles);
|
||||
|
||||
ruleTester.run('role-supports-aria-props', rule, {
|
||||
valid: [].concat(
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<Foo bar />' },
|
||||
{ code: '<div />' },
|
||||
{ code: '<div id="main" />' },
|
||||
|
|
@ -410,14 +408,14 @@ ruleTester.run('role-supports-aria-props', rule, {
|
|||
}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
const Hello = (props) => <div>{props.frag}</div>;
|
||||
`,
|
||||
} : [],
|
||||
validTests,
|
||||
).map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
// implicit basic checks
|
||||
{
|
||||
code: '<a href="#" aria-checked />',
|
||||
|
|
@ -568,5 +566,5 @@ ruleTester.run('role-supports-aria-props', rule, {
|
|||
errors: [errorMessage('aria-checked', 'link', 'a', true)],
|
||||
settings: componentsSettings,
|
||||
},
|
||||
].concat(invalidTests).map(parserOptionsMapper),
|
||||
)).concat(invalidTests).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/scope';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -32,7 +33,7 @@ const componentsSettings = {
|
|||
};
|
||||
|
||||
ruleTester.run('scope', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<div foo />;' },
|
||||
{ code: '<th scope />' },
|
||||
|
|
@ -41,9 +42,9 @@ ruleTester.run('scope', rule, {
|
|||
{ code: '<th scope={"col"} {...props} />' },
|
||||
{ code: '<Foo scope="bar" {...props} />' },
|
||||
{ code: '<TableHeader scope="row" />', settings: componentsSettings },
|
||||
].map(parserOptionsMapper),
|
||||
invalid: [
|
||||
)).map(parserOptionsMapper),
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div scope />', errors: [expectedError] },
|
||||
{ code: '<Foo scope="bar" />', settings: componentsSettings, errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test.js
generated
vendored
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { RuleTester } from 'eslint';
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
import parsers from '../../__util__/helpers/parsers';
|
||||
import rule from '../../../src/rules/tabindex-no-positive';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -23,7 +24,7 @@ const expectedError = {
|
|||
};
|
||||
|
||||
ruleTester.run('tabindex-no-positive', rule, {
|
||||
valid: [
|
||||
valid: parsers.all([].concat(
|
||||
{ code: '<div />;' },
|
||||
{ code: '<div {...props} />' },
|
||||
{ code: '<div id="main" />' },
|
||||
|
|
@ -42,13 +43,13 @@ ruleTester.run('tabindex-no-positive', rule, {
|
|||
{ code: '<div tabIndex="-5.5" />' },
|
||||
{ code: '<div tabIndex={-5.5} />' },
|
||||
{ code: '<div tabIndex={-5} />' },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
|
||||
invalid: [
|
||||
invalid: parsers.all([].concat(
|
||||
{ code: '<div tabIndex="1" />', errors: [expectedError] },
|
||||
{ code: '<div tabIndex={1} />', errors: [expectedError] },
|
||||
{ code: '<div tabIndex={"1"} />', errors: [expectedError] },
|
||||
{ code: '<div tabIndex={`1`} />', errors: [expectedError] },
|
||||
{ code: '<div tabIndex={1.589} />', errors: [expectedError] },
|
||||
].map(parserOptionsMapper),
|
||||
)).map(parserOptionsMapper),
|
||||
});
|
||||
|
|
|
|||
196
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/attributesComparator-test.js
generated
vendored
196
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/attributesComparator-test.js
generated
vendored
|
|
@ -1,115 +1,91 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import attributesComparator from '../../../src/util/attributesComparator';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
|
||||
describe('attributesComparator', () => {
|
||||
describe('base attributes', () => {
|
||||
let baseAttributes;
|
||||
let attributes;
|
||||
describe('are undefined', () => {
|
||||
describe('and attributes are undefined', () => {
|
||||
it('should return true', () => {
|
||||
expect(attributesComparator()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('are empty', () => {
|
||||
beforeEach(() => {
|
||||
baseAttributes = [];
|
||||
});
|
||||
describe('and attributes', () => {
|
||||
describe('are empty', () => {
|
||||
attributes = [];
|
||||
it('should return true', () => {
|
||||
expect(attributesComparator(baseAttributes, attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
describe('have values', () => {
|
||||
attributes = [
|
||||
JSXAttributeMock('foo', 0),
|
||||
JSXAttributeMock('bar', 'baz'),
|
||||
];
|
||||
it('should return true', () => {
|
||||
expect(attributesComparator(baseAttributes, attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('have values', () => {
|
||||
beforeEach(() => {
|
||||
baseAttributes = [
|
||||
{
|
||||
name: 'biz',
|
||||
value: 1,
|
||||
}, {
|
||||
name: 'fizz',
|
||||
value: 'pop',
|
||||
}, {
|
||||
name: 'fuzz',
|
||||
value: 'lolz',
|
||||
},
|
||||
];
|
||||
});
|
||||
describe('and attributes', () => {
|
||||
describe('are empty', () => {
|
||||
attributes = [];
|
||||
it('should return false', () => {
|
||||
expect(attributesComparator(baseAttributes, attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('have values', () => {
|
||||
describe('and the values are the different', () => {
|
||||
it('should return false', () => {
|
||||
attributes = [
|
||||
JSXElementMock(),
|
||||
JSXAttributeMock('biz', 2),
|
||||
JSXAttributeMock('ziff', 'opo'),
|
||||
JSXAttributeMock('far', 'lolz'),
|
||||
];
|
||||
expect(attributesComparator(baseAttributes, attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('and the values are a subset', () => {
|
||||
it('should return true', () => {
|
||||
attributes = [
|
||||
JSXAttributeMock('biz', 1),
|
||||
JSXAttributeMock('fizz', 'pop'),
|
||||
JSXAttributeMock('goo', 'gazz'),
|
||||
];
|
||||
expect(attributesComparator(baseAttributes, attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('and the values are the same', () => {
|
||||
it('should return true', () => {
|
||||
attributes = [
|
||||
JSXAttributeMock('biz', 1),
|
||||
JSXAttributeMock('fizz', 'pop'),
|
||||
JSXAttributeMock('fuzz', 'lolz'),
|
||||
];
|
||||
expect(attributesComparator(baseAttributes, attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
describe('and the values are a superset', () => {
|
||||
it('should return true', () => {
|
||||
attributes = [
|
||||
JSXAttributeMock('biz', 1),
|
||||
JSXAttributeMock('fizz', 'pop'),
|
||||
JSXAttributeMock('fuzz', 'lolz'),
|
||||
JSXAttributeMock('dar', 'tee'),
|
||||
];
|
||||
expect(attributesComparator(baseAttributes, attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
test('attributesComparator', (t) => {
|
||||
t.equal(
|
||||
attributesComparator(),
|
||||
true,
|
||||
'baseAttributes are undefined and attributes are undefined -> true',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
attributesComparator([], []),
|
||||
true,
|
||||
'baseAttributes are empty and attributes are empty -> true',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
attributesComparator([], [
|
||||
JSXAttributeMock('foo', 0),
|
||||
JSXAttributeMock('bar', 'baz'),
|
||||
]),
|
||||
true,
|
||||
'baseAttributes are empty and attributes have values -> true',
|
||||
);
|
||||
|
||||
const baseAttributes = [
|
||||
{
|
||||
name: 'biz',
|
||||
value: 1,
|
||||
}, {
|
||||
name: 'fizz',
|
||||
value: 'pop',
|
||||
}, {
|
||||
name: 'fuzz',
|
||||
value: 'lolz',
|
||||
},
|
||||
];
|
||||
|
||||
t.equal(
|
||||
attributesComparator(baseAttributes, []),
|
||||
false,
|
||||
'baseAttributes have values and attributes are empty -> false',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
attributesComparator(baseAttributes, [
|
||||
JSXElementMock(),
|
||||
JSXAttributeMock('biz', 2),
|
||||
JSXAttributeMock('ziff', 'opo'),
|
||||
JSXAttributeMock('far', 'lolz'),
|
||||
]),
|
||||
false,
|
||||
'baseAttributes have values and attributes have values, and the values are different -> false',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
attributesComparator(baseAttributes, [
|
||||
JSXAttributeMock('biz', 1),
|
||||
JSXAttributeMock('fizz', 'pop'),
|
||||
JSXAttributeMock('goo', 'gazz'),
|
||||
]),
|
||||
false,
|
||||
'baseAttributes have values and attributes have values, and the values are a subset -> false',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
attributesComparator(baseAttributes, [
|
||||
JSXAttributeMock('biz', 1),
|
||||
JSXAttributeMock('fizz', 'pop'),
|
||||
JSXAttributeMock('fuzz', 'lolz'),
|
||||
]),
|
||||
true,
|
||||
'baseAttributes have values and attributes have values, and the values are the same -> true',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
attributesComparator(baseAttributes, [
|
||||
JSXAttributeMock('biz', 1),
|
||||
JSXAttributeMock('fizz', 'pop'),
|
||||
JSXAttributeMock('fuzz', 'lolz'),
|
||||
JSXAttributeMock('dar', 'tee'),
|
||||
]),
|
||||
true,
|
||||
'baseAttributes have values and attributes have values, and the values are a superset -> true',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
157
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getAccessibleChildText-test.js
generated
vendored
157
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getAccessibleChildText-test.js
generated
vendored
|
|
@ -1,95 +1,116 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import getAccessibleChildText from '../../../src/util/getAccessibleChildText';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
|
||||
describe('getAccessibleChildText', () => {
|
||||
it('returns the aria-label when present', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
test('getAccessibleChildText', (t) => {
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[JSXAttributeMock('aria-label', 'foo')],
|
||||
), elementType)).toBe('foo');
|
||||
});
|
||||
), elementType),
|
||||
'foo',
|
||||
'returns the aria-label when present',
|
||||
);
|
||||
|
||||
it('returns the aria-label instead of children', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[JSXAttributeMock('aria-label', 'foo')],
|
||||
[{ type: 'JSXText', value: 'bar' }],
|
||||
), elementType)).toBe('foo');
|
||||
});
|
||||
), elementType),
|
||||
'foo',
|
||||
'returns the aria-label instead of children',
|
||||
);
|
||||
|
||||
it('skips elements with aria-hidden=true', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[JSXAttributeMock('aria-hidden', 'true')],
|
||||
), elementType)).toBe('');
|
||||
});
|
||||
), elementType),
|
||||
'',
|
||||
'skips elements with aria-hidden=true',
|
||||
);
|
||||
|
||||
it('returns literal value for JSXText child', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'JSXText', value: 'bar' }],
|
||||
), elementType)).toBe('bar');
|
||||
});
|
||||
), elementType),
|
||||
'bar',
|
||||
'returns literal value for JSXText child',
|
||||
);
|
||||
|
||||
it('returns alt text for img child', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
JSXAttributeMock('alt', 'a sensible label'),
|
||||
])],
|
||||
), elementType)).toBe('a sensible label');
|
||||
});
|
||||
), elementType),
|
||||
'a sensible label',
|
||||
'returns alt text for img child',
|
||||
);
|
||||
|
||||
it('returns blank when alt tag is used on arbitrary element', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[JSXElementMock('span', [
|
||||
JSXAttributeMock('alt', 'a sensible label'),
|
||||
])],
|
||||
), elementType)).toBe('');
|
||||
});
|
||||
), elementType),
|
||||
'',
|
||||
'returns blank when alt tag is used on arbitrary element',
|
||||
);
|
||||
|
||||
it('returns literal value for JSXText child', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'Literal', value: 'bar' }],
|
||||
), elementType)).toBe('bar');
|
||||
});
|
||||
), elementType),
|
||||
'bar',
|
||||
'returns literal value for JSXText child',
|
||||
);
|
||||
|
||||
it('returns trimmed literal value for JSXText child', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'Literal', value: ' bar ' }],
|
||||
), elementType)).toBe('bar');
|
||||
});
|
||||
), elementType),
|
||||
'bar',
|
||||
'returns trimmed literal value for JSXText child',
|
||||
);
|
||||
|
||||
it('returns space-collapsed literal value for JSXText child', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'Literal', value: 'foo bar' }],
|
||||
), elementType)).toBe('foo bar');
|
||||
});
|
||||
), elementType),
|
||||
'foo bar',
|
||||
'returns space-collapsed literal value for JSXText child',
|
||||
);
|
||||
|
||||
it('returns punctuation-stripped literal value for JSXText child', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'Literal', value: 'foo, bar. baz? foo; bar:' }],
|
||||
), elementType)).toBe('foo bar baz foo bar');
|
||||
});
|
||||
), elementType),
|
||||
'foo bar baz foo bar',
|
||||
'returns punctuation-stripped literal value for JSXText child',
|
||||
);
|
||||
|
||||
it('returns recursive value for JSXElement child', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[JSXElementMock(
|
||||
|
|
@ -97,11 +118,13 @@ describe('getAccessibleChildText', () => {
|
|||
[],
|
||||
[{ type: 'Literal', value: 'bar' }],
|
||||
)],
|
||||
), elementType)).toBe('bar');
|
||||
});
|
||||
), elementType),
|
||||
'bar',
|
||||
'returns recursive value for JSXElement child',
|
||||
);
|
||||
|
||||
it('skips children with aria-hidden-true', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[JSXElementMock(
|
||||
|
|
@ -112,30 +135,40 @@ describe('getAccessibleChildText', () => {
|
|||
[JSXAttributeMock('aria-hidden', 'true')],
|
||||
)],
|
||||
)],
|
||||
), elementType)).toBe('');
|
||||
});
|
||||
), elementType),
|
||||
'',
|
||||
'skips children with aria-hidden-true',
|
||||
);
|
||||
|
||||
it('joins multiple children properly - no spacing', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'Literal', value: 'foo' }, { type: 'Literal', value: 'bar' }],
|
||||
), elementType)).toBe('foo bar');
|
||||
});
|
||||
), elementType),
|
||||
'foo bar',
|
||||
'joins multiple children properly - no spacing',
|
||||
);
|
||||
|
||||
it('joins multiple children properly - with spacing', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'Literal', value: ' foo ' }, { type: 'Literal', value: ' bar ' }],
|
||||
), elementType)).toBe('foo bar');
|
||||
});
|
||||
), elementType),
|
||||
'foo bar',
|
||||
'joins multiple children properly - with spacing',
|
||||
);
|
||||
|
||||
it('skips unknown elements', () => {
|
||||
expect(getAccessibleChildText(JSXElementMock(
|
||||
t.equal(
|
||||
getAccessibleChildText(JSXElementMock(
|
||||
'a',
|
||||
[],
|
||||
[{ type: 'Literal', value: 'foo' }, { type: 'Unknown' }, { type: 'Literal', value: 'bar' }],
|
||||
), elementType)).toBe('foo bar');
|
||||
});
|
||||
), elementType),
|
||||
'foo bar',
|
||||
'skips unknown elements',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
132
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getComputedRole-test.js
generated
vendored
132
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getComputedRole-test.js
generated
vendored
|
|
@ -1,71 +1,71 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import getComputedRole from '../../../src/util/getComputedRole';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
describe('getComputedRole', () => {
|
||||
describe('explicit role', () => {
|
||||
describe('valid role', () => {
|
||||
it('should return the role', () => {
|
||||
expect(getComputedRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'button')],
|
||||
)).toBe('button');
|
||||
});
|
||||
});
|
||||
describe('invalid role', () => {
|
||||
describe('has implicit', () => {
|
||||
it('should return the implicit role', () => {
|
||||
expect(getComputedRole(
|
||||
'li',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
)).toBe('listitem');
|
||||
});
|
||||
});
|
||||
describe('lacks implicit', () => {
|
||||
it('should return null', () => {
|
||||
expect(getComputedRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
)).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
test('getComputedRole', (t) => {
|
||||
t.equal(
|
||||
getComputedRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'button')],
|
||||
),
|
||||
'button',
|
||||
'explicit role + valid role -> returns the role',
|
||||
);
|
||||
|
||||
describe('no role', () => {
|
||||
describe('has implicit', () => {
|
||||
it('should return the implicit role', () => {
|
||||
expect(getComputedRole(
|
||||
'li',
|
||||
[],
|
||||
)).toBe('listitem');
|
||||
});
|
||||
});
|
||||
describe('lacks implicit', () => {
|
||||
it('should return null', () => {
|
||||
expect(getComputedRole(
|
||||
'div',
|
||||
[],
|
||||
)).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('implicit role', () => {
|
||||
describe('has implicit', () => {
|
||||
it('should return the implicit role', () => {
|
||||
expect(getComputedRole(
|
||||
'li',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
)).toBe('listitem');
|
||||
});
|
||||
});
|
||||
describe('lacks implicit', () => {
|
||||
it('should return null', () => {
|
||||
expect(getComputedRole(
|
||||
'div',
|
||||
[],
|
||||
)).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
t.equal(
|
||||
getComputedRole(
|
||||
'li',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
),
|
||||
'listitem',
|
||||
'explicit role + invalid role + has implicit -> returns the implicit role',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getComputedRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
),
|
||||
null,
|
||||
'explicit role + invalid role + lacks implicit -> returns null',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getComputedRole(
|
||||
'li',
|
||||
[],
|
||||
),
|
||||
'listitem',
|
||||
'explicit role + no role + has implicit -> returns the implicit role',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getComputedRole(
|
||||
'div',
|
||||
[],
|
||||
),
|
||||
null,
|
||||
'explicit role + no role + lacks implicit -> returns null',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getComputedRole(
|
||||
'li',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
),
|
||||
'listitem',
|
||||
'implicit role + has implicit -> returns the implicit role',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getComputedRole(
|
||||
'div',
|
||||
[],
|
||||
),
|
||||
null,
|
||||
'implicit role + lacks implicit -> returns null',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
153
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getElementType-test.js
generated
vendored
153
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getElementType-test.js
generated
vendored
|
|
@ -1,25 +1,41 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import getElementType from '../../../src/util/getElementType';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
describe('getElementType', () => {
|
||||
describe('no settings in context', () => {
|
||||
test('getElementType', (t) => {
|
||||
t.test('no settings in context', (st) => {
|
||||
const elementType = getElementType({ settings: {} });
|
||||
|
||||
it('should return the exact tag name for a DOM element', () => {
|
||||
expect(elementType(JSXElementMock('input').openingElement)).toBe('input');
|
||||
});
|
||||
st.equal(
|
||||
elementType(JSXElementMock('input').openingElement),
|
||||
'input',
|
||||
'returns the exact tag name for a DOM element',
|
||||
);
|
||||
|
||||
it('should return the exact tag name for a custom element', () => {
|
||||
expect(elementType(JSXElementMock('CustomInput').openingElement)).toBe('CustomInput');
|
||||
});
|
||||
st.equal(
|
||||
elementType(JSXElementMock('CustomInput').openingElement),
|
||||
'CustomInput',
|
||||
'returns the exact tag name for a custom element',
|
||||
);
|
||||
|
||||
it('should return the exact tag name for names that are in Object.prototype', () => {
|
||||
expect(elementType(JSXElementMock('toString').openingElement)).toBe('toString');
|
||||
});
|
||||
st.equal(
|
||||
elementType(JSXElementMock('toString').openingElement),
|
||||
'toString',
|
||||
'returns the exact tag name for names that are in Object.prototype',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('span', [JSXAttributeMock('as', 'h1')]).openingElement),
|
||||
'span',
|
||||
'returns the default tag name provided',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
describe('components settings in context', () => {
|
||||
t.test('components settings in context', (st) => {
|
||||
const elementType = getElementType({
|
||||
settings: {
|
||||
'jsx-a11y': {
|
||||
|
|
@ -30,16 +46,109 @@ describe('getElementType', () => {
|
|||
},
|
||||
});
|
||||
|
||||
it('should return the exact tag name for a DOM element', () => {
|
||||
expect(elementType(JSXElementMock('input').openingElement)).toBe('input');
|
||||
});
|
||||
st.equal(
|
||||
elementType(JSXElementMock('input').openingElement),
|
||||
'input',
|
||||
'returns the exact tag name for a DOM element',
|
||||
);
|
||||
|
||||
it('should return the mapped tag name for a custom element', () => {
|
||||
expect(elementType(JSXElementMock('CustomInput').openingElement)).toBe('input');
|
||||
});
|
||||
st.equal(
|
||||
elementType(JSXElementMock('CustomInput').openingElement),
|
||||
'input',
|
||||
'returns the mapped tag name for a custom element',
|
||||
);
|
||||
|
||||
it('should return the exact tag name for a custom element not in the components map', () => {
|
||||
expect(elementType(JSXElementMock('CityInput').openingElement)).toBe('CityInput');
|
||||
});
|
||||
st.equal(
|
||||
elementType(JSXElementMock('CityInput').openingElement),
|
||||
'CityInput',
|
||||
'returns the exact tag name for a custom element not in the components map',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('span', [JSXAttributeMock('as', 'h1')]).openingElement),
|
||||
'span',
|
||||
'return the default tag name since not polymorphicPropName was provided',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('polymorphicPropName settings in context', (st) => {
|
||||
const elementType = getElementType({
|
||||
settings: {
|
||||
'jsx-a11y': {
|
||||
polymorphicPropName: 'asChild',
|
||||
components: {
|
||||
CustomButton: 'button',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('span', [JSXAttributeMock('asChild', 'h1')]).openingElement),
|
||||
'h1',
|
||||
'returns the tag name provided by the polymorphic prop, "asChild", defined in the settings',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('CustomButton', [JSXAttributeMock('asChild', 'a')]).openingElement),
|
||||
'a',
|
||||
'returns the tag name provided by the polymorphic prop, "asChild", defined in the settings instead of the component mapping tag',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('CustomButton', [JSXAttributeMock('as', 'a')]).openingElement),
|
||||
'button',
|
||||
'returns the tag name provided by the componnet mapping if the polymorphic prop, "asChild", defined in the settings is not set',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('polymorphicPropName settings and explicitly defined polymorphicAllowList in context', (st) => {
|
||||
const elementType = getElementType({
|
||||
settings: {
|
||||
'jsx-a11y': {
|
||||
polymorphicPropName: 'asChild',
|
||||
polymorphicAllowList: [
|
||||
'Box',
|
||||
'Icon',
|
||||
],
|
||||
components: {
|
||||
Box: 'div',
|
||||
Icon: 'svg',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('Spinner', [JSXAttributeMock('asChild', 'img')]).openingElement),
|
||||
'Spinner',
|
||||
'does not use the polymorphic prop if polymorphicAllowList is defined, but element is not part of polymorphicAllowList',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('Icon', [JSXAttributeMock('asChild', 'img')]).openingElement),
|
||||
'img',
|
||||
'uses the polymorphic prop if it is in explicitly defined polymorphicAllowList',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('Box', [JSXAttributeMock('asChild', 'span')]).openingElement),
|
||||
'span',
|
||||
'returns the tag name provided by the polymorphic prop, "asChild", defined in the settings instead of the component mapping tag',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
elementType(JSXElementMock('Box', [JSXAttributeMock('as', 'a')]).openingElement),
|
||||
'div',
|
||||
'returns the tag name provided by the component mapping if the polymorphic prop, "asChild", defined in the settings is not set',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
57
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getExplicitRole-test.js
generated
vendored
57
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getExplicitRole-test.js
generated
vendored
|
|
@ -1,30 +1,35 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import getExplicitRole from '../../../src/util/getExplicitRole';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
describe('getExplicitRole', () => {
|
||||
describe('valid role', () => {
|
||||
it('should return the role', () => {
|
||||
expect(getExplicitRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'button')],
|
||||
)).toBe('button');
|
||||
});
|
||||
});
|
||||
describe('invalid role', () => {
|
||||
it('should return null', () => {
|
||||
expect(getExplicitRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
)).toBeNull();
|
||||
});
|
||||
});
|
||||
describe('no role', () => {
|
||||
it('should return null', () => {
|
||||
expect(getExplicitRole(
|
||||
'div',
|
||||
[],
|
||||
)).toBeNull();
|
||||
});
|
||||
});
|
||||
test('getExplicitRole', (t) => {
|
||||
t.equal(
|
||||
getExplicitRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'button')],
|
||||
),
|
||||
'button',
|
||||
'valid role returns the role',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getExplicitRole(
|
||||
'div',
|
||||
[JSXAttributeMock('role', 'beeswax')],
|
||||
),
|
||||
null,
|
||||
'invalid role returns null',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getExplicitRole(
|
||||
'div',
|
||||
[],
|
||||
),
|
||||
null,
|
||||
'no role returns null',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
40
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getImplicitRole-test.js
generated
vendored
40
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getImplicitRole-test.js
generated
vendored
|
|
@ -1,21 +1,25 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import getImplicitRole from '../../../src/util/getImplicitRole';
|
||||
|
||||
describe('getImplicitRole', () => {
|
||||
describe('has implicit', () => {
|
||||
it('should return the implicit role', () => {
|
||||
expect(getImplicitRole(
|
||||
'li',
|
||||
[],
|
||||
)).toBe('listitem');
|
||||
});
|
||||
});
|
||||
describe('lacks implicit', () => {
|
||||
it('should return null', () => {
|
||||
expect(getImplicitRole(
|
||||
'div',
|
||||
[],
|
||||
)).toBeNull();
|
||||
});
|
||||
});
|
||||
test('getImplicitRole', (t) => {
|
||||
t.equal(
|
||||
getImplicitRole(
|
||||
'li',
|
||||
[],
|
||||
),
|
||||
'listitem',
|
||||
'has implicit, returns implicit role',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRole(
|
||||
'div',
|
||||
[],
|
||||
),
|
||||
null,
|
||||
'lacks implicit, returns null',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
65
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test.js
generated
vendored
65
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test.js
generated
vendored
|
|
@ -1,48 +1,33 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import getSuggestion from '../../../src/util/getSuggestion';
|
||||
|
||||
describe('spell check suggestion API', () => {
|
||||
it('should return no suggestions given empty word and no dictionary', () => {
|
||||
const word = '';
|
||||
const expected = [];
|
||||
const actual = getSuggestion(word);
|
||||
test('spell check suggestion API', (t) => {
|
||||
t.deepEqual([], getSuggestion('foo'), 'returns no suggestions given empty word and no dictionary');
|
||||
|
||||
expect(expected).toEqual(actual);
|
||||
});
|
||||
t.deepEqual(
|
||||
getSuggestion('foo'),
|
||||
[],
|
||||
'returns no suggestions given real word and no dictionary',
|
||||
);
|
||||
|
||||
it('should return no suggestions given real word and no dictionary', () => {
|
||||
const word = 'foo';
|
||||
const expected = [];
|
||||
const actual = getSuggestion(word);
|
||||
t.deepEqual(
|
||||
getSuggestion('fo', ['foo', 'bar', 'baz']),
|
||||
['foo'],
|
||||
'returns correct suggestion given real word and a dictionary',
|
||||
);
|
||||
|
||||
expect(expected).toEqual(actual);
|
||||
});
|
||||
t.deepEqual(
|
||||
getSuggestion('theer', ['there', 'their', 'foo', 'bar']),
|
||||
['there', 'their'],
|
||||
'returns multiple correct suggestions given real word and a dictionary',
|
||||
);
|
||||
|
||||
it('should return correct suggestion given real word and a dictionary', () => {
|
||||
const word = 'fo';
|
||||
const dictionary = ['foo', 'bar', 'baz'];
|
||||
const expected = ['foo'];
|
||||
const actual = getSuggestion(word, dictionary);
|
||||
t.deepEqual(
|
||||
getSuggestion('theer', ['there', 'their', 'foo', 'bar'], 1),
|
||||
['there'],
|
||||
'returns correct # of suggestions given the limit argument',
|
||||
);
|
||||
|
||||
expect(expected).toEqual(actual);
|
||||
});
|
||||
|
||||
it('should return multiple correct suggestions given real word and a dictionary', () => {
|
||||
const word = 'theer';
|
||||
const dictionary = ['there', 'their', 'foo', 'bar'];
|
||||
const expected = ['there', 'their'];
|
||||
const actual = getSuggestion(word, dictionary);
|
||||
|
||||
expect(expected).toEqual(actual);
|
||||
});
|
||||
|
||||
it('should return correct # of suggestions given the limit argument', () => {
|
||||
const word = 'theer';
|
||||
const dictionary = ['there', 'their', 'foo', 'bar'];
|
||||
const limit = 1;
|
||||
const expected = 1;
|
||||
const actual = getSuggestion(word, dictionary, limit).length;
|
||||
|
||||
expect(expected).toEqual(actual);
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
158
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test.js
generated
vendored
158
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test.js
generated
vendored
|
|
@ -1,83 +1,85 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import getTabIndex from '../../../src/util/getTabIndex';
|
||||
import IdentifierMock from '../../../__mocks__/IdentifierMock';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
describe('getTabIndex', () => {
|
||||
describe('tabIndex is defined', () => {
|
||||
describe('as a number ', () => {
|
||||
describe('zero', () => {
|
||||
it('should return zero', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', 0))).toBe(0);
|
||||
});
|
||||
});
|
||||
describe('positive integer', () => {
|
||||
it('should return the integer', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', 1))).toBe(1);
|
||||
});
|
||||
});
|
||||
describe('negative integer', () => {
|
||||
it('should return the integer', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', -1))).toBe(-1);
|
||||
});
|
||||
});
|
||||
describe('float', () => {
|
||||
it('should return undefined', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', 9.1))).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('as a string', () => {
|
||||
describe('empty', () => {
|
||||
it('should return undefined', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', ''))).toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('which converts to a number', () => {
|
||||
it('should return an integer', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', '0'))).toBe(0);
|
||||
});
|
||||
});
|
||||
describe('which is NaN', () => {
|
||||
it('should return undefined', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', '0a'))).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('as a boolean', () => {
|
||||
describe('true', () => {
|
||||
it('should return undefined', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', true))).toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('false', () => {
|
||||
it('should return undefined', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', false))).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('as an expression', () => {
|
||||
describe('function expression', () => {
|
||||
it('should return the correct type', () => {
|
||||
const attr = function mockFn() { return 0; };
|
||||
expect(typeof getTabIndex(JSXAttributeMock('tabIndex', attr))).toEqual('function');
|
||||
});
|
||||
});
|
||||
describe('variable expression', () => {
|
||||
it('should return the Identifier name', () => {
|
||||
const name = 'identName';
|
||||
expect(getTabIndex(JSXAttributeMock(
|
||||
'tabIndex',
|
||||
IdentifierMock(name),
|
||||
true,
|
||||
))).toEqual(name);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('tabIndex is not defined', () => {
|
||||
it('should return undefined', () => {
|
||||
expect(getTabIndex(JSXAttributeMock('tabIndex', undefined))).toBeUndefined();
|
||||
});
|
||||
});
|
||||
test('getTabIndex', (t) => {
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', 0)),
|
||||
0,
|
||||
'tabIndex is defined as zero -> zero',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', 1)),
|
||||
1,
|
||||
'tabIndex is defined as a positive integer -> returns it',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', -1)),
|
||||
-1,
|
||||
'tabIndex is defined as a negative integer -> returns it',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', '')),
|
||||
undefined,
|
||||
'tabIndex is defined as an empty string -> undefined',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', 9.1)),
|
||||
undefined,
|
||||
'tabIndex is defined as a float -> undefined',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', '0')),
|
||||
0,
|
||||
'tabIndex is defined as a string which converts to a number -> returns the integer',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', '0a')),
|
||||
undefined,
|
||||
'tabIndex is defined as a string which is NaN -> returns undefined',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', true)),
|
||||
undefined,
|
||||
'tabIndex is defined as true -> returns undefined',
|
||||
);
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', false)),
|
||||
undefined,
|
||||
'tabIndex is defined as false -> returns undefined',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
typeof getTabIndex(JSXAttributeMock('tabIndex', () => 0)),
|
||||
'function',
|
||||
'tabIndex is defined as a function expression -> returns the correct type',
|
||||
);
|
||||
|
||||
const name = 'identName';
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock(
|
||||
'tabIndex',
|
||||
IdentifierMock(name),
|
||||
true,
|
||||
)),
|
||||
name,
|
||||
'tabIndex is defined as a variable expression -> returns the Identifier name',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getTabIndex(JSXAttributeMock('tabIndex', undefined)),
|
||||
undefined,
|
||||
'tabIndex is not defined -> returns undefined',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
220
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/hasAccessibleChild-test.js
generated
vendored
220
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/hasAccessibleChild-test.js
generated
vendored
|
|
@ -1,107 +1,157 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import hasAccessibleChild from '../../../src/util/hasAccessibleChild';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
import JSXExpressionContainerMock from '../../../__mocks__/JSXExpressionContainerMock';
|
||||
|
||||
describe('hasAccessibleChild', () => {
|
||||
describe('has no children and does not set dangerouslySetInnerHTML', () => {
|
||||
it('returns false', () => {
|
||||
expect(hasAccessibleChild(JSXElementMock('div', []), elementType)).toBe(false);
|
||||
});
|
||||
});
|
||||
test('hasAccessibleChild', (t) => {
|
||||
t.equal(
|
||||
hasAccessibleChild(JSXElementMock('div', []), elementType),
|
||||
false,
|
||||
'has no children and does not set dangerouslySetInnerHTML -> false',
|
||||
);
|
||||
|
||||
describe('has no children and sets dangerouslySetInnerHTML', () => {
|
||||
it('Returns true', () => {
|
||||
const prop = JSXAttributeMock('dangerouslySetInnerHTML', true);
|
||||
const element = JSXElementMock('div', [prop], []);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(true);
|
||||
});
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [JSXAttributeMock('dangerouslySetInnerHTML', true)], []),
|
||||
elementType,
|
||||
),
|
||||
true,
|
||||
'has no children and sets dangerouslySetInnerHTML -> true',
|
||||
);
|
||||
|
||||
describe('has children', () => {
|
||||
it('Returns true for a Literal child', () => {
|
||||
const child = {
|
||||
type: 'Literal',
|
||||
value: 'foo',
|
||||
};
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(true);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock(
|
||||
'div',
|
||||
[],
|
||||
[{
|
||||
type: 'Literal',
|
||||
value: 'foo',
|
||||
}],
|
||||
),
|
||||
elementType,
|
||||
),
|
||||
true,
|
||||
'has children + Literal child -> true',
|
||||
);
|
||||
|
||||
it('Returns true for visible child JSXElement', () => {
|
||||
const child = JSXElementMock('div', []);
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(true);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [JSXElementMock('div', [])]),
|
||||
elementType,
|
||||
),
|
||||
true,
|
||||
'has children + visible JSXElement child -> true',
|
||||
);
|
||||
|
||||
it('Returns true for JSXText Element', () => {
|
||||
const child = {
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [{
|
||||
type: 'JSXText',
|
||||
value: 'foo',
|
||||
};
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(true);
|
||||
});
|
||||
}]),
|
||||
elementType,
|
||||
),
|
||||
true,
|
||||
'has children + JSText element -> true',
|
||||
);
|
||||
|
||||
it('Returns false for hidden child JSXElement', () => {
|
||||
const ariaHiddenAttr = JSXAttributeMock('aria-hidden', true);
|
||||
const child = JSXElementMock('div', [ariaHiddenAttr]);
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(false);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-hidden', true),
|
||||
]),
|
||||
]),
|
||||
elementType,
|
||||
),
|
||||
false,
|
||||
'has children + hidden child JSXElement -> false',
|
||||
);
|
||||
|
||||
it('Returns true for defined JSXExpressionContainer', () => {
|
||||
const expression = {
|
||||
type: 'Identifier',
|
||||
name: 'foo',
|
||||
};
|
||||
const child = JSXExpressionContainerMock(expression);
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(true);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [
|
||||
JSXExpressionContainerMock({
|
||||
type: 'Identifier',
|
||||
name: 'foo',
|
||||
}),
|
||||
]),
|
||||
elementType,
|
||||
),
|
||||
true,
|
||||
'defined JSXExpressionContainer -> true',
|
||||
);
|
||||
|
||||
it('Returns false for undefined JSXExpressionContainer', () => {
|
||||
const expression = {
|
||||
type: 'Identifier',
|
||||
name: 'undefined',
|
||||
};
|
||||
const child = JSXExpressionContainerMock(expression);
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(false);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [
|
||||
JSXExpressionContainerMock({
|
||||
type: 'Identifier',
|
||||
name: 'undefined',
|
||||
}),
|
||||
]),
|
||||
elementType,
|
||||
),
|
||||
false,
|
||||
'has children + undefined JSXExpressionContainer -> false',
|
||||
);
|
||||
|
||||
it('Returns false for unknown child type', () => {
|
||||
const child = {
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [{
|
||||
type: 'Unknown',
|
||||
};
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(false);
|
||||
});
|
||||
}]),
|
||||
elementType,
|
||||
),
|
||||
false,
|
||||
'unknown child type -> false',
|
||||
);
|
||||
|
||||
it('Returns true with children passed as a prop', () => {
|
||||
const children = JSXAttributeMock('children', true);
|
||||
const element = JSXElementMock('div', [children], []);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(true);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [JSXAttributeMock('children', true)], []),
|
||||
elementType,
|
||||
),
|
||||
true,
|
||||
'children passed as a prop -> true',
|
||||
);
|
||||
|
||||
it('Returns false for hidden child input JSXElement', () => {
|
||||
const child = JSXElementMock('input', [JSXAttributeMock('type', 'hidden')]);
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(false);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('input', [JSXAttributeMock('type', 'hidden')]),
|
||||
]),
|
||||
elementType,
|
||||
),
|
||||
false,
|
||||
'has chidren -> hidden child input JSXElement -> false',
|
||||
);
|
||||
|
||||
it('Returns true for a custom JSXElement even if type hidden', () => {
|
||||
const child = JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]);
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, elementType)).toBe(true);
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]),
|
||||
]),
|
||||
elementType,
|
||||
),
|
||||
true,
|
||||
'has children + custom JSXElement of type hidden -> true',
|
||||
);
|
||||
|
||||
it('Returns false for a custom JSXElement mapped to input if type is hidden', () => {
|
||||
const child = JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]);
|
||||
const element = JSXElementMock('div', [], [child]);
|
||||
expect(hasAccessibleChild(element, () => 'input')).toBe(false);
|
||||
});
|
||||
});
|
||||
t.equal(
|
||||
hasAccessibleChild(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]),
|
||||
]),
|
||||
() => 'input',
|
||||
),
|
||||
false,
|
||||
'custom JSXElement mapped to input if type is hidden -> false',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
109
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/input-test.js
generated
vendored
109
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/input-test.js
generated
vendored
|
|
@ -1,34 +1,87 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock';
|
||||
import getImplicitRoleForInput from '../../../../src/util/implicitRoles/input';
|
||||
|
||||
describe('isAbstractRole', () => {
|
||||
it('works for buttons', () => {
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'button')])).toBe('button');
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'image')])).toBe('button');
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'reset')])).toBe('button');
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'submit')])).toBe('button');
|
||||
test('isAbstractRole', (t) => {
|
||||
t.test('works for buttons', (st) => {
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'button')]),
|
||||
'button',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'image')]),
|
||||
'button',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'reset')]),
|
||||
'button',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'submit')]),
|
||||
'button',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
it('works for checkboxes', () => {
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'checkbox')])).toBe('checkbox');
|
||||
});
|
||||
it('works for radios', () => {
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'radio')])).toBe('radio');
|
||||
});
|
||||
it('works for ranges', () => {
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'range')])).toBe('slider');
|
||||
});
|
||||
it('works for textboxes', () => {
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'email')])).toBe('textbox');
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'password')])).toBe('textbox');
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'search')])).toBe('textbox');
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'tel')])).toBe('textbox');
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', 'url')])).toBe('textbox');
|
||||
});
|
||||
it('works for the default case', () => {
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', '')])).toBe('textbox');
|
||||
});
|
||||
it('works for the true case', () => {
|
||||
expect(getImplicitRoleForInput([JSXAttributeMock('type', true)])).toBe('textbox');
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'checkbox')]),
|
||||
'checkbox',
|
||||
'works for checkboxes',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'radio')]),
|
||||
'radio',
|
||||
'works for radios',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'range')]),
|
||||
'slider',
|
||||
'works for ranges',
|
||||
);
|
||||
|
||||
t.test('works for textboxes', (st) => {
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'email')]),
|
||||
'textbox',
|
||||
);
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'password')]),
|
||||
'textbox',
|
||||
);
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'search')]),
|
||||
'textbox',
|
||||
);
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'tel')]),
|
||||
'textbox',
|
||||
);
|
||||
st.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', 'url')]),
|
||||
'textbox',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', '')]),
|
||||
'textbox',
|
||||
'works for the default case',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForInput([JSXAttributeMock('type', true)]),
|
||||
'textbox',
|
||||
'works for the true case',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
24
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menu-test.js
generated
vendored
24
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menu-test.js
generated
vendored
|
|
@ -1,12 +1,20 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock';
|
||||
import getImplicitRoleForMenu from '../../../../src/util/implicitRoles/menu';
|
||||
|
||||
describe('isAbstractRole', () => {
|
||||
it('works for toolbars', () => {
|
||||
expect(getImplicitRoleForMenu([JSXAttributeMock('type', 'toolbar')])).toBe('toolbar');
|
||||
});
|
||||
it('works for non-toolbars', () => {
|
||||
expect(getImplicitRoleForMenu([JSXAttributeMock('type', '')])).toBe('');
|
||||
});
|
||||
test('isAbstractRole', (t) => {
|
||||
t.equal(
|
||||
getImplicitRoleForMenu([JSXAttributeMock('type', 'toolbar')]),
|
||||
'toolbar',
|
||||
'works for toolbars',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForMenu([JSXAttributeMock('type', '')]),
|
||||
'',
|
||||
'works for non-toolbars',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
51
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menuitem-test.js
generated
vendored
51
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menuitem-test.js
generated
vendored
|
|
@ -1,21 +1,38 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock';
|
||||
import getImplicitRoleForMenuitem from '../../../../src/util/implicitRoles/menuitem';
|
||||
|
||||
describe('isAbstractRole', () => {
|
||||
it('works for menu items', () => {
|
||||
expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', 'command')])).toBe('menuitem');
|
||||
});
|
||||
it('works for menu item checkboxes', () => {
|
||||
expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', 'checkbox')])).toBe('menuitemcheckbox');
|
||||
});
|
||||
it('works for menu item radios', () => {
|
||||
expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', 'radio')])).toBe('menuitemradio');
|
||||
});
|
||||
it('works for non-toolbars', () => {
|
||||
expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', '')])).toBe('');
|
||||
});
|
||||
it('works for the true case', () => {
|
||||
expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', true)])).toBe('');
|
||||
});
|
||||
test('isAbstractRole', (t) => {
|
||||
t.equal(
|
||||
getImplicitRoleForMenuitem([JSXAttributeMock('type', 'command')]),
|
||||
'menuitem',
|
||||
'works for menu items',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForMenuitem([JSXAttributeMock('type', 'checkbox')]),
|
||||
'menuitemcheckbox',
|
||||
'works for menu item checkboxes',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForMenuitem([JSXAttributeMock('type', 'radio')]),
|
||||
'menuitemradio',
|
||||
'works for menu item radios',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForMenuitem([JSXAttributeMock('type', '')]),
|
||||
'',
|
||||
'works for non-toolbars',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
getImplicitRoleForMenuitem([JSXAttributeMock('type', true)]),
|
||||
'',
|
||||
'works for the true case',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
48
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isAbstractRole-test.js
generated
vendored
48
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isAbstractRole-test.js
generated
vendored
|
|
@ -1,5 +1,6 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import isAbstractRole from '../../../src/util/isAbstractRole';
|
||||
import {
|
||||
genElementSymbol,
|
||||
|
|
@ -7,33 +8,44 @@ import {
|
|||
genNonAbstractRoleElements,
|
||||
} from '../../../__mocks__/genInteractives';
|
||||
|
||||
describe('isAbstractRole', () => {
|
||||
describe('JSX Components (no tagName)', () => {
|
||||
it('should NOT identify them as abstract role elements', () => {
|
||||
expect(isAbstractRole(undefined, []))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with an abstract role', () => {
|
||||
test('isAbstractRole', (t) => {
|
||||
t.equal(
|
||||
isAbstractRole(undefined, []),
|
||||
false,
|
||||
'does NOT identify JSX Components (no tagName) as abstract role elements',
|
||||
);
|
||||
|
||||
t.test('elements with an abstract role', (st) => {
|
||||
genAbstractRoleElements().forEach(({ openingElement }) => {
|
||||
const { attributes } = openingElement;
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` as an abstract role element`, () => {
|
||||
expect(isAbstractRole(
|
||||
st.equal(
|
||||
isAbstractRole(
|
||||
elementType(openingElement),
|
||||
attributes,
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as an abstract role element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('elements with a non-abstract role', () => {
|
||||
|
||||
t.test('elements with a non-abstract role', (st) => {
|
||||
genNonAbstractRoleElements().forEach(({ openingElement }) => {
|
||||
const { attributes } = openingElement;
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an abstract role element`, () => {
|
||||
expect(isAbstractRole(
|
||||
st.equal(
|
||||
isAbstractRole(
|
||||
elementType(openingElement),
|
||||
attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`does NOT identify \`${genElementSymbol(openingElement)}\` as an abstract role element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
85
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isContentEditable-test.js
generated
vendored
85
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isContentEditable-test.js
generated
vendored
|
|
@ -1,51 +1,52 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import isContentEditable from '../../../src/util/isContentEditable';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
describe('isContentEditable', () => {
|
||||
describe('HTML5', () => {
|
||||
describe('content editable', () => {
|
||||
it('should identify HTML5 contentEditable elements', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('contentEditable', 'true'),
|
||||
];
|
||||
expect(isContentEditable('some tag', attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
test('isContentEditable - HTML5', (t) => {
|
||||
t.equal(
|
||||
isContentEditable('some tag', [
|
||||
JSXAttributeMock('contentEditable', 'true'),
|
||||
]),
|
||||
true,
|
||||
'identifies HTML5 contentEditable elements',
|
||||
);
|
||||
|
||||
describe('not content editable', () => {
|
||||
it('should not identify HTML5 content editable elements with null as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('contentEditable', null),
|
||||
];
|
||||
expect(isContentEditable('some tag', attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
t.test('not content editable', (st) => {
|
||||
st.equal(
|
||||
isContentEditable('some tag', [
|
||||
JSXAttributeMock('contentEditable', null),
|
||||
]),
|
||||
false,
|
||||
'does not identify HTML5 content editable elements with null as the value',
|
||||
);
|
||||
|
||||
it('should not identify HTML5 content editable elements with undefined as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('contentEditable', undefined),
|
||||
];
|
||||
expect(isContentEditable('some tag', attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
st.equal(
|
||||
isContentEditable('some tag', [
|
||||
JSXAttributeMock('contentEditable', undefined),
|
||||
]),
|
||||
false,
|
||||
'does not identify HTML5 content editable elements with undefined as the value',
|
||||
);
|
||||
|
||||
it('should not identify HTML5 content editable elements with true as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('contentEditable', true),
|
||||
];
|
||||
expect(isContentEditable('some tag', attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
st.equal(
|
||||
isContentEditable('some tag', [
|
||||
JSXAttributeMock('contentEditable', true),
|
||||
]),
|
||||
false,
|
||||
'does not identify HTML5 content editable elements with true as the value',
|
||||
);
|
||||
|
||||
it('should not identify HTML5 content editable elements with "false" as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('contentEditable', 'false'),
|
||||
];
|
||||
expect(isContentEditable('some tag', attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
st.equal(
|
||||
isContentEditable('some tag', [
|
||||
JSXAttributeMock('contentEditable', 'false'),
|
||||
]),
|
||||
false,
|
||||
'does not identify HTML5 content editable elements with "false" as the value',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
38
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isDOMElement-test.js
generated
vendored
38
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isDOMElement-test.js
generated
vendored
|
|
@ -1,26 +1,30 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { dom } from 'aria-query';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import isDOMElement from '../../../src/util/isDOMElement';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
|
||||
const domElements = [...dom.keys()];
|
||||
test('isDOMElement', (t) => {
|
||||
t.test('DOM elements', (st) => {
|
||||
dom.forEach((_, el) => {
|
||||
const element = JSXElementMock(el);
|
||||
|
||||
describe('isDOMElement', () => {
|
||||
describe('DOM elements', () => {
|
||||
domElements.forEach((el) => {
|
||||
it(`should identify ${el} as a DOM element`, () => {
|
||||
const element = JSXElementMock(el);
|
||||
expect(isDOMElement(elementType(element.openingElement)))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('Custom Element', () => {
|
||||
it('should not identify a custom element', () => {
|
||||
const element = JSXElementMock('CustomElement');
|
||||
expect(isDOMElement(element))
|
||||
.toBe(false);
|
||||
st.equal(
|
||||
isDOMElement(elementType(element.openingElement)),
|
||||
true,
|
||||
`identifies ${el} as a DOM element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.equal(
|
||||
isDOMElement(JSXElementMock('CustomElement')),
|
||||
false,
|
||||
'does not identify a custom element',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
157
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isDisabledElement-test.js
generated
vendored
157
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isDisabledElement-test.js
generated
vendored
|
|
@ -1,81 +1,88 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import isDisabledElement from '../../../src/util/isDisabledElement';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
describe('isDisabledElement', () => {
|
||||
describe('HTML5', () => {
|
||||
describe('disabled', () => {
|
||||
it('should identify HTML5 disabled elements', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('disabled', 'disabled'),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
describe('not disabled', () => {
|
||||
it('should identify HTML5 disabled elements with null as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('disabled', null),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
it('should not identify HTML5 disabled elements with undefined as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('disabled', undefined),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
test('isDisabledElement', (t) => {
|
||||
t.test('HTML5', (st) => {
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('disabled', 'disabled'),
|
||||
]),
|
||||
true,
|
||||
'identifies HTML5 disabled elements',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('disabled', null),
|
||||
]),
|
||||
true,
|
||||
'identifies HTML5 disabled elements with null as the value',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('disabled', undefined),
|
||||
]),
|
||||
false,
|
||||
'does not identify HTML5 disabled elements with undefined as the value',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('ARIA', () => {
|
||||
describe('disabled', () => {
|
||||
it('should not identify ARIA disabled elements', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('aria-disabled', 'true'),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
it('should not identify ARIA disabled elements', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('aria-disabled', true),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
describe('not disabled', () => {
|
||||
it('should not identify ARIA disabled elements', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('aria-disabled', 'false'),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
it('should not identify ARIA disabled elements', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('aria-disabled', false),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
it('should not identify ARIA disabled elements with null as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('aria-disabled', null),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
it('should not identify ARIA disabled elements with undefined as the value', () => {
|
||||
const attributes = [
|
||||
JSXAttributeMock('aria-disabled', undefined),
|
||||
];
|
||||
expect(isDisabledElement(attributes))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
t.test('ARIA', (st) => {
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('aria-disabled', 'true'),
|
||||
]),
|
||||
true,
|
||||
'does not identify ARIA disabled elements',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('aria-disabled', true),
|
||||
]),
|
||||
true,
|
||||
'does not identify ARIA disabled elements',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('aria-disabled', 'false'),
|
||||
]),
|
||||
false,
|
||||
'does not identify ARIA disabled elements',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('aria-disabled', false),
|
||||
]),
|
||||
false,
|
||||
'does not identify ARIA disabled elements',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('aria-disabled', null),
|
||||
]),
|
||||
false,
|
||||
'does not identify ARIA disabled elements with null as the value',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isDisabledElement([
|
||||
JSXAttributeMock('aria-disabled', undefined),
|
||||
]),
|
||||
false,
|
||||
'does not identify ARIA disabled elements with undefined as the value',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
107
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isFocusable-test.js
generated
vendored
107
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isFocusable-test.js
generated
vendored
|
|
@ -1,5 +1,6 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import isFocusable from '../../../src/util/isFocusable';
|
||||
import {
|
||||
genElementSymbol,
|
||||
|
|
@ -9,78 +10,102 @@ import {
|
|||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
function mergeTabIndex(index, attributes) {
|
||||
return [...attributes, JSXAttributeMock('tabIndex', index)];
|
||||
return [].concat(attributes, JSXAttributeMock('tabIndex', index));
|
||||
}
|
||||
|
||||
describe('isFocusable', () => {
|
||||
describe('interactive elements', () => {
|
||||
test('isFocusable', (t) => {
|
||||
t.test('interactive elements', (st) => {
|
||||
genInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as a focusable element`,
|
||||
);
|
||||
|
||||
it(`should not identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
mergeTabIndex(-1, openingElement.attributes),
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`does NOT identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`,
|
||||
);
|
||||
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
mergeTabIndex(0, openingElement.attributes),
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`,
|
||||
);
|
||||
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
mergeTabIndex(1, openingElement.attributes),
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
describe('non-interactive elements', () => {
|
||||
t.test('non-interactive elements', (st) => {
|
||||
genNonInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should not identify \`${genElementSymbol(openingElement)}\` as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`does NOT identify \`${genElementSymbol(openingElement)}\` as a focusable element`,
|
||||
);
|
||||
|
||||
it(`should not identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
mergeTabIndex(-1, openingElement.attributes),
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`does NOT identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`,
|
||||
);
|
||||
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
mergeTabIndex(0, openingElement.attributes),
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`,
|
||||
);
|
||||
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
mergeTabIndex(1, openingElement.attributes),
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`,
|
||||
);
|
||||
|
||||
it(`should not identify \`${genElementSymbol(openingElement)}\` with tabIndex of 'bogus' as a focusable element`, () => {
|
||||
expect(isFocusable(
|
||||
st.equal(
|
||||
isFocusable(
|
||||
elementType(openingElement),
|
||||
mergeTabIndex('bogus', openingElement.attributes),
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`does NOT identify \`${genElementSymbol(openingElement)}\` with tabIndex of 'bogus' as a focusable element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
104
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test.js
generated
vendored
104
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test.js
generated
vendored
|
|
@ -1,5 +1,6 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import isInteractiveElement from '../../../src/util/isInteractiveElement';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
import {
|
||||
|
|
@ -11,66 +12,93 @@ import {
|
|||
genNonInteractiveRoleElements,
|
||||
} from '../../../__mocks__/genInteractives';
|
||||
|
||||
describe('isInteractiveElement', () => {
|
||||
describe('JSX Components (no tagName)', () => {
|
||||
it('should identify them as interactive elements', () => {
|
||||
expect(isInteractiveElement(undefined, []))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('interactive elements', () => {
|
||||
test('isInteractiveElement', (t) => {
|
||||
t.equal(
|
||||
isInteractiveElement(undefined, []),
|
||||
false,
|
||||
'identifies them as interactive elements',
|
||||
);
|
||||
|
||||
t.test('interactive elements', (st) => {
|
||||
genInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => {
|
||||
expect(isInteractiveElement(
|
||||
st.equal(
|
||||
isInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as an interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('interactive role elements', () => {
|
||||
|
||||
t.test('interactive role elements', (st) => {
|
||||
genInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => {
|
||||
expect(isInteractiveElement(
|
||||
st.equal(
|
||||
isInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as an interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('non-interactive elements', () => {
|
||||
|
||||
t.test('non-interactive elements', (st) => {
|
||||
genNonInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => {
|
||||
expect(isInteractiveElement(
|
||||
st.equal(
|
||||
isInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as an interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('non-interactive role elements', () => {
|
||||
|
||||
t.test('non-interactive role elements', (st) => {
|
||||
genNonInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => {
|
||||
expect(isInteractiveElement(
|
||||
st.equal(
|
||||
isInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as an interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('indeterminate elements', () => {
|
||||
|
||||
t.test('indeterminate elements', (st) => {
|
||||
genIndeterminantInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${openingElement.name.name}\` as an interactive element`, () => {
|
||||
expect(isInteractiveElement(
|
||||
st.equal(
|
||||
isInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('JSX elements', () => {
|
||||
it('is not interactive', () => {
|
||||
expect(isInteractiveElement('CustomComponent', JSXElementMock())).toBe(false);
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as an interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.equal(
|
||||
isInteractiveElement('CustomComponent', JSXElementMock()),
|
||||
false,
|
||||
'JSX elements are not interactive',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
61
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test.js
generated
vendored
61
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test.js
generated
vendored
|
|
@ -1,5 +1,6 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import isInteractiveRole from '../../../src/util/isInteractiveRole';
|
||||
import {
|
||||
genElementSymbol,
|
||||
|
|
@ -7,38 +8,52 @@ import {
|
|||
genNonInteractiveRoleElements,
|
||||
} from '../../../__mocks__/genInteractives';
|
||||
|
||||
describe('isInteractiveRole', () => {
|
||||
describe('JSX Components (no tagName)', () => {
|
||||
it('should identify them as interactive role elements', () => {
|
||||
expect(isInteractiveRole(undefined, []))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with a non-interactive role', () => {
|
||||
test('isInteractiveRole', (t) => {
|
||||
t.equal(
|
||||
isInteractiveRole(undefined, []),
|
||||
false,
|
||||
'identifies JSX Components (no tagName) as interactive role elements',
|
||||
);
|
||||
|
||||
t.test('elements with a non-interactive role', (st) => {
|
||||
genNonInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
const { attributes } = openingElement;
|
||||
it(`should not identify \`${genElementSymbol(openingElement)}\` as an interactive role element`, () => {
|
||||
expect(isInteractiveRole(
|
||||
|
||||
st.equal(
|
||||
isInteractiveRole(
|
||||
elementType(openingElement),
|
||||
attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`does NOT identify \`${genElementSymbol(openingElement)}\` as an interactive role element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('elements without a role', () => {
|
||||
it('should not identify them as interactive role elements', () => {
|
||||
expect(isInteractiveRole('div', [])).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with an interactive role', () => {
|
||||
|
||||
t.equal(
|
||||
isInteractiveRole('div', []),
|
||||
false,
|
||||
'does NOT identify elements without a role as interactive role elements',
|
||||
);
|
||||
|
||||
t.test('elements with an interactive role', (st) => {
|
||||
genInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
const { attributes } = openingElement;
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` as an interactive role element`, () => {
|
||||
expect(isInteractiveRole(
|
||||
|
||||
st.equal(
|
||||
isInteractiveRole(
|
||||
elementType(openingElement),
|
||||
attributes,
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as an interactive role element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
93
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveElement-test.js
generated
vendored
93
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveElement-test.js
generated
vendored
|
|
@ -1,5 +1,6 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import isNonInteractiveElement from '../../../src/util/isNonInteractiveElement';
|
||||
import {
|
||||
genElementSymbol,
|
||||
|
|
@ -10,61 +11,87 @@ import {
|
|||
genNonInteractiveRoleElements,
|
||||
} from '../../../__mocks__/genInteractives';
|
||||
|
||||
describe('isNonInteractiveElement', () => {
|
||||
describe('JSX Components (no tagName)', () => {
|
||||
it('should identify them as interactive elements', () => {
|
||||
expect(isNonInteractiveElement(undefined, []))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('non-interactive elements', () => {
|
||||
test('isNonInteractiveElement', (t) => {
|
||||
t.equal(
|
||||
isNonInteractiveElement(undefined, []),
|
||||
false,
|
||||
'identifies JSX Components (no tagName) as non-interactive elements',
|
||||
);
|
||||
|
||||
t.test('non-interactive elements', (st) => {
|
||||
genNonInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => {
|
||||
expect(isNonInteractiveElement(
|
||||
st.equal(
|
||||
isNonInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('non-interactive role elements', () => {
|
||||
|
||||
t.test('non-interactive role elements', (st) => {
|
||||
genNonInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => {
|
||||
expect(isNonInteractiveElement(
|
||||
st.equal(
|
||||
isNonInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('interactive elements', () => {
|
||||
|
||||
t.test('interactive elements', (st) => {
|
||||
genInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => {
|
||||
expect(isNonInteractiveElement(
|
||||
st.equal(
|
||||
isNonInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('interactive role elements', () => {
|
||||
|
||||
t.test('interactive role elements', (st) => {
|
||||
genInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => {
|
||||
expect(isNonInteractiveElement(
|
||||
st.equal(
|
||||
isNonInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('indeterminate elements', () => {
|
||||
|
||||
t.test('indeterminate elements', (st) => {
|
||||
genIndeterminantInteractiveElements().forEach(({ openingElement }) => {
|
||||
it(`should NOT identify \`${openingElement.name.name}\` as a non-interactive element`, () => {
|
||||
expect(isNonInteractiveElement(
|
||||
st.equal(
|
||||
isNonInteractiveElement(
|
||||
elementType(openingElement),
|
||||
openingElement.attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
61
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveRole-test.js
generated
vendored
61
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveRole-test.js
generated
vendored
|
|
@ -1,5 +1,6 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
import { elementType } from 'jsx-ast-utils';
|
||||
|
||||
import isNonInteractiveRole from '../../../src/util/isNonInteractiveRole';
|
||||
import {
|
||||
genElementSymbol,
|
||||
|
|
@ -7,38 +8,52 @@ import {
|
|||
genNonInteractiveRoleElements,
|
||||
} from '../../../__mocks__/genInteractives';
|
||||
|
||||
describe('isNonInteractiveRole', () => {
|
||||
describe('JSX Components (no tagName)', () => {
|
||||
it('should identify them as interactive role elements', () => {
|
||||
expect(isNonInteractiveRole(undefined, []))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with a non-interactive role', () => {
|
||||
test('isNonInteractiveRole', (t) => {
|
||||
t.equal(
|
||||
isNonInteractiveRole(undefined, []),
|
||||
false,
|
||||
'identifies JSX Components (no tagName) as non-interactive elements',
|
||||
);
|
||||
|
||||
t.test('elements with a non-interactive role', (st) => {
|
||||
genNonInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
const { attributes } = openingElement;
|
||||
it(`should identify \`${genElementSymbol(openingElement)}\` as non-interactive role element`, () => {
|
||||
expect(isNonInteractiveRole(
|
||||
|
||||
st.equal(
|
||||
isNonInteractiveRole(
|
||||
elementType(openingElement),
|
||||
attributes,
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
`identifies \`${genElementSymbol(openingElement)}\` as a non-interactive role element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('elements without a role', () => {
|
||||
it('should not identify them as non-interactive role elements', () => {
|
||||
expect(isNonInteractiveRole('div', [])).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with an interactive role', () => {
|
||||
|
||||
t.equal(
|
||||
isNonInteractiveRole('div', []),
|
||||
false,
|
||||
'does NOT identify elements without a role as non-interactive role elements',
|
||||
);
|
||||
|
||||
t.test('elements with an interactive role', (st) => {
|
||||
genInteractiveRoleElements().forEach(({ openingElement }) => {
|
||||
const { attributes } = openingElement;
|
||||
it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive role element`, () => {
|
||||
expect(isNonInteractiveRole(
|
||||
|
||||
st.equal(
|
||||
isNonInteractiveRole(
|
||||
elementType(openingElement),
|
||||
attributes,
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
`does NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive role element`,
|
||||
);
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
72
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isNonLiteralProperty-test.js
generated
vendored
72
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isNonLiteralProperty-test.js
generated
vendored
|
|
@ -1,4 +1,5 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import isNonLiteralProperty from '../../../src/util/isNonLiteralProperty';
|
||||
import IdentifierMock from '../../../__mocks__/IdentifierMock';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
|
@ -10,35 +11,42 @@ const theProp = 'theProp';
|
|||
|
||||
const spread = JSXSpreadAttributeMock('theSpread');
|
||||
|
||||
describe('isNonLiteralProperty', () => {
|
||||
describe('elements without the property', () => {
|
||||
it('should not identify them as non-literal role elements', () => {
|
||||
expect(isNonLiteralProperty([], theProp)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with a literal property', () => {
|
||||
it('should not identify them as non-literal role elements without spread operator', () => {
|
||||
expect(isNonLiteralProperty([JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp)).toBe(false);
|
||||
});
|
||||
it('should not identify them as non-literal role elements with spread operator', () => {
|
||||
expect(isNonLiteralProperty([spread, JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with a JSXText property', () => {
|
||||
it('should not identify them as non-literal role elements', () => {
|
||||
expect(isNonLiteralProperty([JSXAttributeMock(theProp, JSXTextMock('theRole'))], theProp)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with a property of undefined', () => {
|
||||
it('should not identify them as non-literal role elements', () => {
|
||||
const undefinedExpression = IdentifierMock('undefined');
|
||||
expect(isNonLiteralProperty([JSXAttributeMock(theProp, undefinedExpression)], theProp)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('elements with a expression property', () => {
|
||||
it('should identify them as non-literal role elements', () => {
|
||||
const identifierExpression = IdentifierMock('theIdentifier');
|
||||
expect(isNonLiteralProperty([JSXAttributeMock(theProp, identifierExpression)], theProp)).toBe(true);
|
||||
});
|
||||
});
|
||||
test('isNonLiteralProperty', (t) => {
|
||||
t.equal(
|
||||
isNonLiteralProperty([], theProp),
|
||||
false,
|
||||
'does not identify them as non-literal role elements',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
isNonLiteralProperty([JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp),
|
||||
false,
|
||||
'does not identify elements with a literal property as non-literal role elements without spread operator',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
isNonLiteralProperty([spread, JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp),
|
||||
false,
|
||||
'does not identify elements with a literal property as non-literal role elements with spread operator',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
isNonLiteralProperty([JSXAttributeMock(theProp, JSXTextMock('theRole'))], theProp),
|
||||
false,
|
||||
'identifies elements with a JSXText property as non-literal role elements',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
isNonLiteralProperty([JSXAttributeMock(theProp, IdentifierMock('undefined'))], theProp),
|
||||
false,
|
||||
'does not identify elements with a property of undefined as non-literal role elements',
|
||||
);
|
||||
|
||||
t.equal(
|
||||
isNonLiteralProperty([JSXAttributeMock(theProp, IdentifierMock('theIdentifier'))], theProp),
|
||||
true,
|
||||
'identifies elements with an expression property as non-literal role elements',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
77
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isSemanticRoleElement-test.js
generated
vendored
77
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/isSemanticRoleElement-test.js
generated
vendored
|
|
@ -1,33 +1,55 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import isSemanticRoleElement from '../../../src/util/isSemanticRoleElement';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
|
||||
describe('isSemanticRoleElement', () => {
|
||||
it('should identify semantic role elements', () => {
|
||||
expect(isSemanticRoleElement('input', [
|
||||
test('isSemanticRoleElement', (t) => {
|
||||
t.equal(
|
||||
isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('type', 'checkbox'),
|
||||
JSXAttributeMock('role', 'switch'),
|
||||
])).toBe(true);
|
||||
]),
|
||||
true,
|
||||
'identifies semantic role elements',
|
||||
);
|
||||
|
||||
t.test('rejects non-semantics role elements', (st) => {
|
||||
st.equal(
|
||||
isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('type', 'radio'),
|
||||
JSXAttributeMock('role', 'switch'),
|
||||
]),
|
||||
false,
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('type', 'text'),
|
||||
JSXAttributeMock('role', 'combobox'),
|
||||
]),
|
||||
false,
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isSemanticRoleElement('button', [
|
||||
JSXAttributeMock('role', 'switch'),
|
||||
JSXAttributeMock('aria-pressed', 'true'),
|
||||
]),
|
||||
false,
|
||||
);
|
||||
|
||||
st.equal(
|
||||
isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('role', 'switch'),
|
||||
]),
|
||||
false,
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
it('should reject non-semantic role elements', () => {
|
||||
expect(isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('type', 'radio'),
|
||||
JSXAttributeMock('role', 'switch'),
|
||||
])).toBe(false);
|
||||
expect(isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('type', 'text'),
|
||||
JSXAttributeMock('role', 'combobox'),
|
||||
])).toBe(false);
|
||||
expect(isSemanticRoleElement('button', [
|
||||
JSXAttributeMock('role', 'switch'),
|
||||
JSXAttributeMock('aria-pressed', 'true'),
|
||||
])).toBe(false);
|
||||
expect(isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('role', 'switch'),
|
||||
])).toBe(false);
|
||||
});
|
||||
it('should not throw on JSXSpreadAttribute', () => {
|
||||
expect(() => {
|
||||
|
||||
t.doesNotThrow(
|
||||
() => {
|
||||
isSemanticRoleElement('input', [
|
||||
JSXAttributeMock('type', 'checkbox'),
|
||||
JSXAttributeMock('role', 'checkbox'),
|
||||
|
|
@ -42,6 +64,9 @@ describe('isSemanticRoleElement', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
},
|
||||
'does not throw on JSXSpreadAttribute',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
225
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/mayContainChildComponent-test.js
generated
vendored
225
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/mayContainChildComponent-test.js
generated
vendored
|
|
@ -1,62 +1,73 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import mayContainChildComponent from '../../../src/util/mayContainChildComponent';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
import JSXExpressionContainerMock from '../../../__mocks__/JSXExpressionContainerMock';
|
||||
|
||||
describe('mayContainChildComponent', () => {
|
||||
describe('no FancyComponent', () => {
|
||||
it('should return false', () => {
|
||||
expect(mayContainChildComponent(
|
||||
test('mayContainChildComponent', (t) => {
|
||||
t.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('span', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('span', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('span', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
]),
|
||||
]),
|
||||
'FancyComponent',
|
||||
5,
|
||||
)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('contains an indicated component', () => {
|
||||
it('should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
]),
|
||||
]),
|
||||
'FancyComponent',
|
||||
5,
|
||||
),
|
||||
false,
|
||||
'no FancyComponent returns false',
|
||||
);
|
||||
|
||||
t.test('contains an indicated component', (st) => {
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('input'),
|
||||
]),
|
||||
'input',
|
||||
)).toBe(true);
|
||||
});
|
||||
it('should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
),
|
||||
true,
|
||||
'returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'FancyComponent',
|
||||
)).toBe(true);
|
||||
});
|
||||
it('FancyComponent is outside of default depth, should return false', () => {
|
||||
expect(mayContainChildComponent(
|
||||
),
|
||||
true,
|
||||
'returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
]),
|
||||
'FancyComponent',
|
||||
)).toBe(false);
|
||||
});
|
||||
it('FancyComponent is inside of custom depth, should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
),
|
||||
false,
|
||||
'FancyComponent is outside of default depth, should return false',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
|
|
@ -64,10 +75,13 @@ describe('mayContainChildComponent', () => {
|
|||
]),
|
||||
'FancyComponent',
|
||||
2,
|
||||
)).toBe(true);
|
||||
});
|
||||
it('deep nesting, should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
),
|
||||
true,
|
||||
'FancyComponent is inside of custom depth, should return true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
|
|
@ -89,90 +103,117 @@ describe('mayContainChildComponent', () => {
|
|||
]),
|
||||
'FancyComponent',
|
||||
6,
|
||||
)).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('Intederminate situations', () => {
|
||||
describe('expression container children', () => {
|
||||
it('should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXExpressionContainerMock('mysteryBox'),
|
||||
]),
|
||||
'FancyComponent',
|
||||
)).toBe(true);
|
||||
});
|
||||
});
|
||||
),
|
||||
true,
|
||||
'deep nesting, returns true',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
describe('Glob name matching', () => {
|
||||
describe('component name contains question mark ? - match any single character', () => {
|
||||
it('should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'Fanc?Co??onent',
|
||||
)).toBe(true);
|
||||
});
|
||||
it('should return false', () => {
|
||||
expect(mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'FancyComponent?',
|
||||
)).toBe(false);
|
||||
});
|
||||
});
|
||||
t.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXExpressionContainerMock('mysteryBox'),
|
||||
]),
|
||||
'FancyComponent',
|
||||
),
|
||||
true,
|
||||
'Intederminate situations + expression container children - returns true',
|
||||
);
|
||||
|
||||
describe('component name contains asterisk * - match zero or more characters', () => {
|
||||
it('should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
t.test('Glob name matching - component name contains question mark ? - match any single character', (st) => {
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'Fanc?Co??onent',
|
||||
),
|
||||
true,
|
||||
'returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'FancyComponent?',
|
||||
),
|
||||
false,
|
||||
'returns false',
|
||||
);
|
||||
|
||||
st.test('component name contains asterisk * - match zero or more characters', (s2t) => {
|
||||
s2t.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'Fancy*',
|
||||
)).toBe(true);
|
||||
});
|
||||
it('should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
),
|
||||
true,
|
||||
'returns true',
|
||||
);
|
||||
|
||||
s2t.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'*Component',
|
||||
)).toBe(true);
|
||||
});
|
||||
it('should return true', () => {
|
||||
expect(mayContainChildComponent(
|
||||
),
|
||||
true,
|
||||
'returns true',
|
||||
);
|
||||
|
||||
s2t.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('FancyComponent'),
|
||||
]),
|
||||
'Fancy*C*t',
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
'returns true',
|
||||
);
|
||||
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
describe('using a custom elementType function', () => {
|
||||
it('should return true when the custom elementType returns the proper name', () => {
|
||||
expect(mayContainChildComponent(
|
||||
t.test('using a custom elementType function', (st) => {
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('CustomInput'),
|
||||
]),
|
||||
'input',
|
||||
2,
|
||||
() => 'input',
|
||||
)).toBe(true);
|
||||
});
|
||||
it('should return false when the custom elementType returns a wrong name', () => {
|
||||
expect(mayContainChildComponent(
|
||||
),
|
||||
true,
|
||||
'returns true when the custom elementType returns the proper name',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayContainChildComponent(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('CustomInput'),
|
||||
]),
|
||||
'input',
|
||||
2,
|
||||
() => 'button',
|
||||
)).toBe(false);
|
||||
});
|
||||
),
|
||||
false,
|
||||
'returns false when the custom elementType returns a wrong name',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
280
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/mayHaveAccessibleLabel-test.js
generated
vendored
280
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/mayHaveAccessibleLabel-test.js
generated
vendored
|
|
@ -1,4 +1,5 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import mayHaveAccessibleLabel from '../../../src/util/mayHaveAccessibleLabel';
|
||||
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
||||
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
||||
|
|
@ -7,101 +8,165 @@ import JSXSpreadAttributeMock from '../../../__mocks__/JSXSpreadAttributeMock';
|
|||
import JSXTextMock from '../../../__mocks__/JSXTextMock';
|
||||
import LiteralMock from '../../../__mocks__/LiteralMock';
|
||||
|
||||
describe('mayHaveAccessibleLabel', () => {
|
||||
describe('no label', () => {
|
||||
it('should return false', () => {
|
||||
expect(mayHaveAccessibleLabel(
|
||||
test('mayHaveAccessibleLabel', (t) => {
|
||||
t.equal(
|
||||
mayHaveAccessibleLabel(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('span', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('span', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('span', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
]),
|
||||
]),
|
||||
5,
|
||||
)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('label via attributes', () => {
|
||||
it('aria-label, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXElementMock('span', [], []),
|
||||
JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
]),
|
||||
]),
|
||||
5,
|
||||
),
|
||||
false,
|
||||
'no label returns false',
|
||||
);
|
||||
|
||||
t.test('label via attributes', (st) => {
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-label', 'A delicate label'),
|
||||
], []))).toBe(true);
|
||||
});
|
||||
it('aria-label without content, should return false', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
], [])),
|
||||
true,
|
||||
'aria-label returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-label', ''),
|
||||
], []))).toBe(false);
|
||||
});
|
||||
it('aria-labelledby, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
], [])),
|
||||
false,
|
||||
'aria-label without content returns false',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-label', ' '),
|
||||
], [])),
|
||||
false,
|
||||
'aria-label with only spaces whitespace, should return false',
|
||||
);
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-label', '\n'),
|
||||
], [])),
|
||||
false,
|
||||
'aria-label with only newline whitespace, should return false',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-labelledby', 'elementId'),
|
||||
], []))).toBe(true);
|
||||
});
|
||||
it('aria-labelledby without content, should return false', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
], [])),
|
||||
true,
|
||||
'aria-labelledby returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-labelledby', ''),
|
||||
], []))).toBe(false);
|
||||
});
|
||||
it('aria-labelledby with an expression container, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
], [])),
|
||||
false,
|
||||
'aria-labelledby without content returns false',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('aria-labelledby', 'elementId', true),
|
||||
], []))).toBe(true);
|
||||
});
|
||||
], [])),
|
||||
true,
|
||||
'aria-labelledby with an expression container, should return true',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('label via custom label attribute', () => {
|
||||
let customLabelProp;
|
||||
beforeEach(() => {
|
||||
customLabelProp = 'cowbell';
|
||||
});
|
||||
it('aria-label, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(
|
||||
|
||||
t.test('label via custom label attribute', (st) => {
|
||||
const customLabelProp = 'cowbell';
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(
|
||||
JSXElementMock('div', [
|
||||
JSXAttributeMock(customLabelProp, 'A delicate label'),
|
||||
], []),
|
||||
1,
|
||||
[customLabelProp],
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
'aria-label returns true',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('text label', () => {
|
||||
it('Literal text, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
|
||||
t.test('text label', (st) => {
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
LiteralMock('A fancy label'),
|
||||
]))).toBe(true);
|
||||
});
|
||||
it('JSXText, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
])),
|
||||
true,
|
||||
'Literal text, returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
LiteralMock(' '),
|
||||
])),
|
||||
false,
|
||||
'Literal spaces whitespace, returns false',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
LiteralMock('\n'),
|
||||
])),
|
||||
false,
|
||||
'Literal newline whitespace, returns false',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
JSXTextMock('A fancy label'),
|
||||
]))).toBe(true);
|
||||
});
|
||||
it('label is outside of default depth, should return false', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
])),
|
||||
true,
|
||||
'JSXText, returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXTextMock('A fancy label'),
|
||||
]),
|
||||
]))).toBe(false);
|
||||
});
|
||||
it('label is inside of custom depth, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(
|
||||
])),
|
||||
false,
|
||||
'label is outside of default depth, returns false',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXTextMock('A fancy label'),
|
||||
]),
|
||||
]),
|
||||
2,
|
||||
)).toBe(true);
|
||||
});
|
||||
it('deep nesting, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(
|
||||
),
|
||||
true,
|
||||
'label is inside of custom depth, returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('div', [], [
|
||||
JSXElementMock('span', [], []),
|
||||
|
|
@ -122,49 +187,70 @@ describe('mayHaveAccessibleLabel', () => {
|
|||
]),
|
||||
]),
|
||||
6,
|
||||
)).toBe(true);
|
||||
});
|
||||
),
|
||||
true,
|
||||
'deep nesting, returns true',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('image content', () => {
|
||||
it('without alt, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
|
||||
t.test('image content', (st) => {
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
]),
|
||||
]))).toBe(false);
|
||||
});
|
||||
it('with alt, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
])),
|
||||
false,
|
||||
'without alt, returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
JSXAttributeMock('alt', 'A sensible label'),
|
||||
]),
|
||||
]))).toBe(true);
|
||||
});
|
||||
it('with aria-label, should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
])),
|
||||
true,
|
||||
'with alt, returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
JSXElementMock('img', [
|
||||
JSXAttributeMock('src', 'some/path'),
|
||||
JSXAttributeMock('aria-label', 'A sensible label'),
|
||||
]),
|
||||
]))).toBe(true);
|
||||
});
|
||||
])),
|
||||
true,
|
||||
'with aria-label, returns true',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
describe('Intederminate situations', () => {
|
||||
describe('expression container children', () => {
|
||||
it('should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
JSXExpressionContainerMock('mysteryBox'),
|
||||
]))).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('spread operator in attributes', () => {
|
||||
it('should return true', () => {
|
||||
expect(mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('style', 'some-junk'),
|
||||
JSXSpreadAttributeMock('props'),
|
||||
], []))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
t.test('Intederminate situations', (st) => {
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [], [
|
||||
JSXExpressionContainerMock('mysteryBox'),
|
||||
])),
|
||||
true,
|
||||
'expression container children, returns true',
|
||||
);
|
||||
|
||||
st.equal(
|
||||
mayHaveAccessibleLabel(JSXElementMock('div', [
|
||||
JSXAttributeMock('style', 'some-junk'),
|
||||
JSXSpreadAttributeMock('props'),
|
||||
], [])),
|
||||
true,
|
||||
'spread operator in attributes, returns true',
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
83
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test.js
generated
vendored
83
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test.js
generated
vendored
|
|
@ -1,14 +1,14 @@
|
|||
import expect from 'expect';
|
||||
import { version as eslintVersion } from 'eslint/package.json';
|
||||
import test from 'tape';
|
||||
import semver from 'semver';
|
||||
|
||||
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
|
||||
|
||||
describe('parserOptionsMapper', () => {
|
||||
it('should return an test case object', () => {
|
||||
const testCase = {
|
||||
code: '<div />',
|
||||
errors: [],
|
||||
options: {},
|
||||
};
|
||||
expect(parserOptionsMapper(testCase)).toEqual({
|
||||
const usingLegacy = semver.major(eslintVersion) < 9;
|
||||
|
||||
test('parserOptionsMapper', (t) => {
|
||||
const expectedResult = usingLegacy
|
||||
? {
|
||||
code: '<div />',
|
||||
errors: [],
|
||||
options: {},
|
||||
|
|
@ -19,18 +19,36 @@ describe('parserOptionsMapper', () => {
|
|||
jsx: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
it('should allow for overriding parserOptions', () => {
|
||||
const testCase = {
|
||||
settings: {},
|
||||
}
|
||||
: {
|
||||
code: '<div />',
|
||||
errors: [],
|
||||
options: {},
|
||||
parserOptions: {
|
||||
ecmaVersion: 5,
|
||||
languageOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
experimentalObjectRestSpread: true,
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
settings: {},
|
||||
};
|
||||
expect(parserOptionsMapper(testCase)).toEqual({
|
||||
|
||||
t.deepEqual(
|
||||
parserOptionsMapper({
|
||||
code: '<div />',
|
||||
errors: [],
|
||||
options: {},
|
||||
}),
|
||||
expectedResult,
|
||||
'returns a test case object',
|
||||
);
|
||||
|
||||
const expectedResult2 = usingLegacy
|
||||
? {
|
||||
code: '<div />',
|
||||
errors: [],
|
||||
options: {},
|
||||
|
|
@ -41,6 +59,35 @@ describe('parserOptionsMapper', () => {
|
|||
jsx: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
settings: {},
|
||||
}
|
||||
: {
|
||||
code: '<div />',
|
||||
errors: [],
|
||||
options: {},
|
||||
languageOptions: {
|
||||
ecmaVersion: 5,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
experimentalObjectRestSpread: true,
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
settings: {},
|
||||
};
|
||||
t.deepEqual(
|
||||
parserOptionsMapper({
|
||||
code: '<div />',
|
||||
errors: [],
|
||||
options: {},
|
||||
languageOptions: {
|
||||
ecmaVersion: 5,
|
||||
},
|
||||
}),
|
||||
expectedResult2,
|
||||
'allows for overriding parserOptions',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
44
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test.js
generated
vendored
44
node_modules/eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test.js
generated
vendored
|
|
@ -1,29 +1,35 @@
|
|||
import expect from 'expect';
|
||||
import test from 'tape';
|
||||
|
||||
import { generateObjSchema, arraySchema, enumArraySchema } from '../../../src/util/schemas';
|
||||
|
||||
describe('schemas', () => {
|
||||
it('should generate an object schema with correct properties', () => {
|
||||
test('schemas', (t) => {
|
||||
t.test('should generate an object schema with correct properties', (st) => {
|
||||
const schema = generateObjSchema({
|
||||
foo: 'bar',
|
||||
baz: arraySchema,
|
||||
});
|
||||
const properties = schema.properties || {};
|
||||
|
||||
expect(properties.foo).toEqual(properties.foo, 'bar');
|
||||
expect(properties.baz.type).toEqual('array');
|
||||
});
|
||||
describe('enumArraySchema', () => {
|
||||
it('works with no arguments', () => {
|
||||
expect(enumArraySchema()).toEqual({
|
||||
additionalItems: false,
|
||||
items: {
|
||||
enum: [],
|
||||
type: 'string',
|
||||
},
|
||||
minItems: 0,
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
});
|
||||
});
|
||||
st.deepEqual(properties.foo, properties.foo, 'bar');
|
||||
st.deepEqual(properties.baz.type, 'array');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.deepEqual(
|
||||
enumArraySchema(),
|
||||
{
|
||||
additionalItems: false,
|
||||
items: {
|
||||
enum: [],
|
||||
type: 'string',
|
||||
},
|
||||
minItems: 0,
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
},
|
||||
'enumArraySchema works with no arguments',
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/accessible-emoji.md
generated
vendored
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/accessible-emoji.md
generated
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
Emoji have become a common way of communicating content to the end user. To a person using a screenreader, however, they may not be aware that this content is there at all. By wrapping the emoji in a `<span>`, giving it the `role="img"`, and providing a useful description in `aria-label`, the screenreader will treat the emoji as an image in the accessibility tree with an accessible name for the end user.
|
||||
Emoji have become a common way of communicating content to the end user. To a person using a screen reader, however, they may not be aware that this content is there at all. By wrapping the emoji in a `<span>`, giving it the `role="img"`, and providing a useful description in `aria-label`, the screen reader will treat the emoji as an image in the accessibility tree with an accessible name for the end user.
|
||||
|
||||
## Rule details
|
||||
|
||||
|
|
|
|||
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/anchor-ambiguous-text.md
generated
vendored
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/anchor-ambiguous-text.md
generated
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
Enforces `<a>` values are not exact matches for the phrases "click here", "here", "link", "a link", or "learn more". Screenreaders announce tags as links/interactive, but rely on values for context. Ambiguous anchor descriptions do not provide sufficient context for users.
|
||||
Enforces `<a>` values are not exact matches for the phrases "click here", "here", "link", "a link", or "learn more". Screen readers announce tags as links/interactive, but rely on values for context. Ambiguous anchor descriptions do not provide sufficient context for users.
|
||||
|
||||
## Rule options
|
||||
|
||||
|
|
|
|||
4
node_modules/eslint-plugin-jsx-a11y/docs/rules/anchor-has-content.md
generated
vendored
4
node_modules/eslint-plugin-jsx-a11y/docs/rules/anchor-has-content.md
generated
vendored
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
Enforce that anchors have content and that the content is accessible to screen readers. Accessible means that it is not hidden using the `aria-hidden` prop. Refer to the references to learn about why this is important.
|
||||
|
||||
Alternatively, you may use the `title` prop or the `aria-label` prop.
|
||||
|
||||
## Rule options
|
||||
|
||||
This rule takes one optional object argument of type object:
|
||||
|
|
@ -45,6 +47,8 @@ return (
|
|||
<a>Anchor Content!</a>
|
||||
<a><TextWrapper /></a>
|
||||
<a dangerouslySetInnerHTML={{ __html: 'foo' }} />
|
||||
<a title='foo' />
|
||||
<a aria-label='foo' />
|
||||
```
|
||||
|
||||
### Fail
|
||||
|
|
|
|||
9
node_modules/eslint-plugin-jsx-a11y/docs/rules/aria-activedescendant-has-tabindex.md
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/docs/rules/aria-activedescendant-has-tabindex.md
generated
vendored
|
|
@ -15,8 +15,7 @@ element will be applied as the value of `aria-activedescendant` on the input
|
|||
element.
|
||||
|
||||
Because an element with `aria-activedescendant` must be tabbable, it must either
|
||||
have an inherent `tabIndex` of zero or declare a `tabIndex` of zero with the `tabIndex`
|
||||
attribute.
|
||||
have an inherent `tabIndex` of zero or declare a `tabIndex` attribute.
|
||||
|
||||
## Rule details
|
||||
|
||||
|
|
@ -34,16 +33,16 @@ This rule takes no arguments.
|
|||
<div aria-activedescendant={someID} tabIndex={0} />
|
||||
<div aria-activedescendant={someID} tabIndex="0" />
|
||||
<div aria-activedescendant={someID} tabIndex={1} />
|
||||
<div aria-activedescendant={someID} tabIndex={-1} />
|
||||
<div aria-activedescendant={someID} tabIndex="-1" />
|
||||
<input aria-activedescendant={someID} />
|
||||
<input aria-activedescendant={someID} tabIndex={0} />
|
||||
<input aria-activedescendant={someID} tabIndex={-1} />
|
||||
```
|
||||
|
||||
### Fail
|
||||
```jsx
|
||||
<div aria-activedescendant={someID} />
|
||||
<div aria-activedescendant={someID} tabIndex={-1} />
|
||||
<div aria-activedescendant={someID} tabIndex="-1" />
|
||||
<input aria-activedescendant={someID} tabIndex={-1} />
|
||||
```
|
||||
|
||||
## Accessibility guidelines
|
||||
|
|
|
|||
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/click-events-have-key-events.md
generated
vendored
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/click-events-have-key-events.md
generated
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
Enforce `onClick` is accompanied by at least one of the following: `onKeyUp`, `onKeyDown`, `onKeyPress`. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users. This does not apply for interactive or hidden elements.
|
||||
Enforce `onClick` is accompanied by at least one of the following: `onKeyUp`, `onKeyDown`, `onKeyPress`. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screen reader users. This does not apply for interactive or hidden elements.
|
||||
|
||||
## Rule details
|
||||
|
||||
|
|
|
|||
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/img-redundant-alt.md
generated
vendored
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/img-redundant-alt.md
generated
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
Enforce img alt attribute does not contain the word image, picture, or photo. Screenreaders already announce `img` elements as an image. There is no need to use words such as *image*, *photo*, and/or *picture*.
|
||||
Enforce img alt attribute does not contain the word image, picture, or photo. Screen readers already announce `img` elements as an image. There is no need to use words such as *image*, *photo*, and/or *picture*.
|
||||
|
||||
## Rule options
|
||||
|
||||
|
|
|
|||
4
node_modules/eslint-plugin-jsx-a11y/docs/rules/label-has-associated-control.md
generated
vendored
4
node_modules/eslint-plugin-jsx-a11y/docs/rules/label-has-associated-control.md
generated
vendored
|
|
@ -104,9 +104,13 @@ This rule takes one optional object argument of type object:
|
|||
```
|
||||
|
||||
`labelComponents` is a list of custom React Component names that should be checked for an associated control.
|
||||
|
||||
`labelAttributes` is a list of attributes to check on the label component and its children for a label. Use this if you have a custom component that uses a string passed on a prop to render an HTML `label`, for example.
|
||||
|
||||
`controlComponents` is a list of custom React Components names that will output an input element. [Glob format](https://linuxhint.com/bash_globbing_tutorial/) is also supported for specifying names (e.g., `Label*` matches `LabelComponent` but not `CustomLabel`, `????Label` matches `LinkLabel` but not `CustomLabel`).
|
||||
|
||||
`assert` asserts that the label has htmlFor, a nested label, both or either. Available options: `'htmlFor', 'nesting', 'both', 'either'`.
|
||||
|
||||
`depth` (default 2, max 25) is an integer that determines how deep within a `JSXElement` label the rule should look for text content or an element with a label to determine if the `label` element will have an accessible label.
|
||||
|
||||
### Fail
|
||||
|
|
|
|||
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/label-has-for.md
generated
vendored
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/label-has-for.md
generated
vendored
|
|
@ -13,7 +13,7 @@ Enforce label tags have associated control.
|
|||
There are two supported ways to associate a label with a control:
|
||||
|
||||
- nesting: by wrapping a control in a label tag
|
||||
- id: by using the prop `htmlFor` as in `htmlFor=[ID of control]`
|
||||
- id: by using the prop `htmlFor` (or any configured attribute) as in `htmlFor=[ID of control]`
|
||||
|
||||
To fully cover 100% of assistive devices, you're encouraged to validate for both nesting and id.
|
||||
|
||||
|
|
|
|||
32
node_modules/eslint-plugin-jsx-a11y/docs/rules/mouse-events-have-key-events.md
generated
vendored
32
node_modules/eslint-plugin-jsx-a11y/docs/rules/mouse-events-have-key-events.md
generated
vendored
|
|
@ -4,11 +4,37 @@
|
|||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
Enforce onmouseover/onmouseout are accompanied by onfocus/onblur. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.
|
||||
Enforce onmouseover/onmouseout are accompanied by onfocus/onblur. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screen reader users.
|
||||
|
||||
## Rule details
|
||||
## Rule options
|
||||
|
||||
This rule takes no arguments.
|
||||
By default, this rule checks that `onmouseover` is paired with `onfocus` and that `onmouseout` is paired with `onblur`. This rule takes an optional argument to specify other handlers to check for "hover in" and/or "hover out" events:
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": {
|
||||
"jsx-a11y/mouse-events-have-key-events": [
|
||||
"error",
|
||||
{
|
||||
"hoverInHandlers": [
|
||||
"onMouseOver",
|
||||
"onMouseEnter",
|
||||
"onPointerOver",
|
||||
"onPointerEnter"
|
||||
],
|
||||
"hoverOutHandlers": [
|
||||
"onMouseOut",
|
||||
"onMouseLeave",
|
||||
"onPointerOut",
|
||||
"onPointerLeave"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that while `onmouseover` and `onmouseout` are checked by default if no arguments are passed in, those are *not* included by default if you *do* provide an argument, so remember to explicitly include them if you want to check them.
|
||||
|
||||
### Succeed
|
||||
```jsx
|
||||
|
|
|
|||
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/no-access-key.md
generated
vendored
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/no-access-key.md
generated
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
Enforce no accessKey prop on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screenreaders and keyboard-only users create accessibility complications so to avoid complications, access keys should not be used.
|
||||
Enforce no accessKey prop on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen readers and keyboard-only users create accessibility complications so to avoid complications, access keys should not be used.
|
||||
|
||||
### References
|
||||
1. [WebAIM](https://webaim.org/techniques/keyboard/accesskey#spec)
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ Adjust the list of handler prop names in the handlers array to increase or decre
|
|||
<div onClick={() => void 0} role="presentation" />
|
||||
<input type="text" onClick={() => void 0} /> // Interactive element does not require role.
|
||||
<button onClick={() => void 0} className="foo" /> // button is interactive.
|
||||
<div onClick={() => void 0} role="button" aria-hidden /> // This is hidden from screenreader.
|
||||
<div onClick={() => void 0} role="button" aria-hidden /> // This is hidden from screen reader.
|
||||
<Input onClick={() => void 0} type="hidden" /> // This is a higher-level DOM component
|
||||
```
|
||||
|
||||
|
|
|
|||
1
node_modules/eslint-plugin-jsx-a11y/docs/rules/no-redundant-roles.md
generated
vendored
1
node_modules/eslint-plugin-jsx-a11y/docs/rules/no-redundant-roles.md
generated
vendored
|
|
@ -43,3 +43,4 @@ General best practice (reference resources)
|
|||
### Resources
|
||||
|
||||
- [ARIA Spec, ARIA Adds Nothing to Default Semantics of Most HTML Elements](https://www.w3.org/TR/using-aria/#aria-does-nothing)
|
||||
- [Identifying SVG as an image](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#identifying_svg_as_an_image)
|
||||
|
|
|
|||
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/no-static-element-interactions.md
generated
vendored
2
node_modules/eslint-plugin-jsx-a11y/docs/rules/no-static-element-interactions.md
generated
vendored
|
|
@ -21,7 +21,7 @@ Indicate the element's role with the `role` attribute:
|
|||
onClick={onClickHandler}
|
||||
onKeyPress={onKeyPressHandler}
|
||||
role="button"
|
||||
tabIndex="0">
|
||||
tabindex="0">
|
||||
Save
|
||||
</div>
|
||||
```
|
||||
|
|
|
|||
11
node_modules/eslint-plugin-jsx-a11y/lib/configs/flat-config-base.js
generated
vendored
Normal file
11
node_modules/eslint-plugin-jsx-a11y/lib/configs/flat-config-base.js
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
9
node_modules/eslint-plugin-jsx-a11y/lib/configs/legacy-config-base.js
generated
vendored
Normal file
9
node_modules/eslint-plugin-jsx-a11y/lib/configs/legacy-config-base.js
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
}
|
||||
}
|
||||
};
|
||||
373
node_modules/eslint-plugin-jsx-a11y/lib/index.js
generated
vendored
373
node_modules/eslint-plugin-jsx-a11y/lib/index.js
generated
vendored
|
|
@ -1,177 +1,208 @@
|
|||
"use strict";
|
||||
|
||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
||||
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
||||
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||
/* eslint-disable global-require */
|
||||
var flatConfigBase = require('./configs/flat-config-base');
|
||||
var legacyConfigBase = require('./configs/legacy-config-base');
|
||||
var _require = require('../package.json'),
|
||||
name = _require.name,
|
||||
version = _require.version;
|
||||
var allRules = {
|
||||
'accessible-emoji': require('./rules/accessible-emoji'),
|
||||
'alt-text': require('./rules/alt-text'),
|
||||
'anchor-ambiguous-text': require('./rules/anchor-ambiguous-text'),
|
||||
'anchor-has-content': require('./rules/anchor-has-content'),
|
||||
'anchor-is-valid': require('./rules/anchor-is-valid'),
|
||||
'aria-activedescendant-has-tabindex': require('./rules/aria-activedescendant-has-tabindex'),
|
||||
'aria-props': require('./rules/aria-props'),
|
||||
'aria-proptypes': require('./rules/aria-proptypes'),
|
||||
'aria-role': require('./rules/aria-role'),
|
||||
'aria-unsupported-elements': require('./rules/aria-unsupported-elements'),
|
||||
'autocomplete-valid': require('./rules/autocomplete-valid'),
|
||||
'click-events-have-key-events': require('./rules/click-events-have-key-events'),
|
||||
'control-has-associated-label': require('./rules/control-has-associated-label'),
|
||||
'heading-has-content': require('./rules/heading-has-content'),
|
||||
'html-has-lang': require('./rules/html-has-lang'),
|
||||
'iframe-has-title': require('./rules/iframe-has-title'),
|
||||
'img-redundant-alt': require('./rules/img-redundant-alt'),
|
||||
'interactive-supports-focus': require('./rules/interactive-supports-focus'),
|
||||
'label-has-associated-control': require('./rules/label-has-associated-control'),
|
||||
'label-has-for': require('./rules/label-has-for'),
|
||||
lang: require('./rules/lang'),
|
||||
'media-has-caption': require('./rules/media-has-caption'),
|
||||
'mouse-events-have-key-events': require('./rules/mouse-events-have-key-events'),
|
||||
'no-access-key': require('./rules/no-access-key'),
|
||||
'no-aria-hidden-on-focusable': require('./rules/no-aria-hidden-on-focusable'),
|
||||
'no-autofocus': require('./rules/no-autofocus'),
|
||||
'no-distracting-elements': require('./rules/no-distracting-elements'),
|
||||
'no-interactive-element-to-noninteractive-role': require('./rules/no-interactive-element-to-noninteractive-role'),
|
||||
'no-noninteractive-element-interactions': require('./rules/no-noninteractive-element-interactions'),
|
||||
'no-noninteractive-element-to-interactive-role': require('./rules/no-noninteractive-element-to-interactive-role'),
|
||||
'no-noninteractive-tabindex': require('./rules/no-noninteractive-tabindex'),
|
||||
'no-onchange': require('./rules/no-onchange'),
|
||||
'no-redundant-roles': require('./rules/no-redundant-roles'),
|
||||
'no-static-element-interactions': require('./rules/no-static-element-interactions'),
|
||||
'prefer-tag-over-role': require('./rules/prefer-tag-over-role'),
|
||||
'role-has-required-aria-props': require('./rules/role-has-required-aria-props'),
|
||||
'role-supports-aria-props': require('./rules/role-supports-aria-props'),
|
||||
scope: require('./rules/scope'),
|
||||
'tabindex-no-positive': require('./rules/tabindex-no-positive')
|
||||
};
|
||||
var recommendedRules = {
|
||||
'jsx-a11y/alt-text': 'error',
|
||||
'jsx-a11y/anchor-ambiguous-text': 'off',
|
||||
// TODO: error
|
||||
'jsx-a11y/anchor-has-content': 'error',
|
||||
'jsx-a11y/anchor-is-valid': 'error',
|
||||
'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
|
||||
'jsx-a11y/aria-props': 'error',
|
||||
'jsx-a11y/aria-proptypes': 'error',
|
||||
'jsx-a11y/aria-role': 'error',
|
||||
'jsx-a11y/aria-unsupported-elements': 'error',
|
||||
'jsx-a11y/autocomplete-valid': 'error',
|
||||
'jsx-a11y/click-events-have-key-events': 'error',
|
||||
'jsx-a11y/control-has-associated-label': ['off', {
|
||||
ignoreElements: ['audio', 'canvas', 'embed', 'input', 'textarea', 'tr', 'video'],
|
||||
ignoreRoles: ['grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'row', 'tablist', 'toolbar', 'tree', 'treegrid'],
|
||||
includeRoles: ['alert', 'dialog']
|
||||
}],
|
||||
'jsx-a11y/heading-has-content': 'error',
|
||||
'jsx-a11y/html-has-lang': 'error',
|
||||
'jsx-a11y/iframe-has-title': 'error',
|
||||
'jsx-a11y/img-redundant-alt': 'error',
|
||||
'jsx-a11y/interactive-supports-focus': ['error', {
|
||||
tabbable: ['button', 'checkbox', 'link', 'searchbox', 'spinbutton', 'switch', 'textbox']
|
||||
}],
|
||||
'jsx-a11y/label-has-associated-control': 'error',
|
||||
'jsx-a11y/label-has-for': 'off',
|
||||
'jsx-a11y/media-has-caption': 'error',
|
||||
'jsx-a11y/mouse-events-have-key-events': 'error',
|
||||
'jsx-a11y/no-access-key': 'error',
|
||||
'jsx-a11y/no-autofocus': 'error',
|
||||
'jsx-a11y/no-distracting-elements': 'error',
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': ['error', {
|
||||
tr: ['none', 'presentation'],
|
||||
canvas: ['img']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-element-interactions': ['error', {
|
||||
handlers: ['onClick', 'onError', 'onLoad', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'],
|
||||
alert: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
|
||||
body: ['onError', 'onLoad'],
|
||||
dialog: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
|
||||
iframe: ['onError', 'onLoad'],
|
||||
img: ['onError', 'onLoad']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-element-to-interactive-role': ['error', {
|
||||
ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
||||
ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
||||
li: ['menuitem', 'menuitemradio', 'menuitemcheckbox', 'option', 'row', 'tab', 'treeitem'],
|
||||
table: ['grid'],
|
||||
td: ['gridcell'],
|
||||
fieldset: ['radiogroup', 'presentation']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-tabindex': ['error', {
|
||||
tags: [],
|
||||
roles: ['tabpanel'],
|
||||
allowExpressionValues: true
|
||||
}],
|
||||
'jsx-a11y/no-redundant-roles': 'error',
|
||||
'jsx-a11y/no-static-element-interactions': ['error', {
|
||||
allowExpressionValues: true,
|
||||
handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp']
|
||||
}],
|
||||
'jsx-a11y/role-has-required-aria-props': 'error',
|
||||
'jsx-a11y/role-supports-aria-props': 'error',
|
||||
'jsx-a11y/scope': 'error',
|
||||
'jsx-a11y/tabindex-no-positive': 'error'
|
||||
};
|
||||
var strictRules = {
|
||||
'jsx-a11y/alt-text': 'error',
|
||||
'jsx-a11y/anchor-has-content': 'error',
|
||||
'jsx-a11y/anchor-is-valid': 'error',
|
||||
'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
|
||||
'jsx-a11y/aria-props': 'error',
|
||||
'jsx-a11y/aria-proptypes': 'error',
|
||||
'jsx-a11y/aria-role': 'error',
|
||||
'jsx-a11y/aria-unsupported-elements': 'error',
|
||||
'jsx-a11y/autocomplete-valid': 'error',
|
||||
'jsx-a11y/click-events-have-key-events': 'error',
|
||||
'jsx-a11y/control-has-associated-label': ['off', {
|
||||
ignoreElements: ['audio', 'canvas', 'embed', 'input', 'textarea', 'tr', 'video'],
|
||||
ignoreRoles: ['grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'row', 'tablist', 'toolbar', 'tree', 'treegrid'],
|
||||
includeRoles: ['alert', 'dialog']
|
||||
}],
|
||||
'jsx-a11y/heading-has-content': 'error',
|
||||
'jsx-a11y/html-has-lang': 'error',
|
||||
'jsx-a11y/iframe-has-title': 'error',
|
||||
'jsx-a11y/img-redundant-alt': 'error',
|
||||
'jsx-a11y/interactive-supports-focus': ['error', {
|
||||
tabbable: ['button', 'checkbox', 'link', 'progressbar', 'searchbox', 'slider', 'spinbutton', 'switch', 'textbox']
|
||||
}],
|
||||
'jsx-a11y/label-has-for': 'off',
|
||||
'jsx-a11y/label-has-associated-control': 'error',
|
||||
'jsx-a11y/media-has-caption': 'error',
|
||||
'jsx-a11y/mouse-events-have-key-events': 'error',
|
||||
'jsx-a11y/no-access-key': 'error',
|
||||
'jsx-a11y/no-autofocus': 'error',
|
||||
'jsx-a11y/no-distracting-elements': 'error',
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'error',
|
||||
'jsx-a11y/no-noninteractive-element-interactions': ['error', {
|
||||
body: ['onError', 'onLoad'],
|
||||
iframe: ['onError', 'onLoad'],
|
||||
img: ['onError', 'onLoad']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
|
||||
'jsx-a11y/no-noninteractive-tabindex': 'error',
|
||||
'jsx-a11y/no-redundant-roles': 'error',
|
||||
'jsx-a11y/no-static-element-interactions': 'error',
|
||||
'jsx-a11y/role-has-required-aria-props': 'error',
|
||||
'jsx-a11y/role-supports-aria-props': 'error',
|
||||
'jsx-a11y/scope': 'error',
|
||||
'jsx-a11y/tabindex-no-positive': 'error'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
'accessible-emoji': require('./rules/accessible-emoji'),
|
||||
'alt-text': require('./rules/alt-text'),
|
||||
'anchor-ambiguous-text': require('./rules/anchor-ambiguous-text'),
|
||||
'anchor-has-content': require('./rules/anchor-has-content'),
|
||||
'anchor-is-valid': require('./rules/anchor-is-valid'),
|
||||
'aria-activedescendant-has-tabindex': require('./rules/aria-activedescendant-has-tabindex'),
|
||||
'aria-props': require('./rules/aria-props'),
|
||||
'aria-proptypes': require('./rules/aria-proptypes'),
|
||||
'aria-role': require('./rules/aria-role'),
|
||||
'aria-unsupported-elements': require('./rules/aria-unsupported-elements'),
|
||||
'autocomplete-valid': require('./rules/autocomplete-valid'),
|
||||
'click-events-have-key-events': require('./rules/click-events-have-key-events'),
|
||||
'control-has-associated-label': require('./rules/control-has-associated-label'),
|
||||
'heading-has-content': require('./rules/heading-has-content'),
|
||||
'html-has-lang': require('./rules/html-has-lang'),
|
||||
'iframe-has-title': require('./rules/iframe-has-title'),
|
||||
'img-redundant-alt': require('./rules/img-redundant-alt'),
|
||||
'interactive-supports-focus': require('./rules/interactive-supports-focus'),
|
||||
'label-has-associated-control': require('./rules/label-has-associated-control'),
|
||||
'label-has-for': require('./rules/label-has-for'),
|
||||
lang: require('./rules/lang'),
|
||||
'media-has-caption': require('./rules/media-has-caption'),
|
||||
'mouse-events-have-key-events': require('./rules/mouse-events-have-key-events'),
|
||||
'no-access-key': require('./rules/no-access-key'),
|
||||
'no-aria-hidden-on-focusable': require('./rules/no-aria-hidden-on-focusable'),
|
||||
'no-autofocus': require('./rules/no-autofocus'),
|
||||
'no-distracting-elements': require('./rules/no-distracting-elements'),
|
||||
'no-interactive-element-to-noninteractive-role': require('./rules/no-interactive-element-to-noninteractive-role'),
|
||||
'no-noninteractive-element-interactions': require('./rules/no-noninteractive-element-interactions'),
|
||||
'no-noninteractive-element-to-interactive-role': require('./rules/no-noninteractive-element-to-interactive-role'),
|
||||
'no-noninteractive-tabindex': require('./rules/no-noninteractive-tabindex'),
|
||||
'no-onchange': require('./rules/no-onchange'),
|
||||
'no-redundant-roles': require('./rules/no-redundant-roles'),
|
||||
'no-static-element-interactions': require('./rules/no-static-element-interactions'),
|
||||
'prefer-tag-over-role': require('./rules/prefer-tag-over-role'),
|
||||
'role-has-required-aria-props': require('./rules/role-has-required-aria-props'),
|
||||
'role-supports-aria-props': require('./rules/role-supports-aria-props'),
|
||||
scope: require('./rules/scope'),
|
||||
'tabindex-no-positive': require('./rules/tabindex-no-positive')
|
||||
/** Base plugin object */
|
||||
var jsxA11y = {
|
||||
meta: {
|
||||
name,
|
||||
version
|
||||
},
|
||||
configs: {
|
||||
recommended: {
|
||||
plugins: ['jsx-a11y'],
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'jsx-a11y/alt-text': 'error',
|
||||
'jsx-a11y/anchor-ambiguous-text': 'off',
|
||||
// TODO: error
|
||||
'jsx-a11y/anchor-has-content': 'error',
|
||||
'jsx-a11y/anchor-is-valid': 'error',
|
||||
'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
|
||||
'jsx-a11y/aria-props': 'error',
|
||||
'jsx-a11y/aria-proptypes': 'error',
|
||||
'jsx-a11y/aria-role': 'error',
|
||||
'jsx-a11y/aria-unsupported-elements': 'error',
|
||||
'jsx-a11y/autocomplete-valid': 'error',
|
||||
'jsx-a11y/click-events-have-key-events': 'error',
|
||||
'jsx-a11y/control-has-associated-label': ['off', {
|
||||
ignoreElements: ['audio', 'canvas', 'embed', 'input', 'textarea', 'tr', 'video'],
|
||||
ignoreRoles: ['grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'row', 'tablist', 'toolbar', 'tree', 'treegrid'],
|
||||
includeRoles: ['alert', 'dialog']
|
||||
}],
|
||||
'jsx-a11y/heading-has-content': 'error',
|
||||
'jsx-a11y/html-has-lang': 'error',
|
||||
'jsx-a11y/iframe-has-title': 'error',
|
||||
'jsx-a11y/img-redundant-alt': 'error',
|
||||
'jsx-a11y/interactive-supports-focus': ['error', {
|
||||
tabbable: ['button', 'checkbox', 'link', 'searchbox', 'spinbutton', 'switch', 'textbox']
|
||||
}],
|
||||
'jsx-a11y/label-has-associated-control': 'error',
|
||||
'jsx-a11y/label-has-for': 'off',
|
||||
'jsx-a11y/media-has-caption': 'error',
|
||||
'jsx-a11y/mouse-events-have-key-events': 'error',
|
||||
'jsx-a11y/no-access-key': 'error',
|
||||
'jsx-a11y/no-autofocus': 'error',
|
||||
'jsx-a11y/no-distracting-elements': 'error',
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': ['error', {
|
||||
tr: ['none', 'presentation'],
|
||||
canvas: ['img']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-element-interactions': ['error', {
|
||||
handlers: ['onClick', 'onError', 'onLoad', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'],
|
||||
alert: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
|
||||
body: ['onError', 'onLoad'],
|
||||
dialog: ['onKeyUp', 'onKeyDown', 'onKeyPress'],
|
||||
iframe: ['onError', 'onLoad'],
|
||||
img: ['onError', 'onLoad']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-element-to-interactive-role': ['error', {
|
||||
ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
||||
ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
||||
li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
|
||||
table: ['grid'],
|
||||
td: ['gridcell'],
|
||||
fieldset: ['radiogroup', 'presentation']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-tabindex': ['error', {
|
||||
tags: [],
|
||||
roles: ['tabpanel'],
|
||||
allowExpressionValues: true
|
||||
}],
|
||||
'jsx-a11y/no-redundant-roles': 'error',
|
||||
'jsx-a11y/no-static-element-interactions': ['error', {
|
||||
allowExpressionValues: true,
|
||||
handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp']
|
||||
}],
|
||||
'jsx-a11y/role-has-required-aria-props': 'error',
|
||||
'jsx-a11y/role-supports-aria-props': 'error',
|
||||
'jsx-a11y/scope': 'error',
|
||||
'jsx-a11y/tabindex-no-positive': 'error'
|
||||
}
|
||||
},
|
||||
strict: {
|
||||
plugins: ['jsx-a11y'],
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'jsx-a11y/alt-text': 'error',
|
||||
'jsx-a11y/anchor-has-content': 'error',
|
||||
'jsx-a11y/anchor-is-valid': 'error',
|
||||
'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
|
||||
'jsx-a11y/aria-props': 'error',
|
||||
'jsx-a11y/aria-proptypes': 'error',
|
||||
'jsx-a11y/aria-role': 'error',
|
||||
'jsx-a11y/aria-unsupported-elements': 'error',
|
||||
'jsx-a11y/autocomplete-valid': 'error',
|
||||
'jsx-a11y/click-events-have-key-events': 'error',
|
||||
'jsx-a11y/control-has-associated-label': ['off', {
|
||||
ignoreElements: ['audio', 'canvas', 'embed', 'input', 'textarea', 'tr', 'video'],
|
||||
ignoreRoles: ['grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'row', 'tablist', 'toolbar', 'tree', 'treegrid'],
|
||||
includeRoles: ['alert', 'dialog']
|
||||
}],
|
||||
'jsx-a11y/heading-has-content': 'error',
|
||||
'jsx-a11y/html-has-lang': 'error',
|
||||
'jsx-a11y/iframe-has-title': 'error',
|
||||
'jsx-a11y/img-redundant-alt': 'error',
|
||||
'jsx-a11y/interactive-supports-focus': ['error', {
|
||||
tabbable: ['button', 'checkbox', 'link', 'progressbar', 'searchbox', 'slider', 'spinbutton', 'switch', 'textbox']
|
||||
}],
|
||||
'jsx-a11y/label-has-for': 'off',
|
||||
'jsx-a11y/label-has-associated-control': 'error',
|
||||
'jsx-a11y/media-has-caption': 'error',
|
||||
'jsx-a11y/mouse-events-have-key-events': 'error',
|
||||
'jsx-a11y/no-access-key': 'error',
|
||||
'jsx-a11y/no-autofocus': 'error',
|
||||
'jsx-a11y/no-distracting-elements': 'error',
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'error',
|
||||
'jsx-a11y/no-noninteractive-element-interactions': ['error', {
|
||||
body: ['onError', 'onLoad'],
|
||||
iframe: ['onError', 'onLoad'],
|
||||
img: ['onError', 'onLoad']
|
||||
}],
|
||||
'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
|
||||
'jsx-a11y/no-noninteractive-tabindex': 'error',
|
||||
'jsx-a11y/no-redundant-roles': 'error',
|
||||
'jsx-a11y/no-static-element-interactions': 'error',
|
||||
'jsx-a11y/role-has-required-aria-props': 'error',
|
||||
'jsx-a11y/role-supports-aria-props': 'error',
|
||||
'jsx-a11y/scope': 'error',
|
||||
'jsx-a11y/tabindex-no-positive': 'error'
|
||||
}
|
||||
rules: _objectSpread({}, allRules)
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a ruleset and optionally a flat config name, generate a config.
|
||||
* @param {object} rules - ruleset for this config
|
||||
* @param {string} flatConfigName - name for the config if flat
|
||||
* @returns Config for this set of rules.
|
||||
*/
|
||||
var createConfig = function createConfig(rules, flatConfigName) {
|
||||
return _objectSpread(_objectSpread({}, flatConfigName ? _objectSpread(_objectSpread({}, flatConfigBase), {}, {
|
||||
name: "jsx-a11y/".concat(flatConfigName),
|
||||
plugins: {
|
||||
'jsx-a11y': jsxA11y
|
||||
}
|
||||
}
|
||||
};
|
||||
}) : _objectSpread(_objectSpread({}, legacyConfigBase), {}, {
|
||||
plugins: ['jsx-a11y']
|
||||
})), {}, {
|
||||
rules: _objectSpread({}, rules)
|
||||
});
|
||||
};
|
||||
|
||||
// Create configs for the plugin object
|
||||
var configs = {
|
||||
recommended: createConfig(recommendedRules),
|
||||
strict: createConfig(strictRules)
|
||||
};
|
||||
var flatConfigs = {
|
||||
recommended: createConfig(recommendedRules, 'recommended'),
|
||||
strict: createConfig(strictRules, 'strict')
|
||||
};
|
||||
module.exports = _objectSpread(_objectSpread({}, jsxA11y), {}, {
|
||||
configs,
|
||||
flatConfigs
|
||||
});
|
||||
14
node_modules/eslint-plugin-jsx-a11y/lib/rules/accessible-emoji.js
generated
vendored
14
node_modules/eslint-plugin-jsx-a11y/lib/rules/accessible-emoji.js
generated
vendored
|
|
@ -1,17 +1,18 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
var _emojiRegex = _interopRequireDefault(require("emoji-regex"));
|
||||
var _jsxAstUtils = require("jsx-ast-utils");
|
||||
var _safeRegexTest = _interopRequireDefault(require("safe-regex-test"));
|
||||
var _schemas = require("../util/schemas");
|
||||
var _getElementType = _interopRequireDefault(require("../util/getElementType"));
|
||||
var _isHiddenFromScreenReader = _interopRequireDefault(require("../util/isHiddenFromScreenReader"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Enforce emojis are wrapped in <span> and provide screenreader access.
|
||||
* @fileoverview Enforce emojis are wrapped in <span> and provide screen reader access.
|
||||
* @author Ethan Cohen
|
||||
*/
|
||||
|
||||
|
|
@ -21,10 +22,10 @@ var _isHiddenFromScreenReader = _interopRequireDefault(require("../util/isHidden
|
|||
|
||||
var errorMessage = 'Emojis should be wrapped in <span>, have role="img", and have an accessible description with aria-label or aria-labelledby.';
|
||||
var schema = (0, _schemas.generateObjSchema)();
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
description: 'Enforce emojis are wrapped in `<span>` and provide screenreader access.',
|
||||
description: 'Enforce emojis are wrapped in `<span>` and provide screen reader access.',
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/accessible-emoji.md'
|
||||
},
|
||||
deprecated: true,
|
||||
|
|
@ -32,17 +33,17 @@ var _default = {
|
|||
},
|
||||
create: function create(context) {
|
||||
var elementType = (0, _getElementType["default"])(context);
|
||||
var testEmoji = (0, _safeRegexTest["default"])((0, _emojiRegex["default"])());
|
||||
return {
|
||||
JSXOpeningElement: function JSXOpeningElement(node) {
|
||||
var literalChildValue = node.parent.children.find(function (child) {
|
||||
return child.type === 'Literal' || child.type === 'JSXText';
|
||||
});
|
||||
if (literalChildValue && (0, _emojiRegex["default"])().test(literalChildValue.value)) {
|
||||
if (literalChildValue && testEmoji(literalChildValue.value)) {
|
||||
var elementIsHidden = (0, _isHiddenFromScreenReader["default"])(elementType(node), node.attributes);
|
||||
if (elementIsHidden) {
|
||||
return; // emoji is decorative
|
||||
}
|
||||
|
||||
var rolePropValue = (0, _jsxAstUtils.getLiteralPropValue)((0, _jsxAstUtils.getProp)(node.attributes, 'role'));
|
||||
var ariaLabelProp = (0, _jsxAstUtils.getProp)(node.attributes, 'aria-label');
|
||||
var arialLabelledByProp = (0, _jsxAstUtils.getProp)(node.attributes, 'aria-labelledby');
|
||||
|
|
@ -59,5 +60,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
5
node_modules/eslint-plugin-jsx-a11y/lib/rules/alt-text.js
generated
vendored
5
node_modules/eslint-plugin-jsx-a11y/lib/rules/alt-text.js
generated
vendored
|
|
@ -1,6 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
|
@ -11,6 +10,7 @@ var _schemas = require("../util/schemas");
|
|||
var _getElementType = _interopRequireDefault(require("../util/getElementType"));
|
||||
var _hasAccessibleChild = _interopRequireDefault(require("../util/hasAccessibleChild"));
|
||||
var _isPresentationRole = _interopRequireDefault(require("../util/isPresentationRole"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Enforce all elements that require alternative text have it.
|
||||
* @author Ethan Cohen
|
||||
|
|
@ -172,7 +172,7 @@ var ruleByElement = {
|
|||
});
|
||||
}
|
||||
};
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/alt-text.md',
|
||||
|
|
@ -215,5 +215,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
7
node_modules/eslint-plugin-jsx-a11y/lib/rules/anchor-ambiguous-text.js
generated
vendored
7
node_modules/eslint-plugin-jsx-a11y/lib/rules/anchor-ambiguous-text.js
generated
vendored
|
|
@ -1,6 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
|
@ -8,6 +7,7 @@ exports["default"] = void 0;
|
|||
var _schemas = require("../util/schemas");
|
||||
var _getAccessibleChildText = _interopRequireDefault(require("../util/getAccessibleChildText"));
|
||||
var _getElementType = _interopRequireDefault(require("../util/getElementType"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Enforce anchor text to not exactly match 'click here', 'here', 'link', 'learn more', and user-specified words.
|
||||
* @author Matt Wang
|
||||
|
|
@ -22,7 +22,7 @@ var DEFAULT_AMBIGUOUS_WORDS = ['click here', 'here', 'link', 'a link', 'learn mo
|
|||
var schema = (0, _schemas.generateObjSchema)({
|
||||
words: _schemas.arraySchema
|
||||
});
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-ambiguous-text.md',
|
||||
|
|
@ -52,7 +52,7 @@ var _default = {
|
|||
}
|
||||
context.report({
|
||||
node,
|
||||
message: 'Ambiguous text within anchor. Screenreader users rely on link text for context; the words "{{wordsList}}" are ambiguous and do not provide enough context.',
|
||||
message: 'Ambiguous text within anchor. Screen reader users rely on link text for context; the words "{{wordsList}}" are ambiguous and do not provide enough context.',
|
||||
data: {
|
||||
wordsList: words.join('", "')
|
||||
}
|
||||
|
|
@ -61,5 +61,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
9
node_modules/eslint-plugin-jsx-a11y/lib/rules/anchor-has-content.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/lib/rules/anchor-has-content.js
generated
vendored
|
|
@ -1,13 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
var _jsxAstUtils = require("jsx-ast-utils");
|
||||
var _getElementType = _interopRequireDefault(require("../util/getElementType"));
|
||||
var _schemas = require("../util/schemas");
|
||||
var _hasAccessibleChild = _interopRequireDefault(require("../util/hasAccessibleChild"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Enforce anchor elements to contain accessible content.
|
||||
* @author Lisa Ring & Niklas Holmberg
|
||||
|
|
@ -21,7 +22,7 @@ var errorMessage = 'Anchors must have content and the content must be accessible
|
|||
var schema = (0, _schemas.generateObjSchema)({
|
||||
components: _schemas.arraySchema
|
||||
});
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-has-content.md',
|
||||
|
|
@ -45,6 +46,9 @@ var _default = {
|
|||
if ((0, _hasAccessibleChild["default"])(node.parent, elementType)) {
|
||||
return;
|
||||
}
|
||||
if ((0, _jsxAstUtils.hasAnyProp)(node.attributes, ['title', 'aria-label'])) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
message: errorMessage
|
||||
|
|
@ -53,5 +57,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
9
node_modules/eslint-plugin-jsx-a11y/lib/rules/anchor-is-valid.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/lib/rules/anchor-is-valid.js
generated
vendored
|
|
@ -1,13 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
var _jsxAstUtils = require("jsx-ast-utils");
|
||||
var _safeRegexTest = _interopRequireDefault(require("safe-regex-test"));
|
||||
var _schemas = require("../util/schemas");
|
||||
var _getElementType = _interopRequireDefault(require("../util/getElementType"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Performs validity check on anchor hrefs. Warns when anchors are used as buttons.
|
||||
* @author Almero Steyn
|
||||
|
|
@ -27,7 +28,7 @@ var schema = (0, _schemas.generateObjSchema)({
|
|||
specialLink: _schemas.arraySchema,
|
||||
aspects: (0, _schemas.enumArraySchema)(allAspects, 1)
|
||||
});
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/anchor-is-valid.md',
|
||||
|
|
@ -37,6 +38,7 @@ var _default = {
|
|||
},
|
||||
create: function create(context) {
|
||||
var elementType = (0, _getElementType["default"])(context);
|
||||
var testJShref = (0, _safeRegexTest["default"])(/^\W*?javascript:/);
|
||||
return {
|
||||
JSXOpeningElement: function JSXOpeningElement(node) {
|
||||
var attributes = node.attributes;
|
||||
|
|
@ -97,7 +99,7 @@ var _default = {
|
|||
|
||||
// Hrefs have been found, now check for validity.
|
||||
var invalidHrefValues = values.filter(function (value) {
|
||||
return value != null && typeof value === 'string' && (!value.length || value === '#' || /^\W*?javascript:/.test(value));
|
||||
return value != null && typeof value === 'string' && (!value.length || value === '#' || testJShref(value));
|
||||
});
|
||||
if (invalidHrefValues.length !== 0) {
|
||||
// If an onClick is found it should be a button, otherwise it is an invalid link.
|
||||
|
|
@ -117,5 +119,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
9
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex.js
generated
vendored
9
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex.js
generated
vendored
|
|
@ -1,17 +1,16 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
||||
var _ariaQuery = require("aria-query");
|
||||
var _jsxAstUtils = require("jsx-ast-utils");
|
||||
var _schemas = require("../util/schemas");
|
||||
var _getElementType = _interopRequireDefault(require("../util/getElementType"));
|
||||
var _getTabIndex = _interopRequireDefault(require("../util/getTabIndex"));
|
||||
var _isInteractiveElement = _interopRequireDefault(require("../util/isInteractiveElement"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Enforce elements with aria-activedescendant are tabbable.
|
||||
* @author Jesse Beach <@jessebeach>
|
||||
|
|
@ -23,8 +22,7 @@ var _isInteractiveElement = _interopRequireDefault(require("../util/isInteractiv
|
|||
|
||||
var errorMessage = 'An element that manages focus with `aria-activedescendant` must have a tabindex';
|
||||
var schema = (0, _schemas.generateObjSchema)();
|
||||
var domElements = (0, _toConsumableArray2["default"])(_ariaQuery.dom.keys());
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-activedescendant-has-tabindex.md',
|
||||
|
|
@ -43,7 +41,7 @@ var _default = {
|
|||
var type = elementType(node);
|
||||
// Do not test higher level JSX components, as we do not know what
|
||||
// low-level DOM element this maps to.
|
||||
if (domElements.indexOf(type) === -1) {
|
||||
if (!_ariaQuery.dom.has(type)) {
|
||||
return;
|
||||
}
|
||||
var tabIndex = (0, _getTabIndex["default"])((0, _jsxAstUtils.getProp)(attributes, 'tabIndex'));
|
||||
|
|
@ -65,5 +63,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
10
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-props.js
generated
vendored
10
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-props.js
generated
vendored
|
|
@ -1,15 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
||||
var _ariaQuery = require("aria-query");
|
||||
var _jsxAstUtils = require("jsx-ast-utils");
|
||||
var _schemas = require("../util/schemas");
|
||||
var _getSuggestion = _interopRequireDefault(require("../util/getSuggestion"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Enforce all aria-* properties are valid.
|
||||
* @author Ethan Cohen
|
||||
|
|
@ -19,7 +18,7 @@ var _getSuggestion = _interopRequireDefault(require("../util/getSuggestion"));
|
|||
// Rule Definition
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var ariaAttributes = (0, _toConsumableArray2["default"])(_ariaQuery.aria.keys());
|
||||
var ariaAttributes = _ariaQuery.aria.keys();
|
||||
var errorMessage = function errorMessage(name) {
|
||||
var suggestions = (0, _getSuggestion["default"])(name, ariaAttributes);
|
||||
var message = "".concat(name, ": This attribute is an invalid ARIA attribute.");
|
||||
|
|
@ -29,7 +28,7 @@ var errorMessage = function errorMessage(name) {
|
|||
return message;
|
||||
};
|
||||
var schema = (0, _schemas.generateObjSchema)();
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-props.md',
|
||||
|
|
@ -46,7 +45,7 @@ var _default = {
|
|||
if (name.indexOf('aria-') !== 0) {
|
||||
return;
|
||||
}
|
||||
var isValid = ariaAttributes.indexOf(name) > -1;
|
||||
var isValid = _ariaQuery.aria.has(name);
|
||||
if (isValid === false) {
|
||||
context.report({
|
||||
node: attribute,
|
||||
|
|
@ -57,5 +56,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
11
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-proptypes.js
generated
vendored
11
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-proptypes.js
generated
vendored
|
|
@ -36,7 +36,7 @@ var errorMessage = function errorMessage(name, type, permittedValues) {
|
|||
return "The value for ".concat(name, " must be a ").concat(type, ".");
|
||||
}
|
||||
};
|
||||
var validityCheck = function validityCheck(value, expectedType, permittedValues) {
|
||||
var _validityCheck = function validityCheck(value, expectedType, permittedValues) {
|
||||
switch (expectedType) {
|
||||
case 'boolean':
|
||||
return typeof value === 'boolean';
|
||||
|
|
@ -54,7 +54,7 @@ var validityCheck = function validityCheck(value, expectedType, permittedValues)
|
|||
return permittedValues.indexOf(typeof value === 'string' ? value.toLowerCase() : value) > -1;
|
||||
case 'idlist':
|
||||
return typeof value === 'string' && value.split(' ').every(function (token) {
|
||||
return validityCheck(token, 'id', []);
|
||||
return _validityCheck(token, 'id', []);
|
||||
});
|
||||
case 'tokenlist':
|
||||
return typeof value === 'string' && value.split(' ').every(function (token) {
|
||||
|
|
@ -65,8 +65,8 @@ var validityCheck = function validityCheck(value, expectedType, permittedValues)
|
|||
}
|
||||
};
|
||||
var schema = (0, _schemas.generateObjSchema)();
|
||||
var _default = {
|
||||
validityCheck,
|
||||
var _default = exports["default"] = {
|
||||
validityCheck: _validityCheck,
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-proptypes.md',
|
||||
|
|
@ -99,7 +99,7 @@ var _default = {
|
|||
var permittedType = attributes.type;
|
||||
var allowUndefined = attributes.allowUndefined || false;
|
||||
var permittedValues = attributes.values || [];
|
||||
var isValid = validityCheck(value, permittedType, permittedValues) || allowUndefined && value === undefined;
|
||||
var isValid = _validityCheck(value, permittedType, permittedValues) || allowUndefined && value === undefined;
|
||||
if (isValid) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -111,5 +111,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
8
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-role.js
generated
vendored
8
node_modules/eslint-plugin-jsx-a11y/lib/rules/aria-role.js
generated
vendored
|
|
@ -1,15 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
||||
var _ariaQuery = require("aria-query");
|
||||
var _jsxAstUtils = require("jsx-ast-utils");
|
||||
var _getElementType = _interopRequireDefault(require("../util/getElementType"));
|
||||
var _schemas = require("../util/schemas");
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
||||
/**
|
||||
* @fileoverview Enforce aria role attribute is valid.
|
||||
* @author Ethan Cohen
|
||||
|
|
@ -33,10 +32,10 @@ var schema = (0, _schemas.generateObjSchema)({
|
|||
"default": false
|
||||
}
|
||||
});
|
||||
var validRoles = new Set((0, _toConsumableArray2["default"])(_ariaQuery.roles.keys()).filter(function (role) {
|
||||
var validRoles = new Set(_ariaQuery.roles.keys().filter(function (role) {
|
||||
return _ariaQuery.roles.get(role)["abstract"] === false;
|
||||
}));
|
||||
var _default = {
|
||||
var _default = exports["default"] = {
|
||||
meta: {
|
||||
docs: {
|
||||
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/aria-role.md',
|
||||
|
|
@ -87,5 +86,4 @@ var _default = {
|
|||
};
|
||||
}
|
||||
};
|
||||
exports["default"] = _default;
|
||||
module.exports = exports.default;
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue