Skip to content

Commit fc6744a

Browse files
authored
Merge branch 'master' into more-flow-configuration
2 parents b8932b2 + cac0693 commit fc6744a

22 files changed

+625
-3885
lines changed

__mocks__/genInteractives.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import {
2+
dom,
3+
roles,
4+
} from 'aria-query';
15
import JSXAttributeMock from './JSXAttributeMock';
26
import JSXElementMock from './JSXElementMock';
3-
import DOMElements from '../src/util/attributes/DOM.json';
4-
import roles from '../src/util/attributes/role.json';
57

6-
const pureInteractiveElements = Object.keys(DOMElements)
7-
.filter(name => DOMElements[name].interactive === true)
8+
const domElements = [...dom.keys()];
9+
10+
const pureInteractiveElements = domElements
11+
.filter(name => dom.get(name).interactive === true)
812
.reduce((interactiveElements, name) => {
913
interactiveElements[name] = [];
1014
return interactiveElements;
@@ -23,8 +27,8 @@ const interactiveElementsMap = {
2327
],
2428
};
2529

26-
const pureNonInteractiveElementsMap = Object.keys(DOMElements)
27-
.filter(name => !DOMElements[name].interactive)
30+
const pureNonInteractiveElementsMap = domElements
31+
.filter(name => !dom.get(name).interactive)
2832
.reduce((nonInteractiveElements, name) => {
2933
nonInteractiveElements[name] = [];
3034
return nonInteractiveElements;
@@ -37,12 +41,14 @@ const nonInteractiveElementsMap = {
3741
],
3842
};
3943

40-
const interactiveRoles = Object.keys(roles).filter(
41-
role => roles[role].interactive === true
44+
const roleNames = [...roles.keys()];
45+
46+
const interactiveRoles = roleNames.filter(
47+
role => roles.get(role).interactive === true
4248
);
4349

44-
const nonInteractiveRoles = Object.keys(roles).filter(
45-
role => roles[role].interactive === false
50+
const nonInteractiveRoles = roleNames.filter(
51+
role => roles.get(role).interactive === false
4652
);
4753

4854
export function genInteractiveElements () {

__tests__/src/rules/aria-props-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@
88
// Requirements
99
// -----------------------------------------------------------------------------
1010

11+
import { aria } from 'aria-query';
1112
import { RuleTester } from 'eslint';
1213
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
1314
import rule from '../../../src/rules/aria-props';
14-
import ariaAttributes from '../../../src/util/attributes/ARIA.json';
1515
import getSuggestion from '../../../src/util/getSuggestion';
1616

1717
// -----------------------------------------------------------------------------
1818
// Tests
1919
// -----------------------------------------------------------------------------
2020

2121
const ruleTester = new RuleTester();
22+
const ariaAttributes = [...aria.keys()];
2223

2324
const errorMessage = (name) => {
24-
const dictionary = Object.keys(ariaAttributes).map(aria => aria.toLowerCase());
25-
const suggestions = getSuggestion(name, dictionary);
25+
const suggestions = getSuggestion(name, ariaAttributes);
2626
const message = `${name}: This attribute is an invalid ARIA attribute.`;
2727

2828
if (suggestions.length > 0) {
@@ -39,7 +39,7 @@ const errorMessage = (name) => {
3939
};
4040

4141
// Create basic test cases using all valid role types.
42-
const basicValidityTests = Object.keys(ariaAttributes).map(prop => ({
42+
const basicValidityTests = ariaAttributes.map(prop => ({
4343
code: `<div ${prop.toLowerCase()}="foobar" />`,
4444
}));
4545

__tests__/src/rules/aria-proptypes-test.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
// Requirements
99
// -----------------------------------------------------------------------------
1010

11+
import { aria } from 'aria-query';
1112
import { RuleTester } from 'eslint';
12-
import ariaAttributes from '../../../src/util/attributes/ARIA.json';
1313
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
1414
import rule, { validityCheck } from '../../../src/rules/aria-proptypes';
1515

@@ -20,7 +20,10 @@ import rule, { validityCheck } from '../../../src/rules/aria-proptypes';
2020
const ruleTester = new RuleTester();
2121

2222
const errorMessage = (name) => {
23-
const { type, values: permittedValues } = ariaAttributes[name.toUpperCase()];
23+
const {
24+
type,
25+
values: permittedValues,
26+
} = aria.get(name.toLowerCase());
2427

2528
switch (type) {
2629
case 'tristate':

__tests__/src/rules/aria-role-test.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// Requirements
99
// -----------------------------------------------------------------------------
1010

11+
import { roles } from 'aria-query';
1112
import { RuleTester } from 'eslint';
1213
import assign from 'object-assign';
1314
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
1415
import rule from '../../../src/rules/aria-role';
15-
import ROLES from '../../../src/util/attributes/role.json';
1616

1717
// -----------------------------------------------------------------------------
1818
// Tests
@@ -25,10 +25,14 @@ const errorMessage = {
2525
type: 'JSXAttribute',
2626
};
2727

28-
const validRoles = Object.keys(ROLES).filter(role => ROLES[role].abstract === false);
29-
const invalidRoles = Object.keys(ROLES).filter(role => ROLES[role].abstract === true);
28+
const validRoles = [...roles.keys()].filter(
29+
role => roles.get(role).abstract === false,
30+
);
31+
const invalidRoles = [...roles.keys()].filter(
32+
role => roles.get(role).abstract === true,
33+
);
3034

31-
const createTests = roles => roles.map(role => ({
35+
const createTests = roleNames => roleNames.map(role => ({
3236
code: `<div role="${role.toLowerCase()}" />`,
3337
}));
3438

@@ -39,6 +43,10 @@ const invalidTests = createTests(invalidRoles).map((test) => {
3943
return invalidTest;
4044
});
4145

46+
const ignoreNonDOMSchema = [{
47+
ignoreNonDOM: true,
48+
}];
49+
4250
ruleTester.run('aria-role', rule, {
4351
valid: [
4452
// Variables should pass, as we are only testing literals.
@@ -52,6 +60,7 @@ ruleTester.run('aria-role', rule, {
5260
{ code: '<div role="doc-abstract" />' },
5361
{ code: '<div role="doc-appendix doc-bibliography" />' },
5462
{ code: '<Bar baz />' },
63+
{ code: '<Foo role="bar" />', options: ignoreNonDOMSchema },
5564
].concat(validTests).map(parserOptionsMapper),
5665

5766
invalid: [
@@ -64,5 +73,6 @@ ruleTester.run('aria-role', rule, {
6473
{ code: '<div role="doc-endnotes range"></div>', errors: [errorMessage] },
6574
{ code: '<div role />', errors: [errorMessage] },
6675
{ code: '<div role={null}></div>', errors: [errorMessage] },
76+
{ code: '<Foo role="datepicker" />', errors: [errorMessage] },
6777
].concat(invalidTests).map(parserOptionsMapper),
6878
});

__tests__/src/rules/aria-unsupported-elements-test.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
// Requirements
1010
// -----------------------------------------------------------------------------
1111

12+
import { dom } from 'aria-query';
1213
import { RuleTester } from 'eslint';
1314
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
14-
import DOM from '../../../src/util/attributes/DOM.json';
1515
import rule from '../../../src/rules/aria-unsupported-elements';
1616

1717
// -----------------------------------------------------------------------------
@@ -26,18 +26,19 @@ Try removing the prop '${invalidProp}'.`,
2626
type: 'JSXOpeningElement',
2727
});
2828

29+
const domElements = [...dom.keys()];
2930
// Generate valid test cases
30-
const roleValidityTests = Object.keys(DOM).map((element) => {
31-
const isReserved = DOM[element].reserved || false;
31+
const roleValidityTests = domElements.map((element) => {
32+
const isReserved = dom.get(element).reserved || false;
3233
const role = isReserved ? '' : 'role';
3334

3435
return {
3536
code: `<${element} ${role} />`,
3637
};
3738
});
3839

39-
const ariaValidityTests = Object.keys(DOM).map((element) => {
40-
const isReserved = DOM[element].reserved || false;
40+
const ariaValidityTests = domElements.map((element) => {
41+
const isReserved = dom.get(element).reserved || false;
4142
const aria = isReserved ? '' : 'aria-hidden';
4243

4344
return {
@@ -46,15 +47,15 @@ const ariaValidityTests = Object.keys(DOM).map((element) => {
4647
});
4748

4849
// Generate invalid test cases.
49-
const invalidRoleValidityTests = Object.keys(DOM)
50-
.filter(element => Boolean(DOM[element].reserved))
50+
const invalidRoleValidityTests = domElements
51+
.filter(element => Boolean(dom.get(element).reserved))
5152
.map(reservedElem => ({
5253
code: `<${reservedElem} role {...props} />`,
5354
errors: [errorMessage('role')],
5455
}));
5556

56-
const invalidAriaValidityTests = Object.keys(DOM)
57-
.filter(element => Boolean(DOM[element].reserved))
57+
const invalidAriaValidityTests = domElements
58+
.filter(element => Boolean(dom.get(element).reserved))
5859
.map(reservedElem => ({
5960
code: `<${reservedElem} aria-hidden {...props} />`,
6061
errors: [errorMessage('aria-hidden')],

__tests__/src/rules/role-has-required-aria-props-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
// Requirements
1010
// -----------------------------------------------------------------------------
1111

12+
import { roles } from 'aria-query';
1213
import { RuleTester } from 'eslint';
1314
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
14-
import validRoleTypes from '../../../src/util/attributes/role.json';
1515
import rule from '../../../src/rules/role-has-required-aria-props';
1616

1717
// -----------------------------------------------------------------------------
@@ -21,7 +21,7 @@ import rule from '../../../src/rules/role-has-required-aria-props';
2121
const ruleTester = new RuleTester();
2222

2323
const errorMessage = (role) => {
24-
const requiredProps = validRoleTypes[role.toUpperCase()].requiredProps.toString().toLowerCase();
24+
const requiredProps = roles.get(role).requiredProps.toString().toLowerCase();
2525

2626
return {
2727
message: `Elements with the ARIA role "${role}" must have the following ` +
@@ -32,8 +32,8 @@ const errorMessage = (role) => {
3232

3333

3434
// Create basic test cases using all valid role types.
35-
const basicValidityTests = Object.keys(validRoleTypes).map((role) => {
36-
const { requiredProps } = validRoleTypes[role];
35+
const basicValidityTests = [...roles.keys()].map((role) => {
36+
const { requiredProps } = roles.get(role);
3737
const propChain = requiredProps.join(' ').toLowerCase();
3838

3939
return {

__tests__/src/rules/role-supports-aria-props-test.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
// Requirements
99
// -----------------------------------------------------------------------------
1010

11+
import {
12+
aria,
13+
roles,
14+
} from 'aria-query';
1115
import { RuleTester } from 'eslint';
1216
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
1317
import rule from '../../../src/rules/role-supports-aria-props';
14-
import ROLES from '../../../src/util/attributes/role.json';
15-
import ARIA from '../../../src/util/attributes/ARIA.json';
1618

1719
// -----------------------------------------------------------------------------
1820
// Tests
@@ -34,11 +36,12 @@ const errorMessage = (attr, role, tag, isImplicit) => ({
3436
type: 'JSXOpeningElement',
3537
});
3638

37-
const nonAbstractRoles = Object.keys(ROLES).filter(role => ROLES[role].abstract === false);
39+
const nonAbstractRoles = [...roles.keys()].filter(role => roles.get(role).abstract === false);
3840

39-
const createTests = roles => roles.reduce((tests, role) => {
40-
const validPropsForRole = ROLES[role.toUpperCase()].props;
41-
const invalidPropsForRole = Object.keys(ARIA)
41+
const createTests = rolesNames => rolesNames.reduce((tests, role) => {
42+
const validPropsForRole = roles.get(role.toLowerCase()).props;
43+
const invalidPropsForRole = [...aria.keys()]
44+
.map(attribute => attribute.toLowerCase())
4245
.filter(attribute => validPropsForRole.indexOf(attribute) === -1);
4346
const normalRole = role.toLowerCase();
4447

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"lint": "eslint --config .eslintrc src __tests__",
2525
"lint:fix": "npm run lint -- --fix",
2626
"pretest": "npm run lint:fix && npm run flow",
27-
"test": "jest --coverage",
27+
"test": "jest --bail --coverage",
2828
"create": "node ./scripts/create-rule"
2929
},
3030
"devDependencies": {
@@ -54,6 +54,7 @@
5454
},
5555
"license": "MIT",
5656
"dependencies": {
57+
"aria-query": "^0.3.0",
5758
"ast-types-flow": "0.0.7",
5859
"damerau-levenshtein": "^1.0.0",
5960
"emoji-regex": "^6.1.0",

src/rules/aria-activedescendant-has-tabindex.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
* @author Jesse Beach <@jessebeach>
44
*/
55

6+
import { dom } from 'aria-query';
67
import { getProp, elementType } from 'jsx-ast-utils';
78
import { generateObjSchema } from '../util/schemas';
8-
import DOMElements from '../util/attributes/DOM.json';
99
import getTabIndex from '../util/getTabIndex';
1010
import isInteractiveElement from '../util/isInteractiveElement';
1111

@@ -18,7 +18,7 @@ const errorMessage =
1818

1919
const schema = generateObjSchema();
2020

21-
const DOMElementKeys = Object.keys(DOMElements);
21+
const domElements = [...dom.keys()];
2222

2323
module.exports = {
2424
meta: {
@@ -37,7 +37,7 @@ module.exports = {
3737
const type = elementType(node);
3838
// Do not test higher level JSX components, as we do not know what
3939
// low-level DOM element this maps to.
40-
if (DOMElementKeys.indexOf(type) === -1) {
40+
if (domElements.indexOf(type) === -1) {
4141
return;
4242
}
4343
const tabIndex = getTabIndex(getProp(attributes, 'tabIndex'));

src/rules/aria-props.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
// Rule Definition
88
// ----------------------------------------------------------------------------
99

10+
import { aria } from 'aria-query';
1011
import { propName } from 'jsx-ast-utils';
1112
import { generateObjSchema } from '../util/schemas';
12-
import ariaAttributes from '../util/attributes/ARIA.json';
1313
import getSuggestion from '../util/getSuggestion';
1414

15+
const ariaAttributes = [...aria.keys()];
16+
1517
const errorMessage = (name) => {
16-
const dictionary = Object.keys(ariaAttributes).map(aria => aria.toLowerCase());
17-
const suggestions = getSuggestion(name, dictionary);
18+
const suggestions = getSuggestion(name, ariaAttributes);
1819
const message = `${name}: This attribute is an invalid ARIA attribute.`;
1920

2021
if (suggestions.length > 0) {
@@ -35,14 +36,14 @@ module.exports = {
3536
create: context => ({
3637
JSXAttribute: (attribute) => {
3738
const name = propName(attribute);
38-
const normalizedName = name ? name.toUpperCase() : '';
39+
const normalizedName = name ? name.toLowerCase() : '';
3940

4041
// `aria` needs to be prefix of property.
41-
if (normalizedName.indexOf('ARIA-') !== 0) {
42+
if (normalizedName.indexOf('aria-') !== 0) {
4243
return;
4344
}
4445

45-
const isValid = Object.keys(ariaAttributes).indexOf(normalizedName) > -1;
46+
const isValid = ariaAttributes.indexOf(normalizedName) > -1;
4647

4748
if (isValid === false) {
4849
context.report({

0 commit comments

Comments
 (0)