diff --git a/__tests__/__util__/helpers/getESLintCoreRule.js b/__tests__/__util__/helpers/getESLintCoreRule.js
new file mode 100644
index 000000000..ee04494f0
--- /dev/null
+++ b/__tests__/__util__/helpers/getESLintCoreRule.js
@@ -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;
diff --git a/__tests__/__util__/helpers/parsers.js b/__tests__/__util__/helpers/parsers.js
new file mode 100644
index 000000000..fc75cf337
--- /dev/null
+++ b/__tests__/__util__/helpers/parsers.js
@@ -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;
diff --git a/__tests__/src/rules/accessible-emoji-test.js b/__tests__/src/rules/accessible-emoji-test.js
index dc3d19683..a1d21f461 100644
--- a/__tests__/src/rules/accessible-emoji-test.js
+++ b/__tests__/src/rules/accessible-emoji-test.js
@@ -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: '
;' },
{ code: ' ' },
{ code: 'No emoji here! ' },
@@ -42,8 +43,8 @@ ruleTester.run('accessible-emoji', rule, {
code: '๐ผ ',
settings: { 'jsx-a11y': { components: { CustomInput: 'input' } } },
},
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: '๐ผ ', errors: [expectedError] },
{ code: 'foo๐ผbar ', errors: [expectedError] },
{ code: 'foo ๐ผ bar ', errors: [expectedError] },
@@ -52,5 +53,5 @@ ruleTester.run('accessible-emoji', rule, {
{ code: '๐ผ ', errors: [expectedError] },
{ code: '๐ผ ', errors: [expectedError] },
{ code: '๐ผ ', errors: [expectedError] },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/alt-text-test.js b/__tests__/src/rules/alt-text-test.js
index bd2463d73..07b2c8259 100644
--- a/__tests__/src/rules/alt-text-test.js
+++ b/__tests__/src/rules/alt-text-test.js
@@ -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,19 +29,29 @@ 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 elements must have alternative text by providing inner text, aria-label or aria-labelledby props.';
+const objectError = {
+ message: 'Embedded 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 = ' elements with type="image" must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.';
+const inputImageError = {
+ message: ' elements with type="image" must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.',
+};
const componentsSettings = {
'jsx-a11y': {
@@ -58,7 +69,7 @@ const array = [{
}];
ruleTester.run('alt-text', rule, {
- valid: [
+ valid: parsers.all([].concat(
// DEFAULT ELEMENT 'img' TESTS
{ code: ' ;' },
{ code: ' ;' },
@@ -166,8 +177,8 @@ ruleTester.run('alt-text', rule, {
{ code: ' ', options: array },
{ code: ' ', options: array },
{ code: ' ', options: array },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
// DEFAULT ELEMENT 'img' TESTS
{ code: ' ;', errors: [missingPropError('img')] },
{ code: ' ;', errors: [altValueError('img')] },
@@ -273,5 +284,5 @@ ruleTester.run('alt-text', rule, {
{ code: 'Foo ', errors: [inputImageError], options: array },
{ code: ' ', errors: [inputImageError], options: array },
{ code: ' ', errors: [inputImageError], settings: componentsSettings },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/anchor-ambiguous-text-test.js b/__tests__/src/rules/anchor-ambiguous-text-test.js
index da57274cd..cbbc39501 100644
--- a/__tests__/src/rules/anchor-ambiguous-text-test.js
+++ b/__tests__/src/rules/anchor-ambiguous-text-test.js
@@ -10,6 +10,7 @@
import { RuleTester } from 'eslint';
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
+import parsers from '../../__util__/helpers/parsers';
import rule from '../../../src/rules/anchor-ambiguous-text';
// -----------------------------------------------------------------------------
@@ -34,7 +35,7 @@ const expectedErrorGenerator = (words) => ({
const expectedError = expectedErrorGenerator(DEFAULT_AMBIGUOUS_WORDS);
ruleTester.run('anchor-ambiguous-text', rule, {
- valid: [
+ valid: parsers.all([].concat(
{ code: 'documentation ;' },
{ code: '${here} ;' },
{ code: 'click here ;' },
@@ -69,8 +70,8 @@ ruleTester.run('anchor-ambiguous-text', rule, {
}],
settings: { 'jsx-a11y': { components: { Link: 'a' } } },
},
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: 'here ;', errors: [expectedError] },
{ code: 'HERE ;', errors: [expectedError] },
{ code: 'click here ;', errors: [expectedError] },
@@ -113,5 +114,5 @@ ruleTester.run('anchor-ambiguous-text', rule, {
words: ['a disallowed word'],
}],
},
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/anchor-has-content-test.js b/__tests__/src/rules/anchor-has-content-test.js
index eb47e8e55..c55dbb9fb 100644
--- a/__tests__/src/rules/anchor-has-content-test.js
+++ b/__tests__/src/rules/anchor-has-content-test.js
@@ -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: '
;' },
{ code: 'Foo ' },
{ code: ' ' },
@@ -39,8 +40,8 @@ ruleTester.run('anchor-has-content', rule, {
{ code: ' ' },
{ code: ' ' },
{ code: ' ' },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: ' ', errors: [expectedError] },
{ code: ' ', errors: [expectedError] },
{ code: '{undefined} ', errors: [expectedError] },
@@ -49,5 +50,5 @@ ruleTester.run('anchor-has-content', rule, {
errors: [expectedError],
settings: { 'jsx-a11y': { components: { Link: 'a' } } },
},
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/anchor-is-valid-test.js b/__tests__/src/rules/anchor-is-valid-test.js
index 5b368d9e7..9fb4025e9 100644
--- a/__tests__/src/rules/anchor-is-valid-test.js
+++ b/__tests__/src/rules/anchor-is-valid-test.js
@@ -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: ' ' },
{ code: ' ' },
@@ -279,8 +280,8 @@ ruleTester.run('anchor-is-valid', rule, {
{ code: ' ', options: componentsAndSpecialLinkAndInvalidHrefAspect },
{ code: ' ', options: componentsAndSpecialLinkAndInvalidHrefAspect },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
// DEFAULT ELEMENT 'a' TESTS
// NO HREF
{ code: ' ', errors: [noHrefexpectedError] },
@@ -288,8 +289,8 @@ ruleTester.run('anchor-is-valid', rule, {
{ code: ' ', errors: [noHrefexpectedError] },
// INVALID HREF
{ code: ' ;', errors: [invalidHrefexpectedError] },
- { code: ' ', errors: [invalidHrefErrorMessage] },
- { code: ' ', errors: [invalidHrefErrorMessage] },
+ { code: ' ', errors: [invalidHrefexpectedError] },
+ { code: ' ', errors: [invalidHrefexpectedError] },
{ code: ' ', errors: [invalidHrefexpectedError] },
{ code: ' ', errors: [invalidHrefexpectedError] },
// SHOULD BE BUTTON
@@ -308,13 +309,13 @@ ruleTester.run('anchor-is-valid', rule, {
{ code: ' ', errors: [noHrefexpectedError], options: components },
// INVALID HREF
{ code: ' ', errors: [invalidHrefexpectedError], options: components },
- { code: ' ', errors: [invalidHrefErrorMessage], options: components },
- { code: ' ', errors: [invalidHrefErrorMessage], options: components },
+ { code: ' ', errors: [invalidHrefexpectedError], options: components },
+ { code: ' ', errors: [invalidHrefexpectedError], options: components },
{ code: ' ', errors: [invalidHrefexpectedError], options: components },
{ code: ' ', errors: [invalidHrefexpectedError], options: components },
{ code: ' ', errors: [invalidHrefexpectedError], options: components },
- { code: ' ', errors: [invalidHrefErrorMessage], options: components },
- { code: ' ', errors: [invalidHrefErrorMessage], options: components },
+ { code: ' ', errors: [invalidHrefexpectedError], options: components },
+ { code: ' ', errors: [invalidHrefexpectedError], options: components },
{ code: ' ', errors: [invalidHrefexpectedError], options: components },
{ code: ' ', errors: [invalidHrefexpectedError], options: components },
// SHOULD BE BUTTON
@@ -354,8 +355,8 @@ ruleTester.run('anchor-is-valid', rule, {
{ code: ' ', errors: [noHrefexpectedError], options: specialLink },
// INVALID HREF
{ code: ' ;', errors: [invalidHrefexpectedError], options: specialLink },
- { code: ' ', errors: [invalidHrefErrorMessage], options: specialLink },
- { code: ' ', errors: [invalidHrefErrorMessage], options: specialLink },
+ { code: ' ', errors: [invalidHrefexpectedError], options: specialLink },
+ { code: ' ', errors: [invalidHrefexpectedError], options: specialLink },
{ code: ' ', errors: [invalidHrefexpectedError], options: specialLink },
{ code: ' ', errors: [invalidHrefexpectedError], options: specialLink },
// SHOULD BE BUTTON
@@ -377,8 +378,8 @@ ruleTester.run('anchor-is-valid', rule, {
{ code: ' ', errors: [noHrefexpectedError], options: componentsAndSpecialLink },
// INVALID HREF
{ code: ' ;', errors: [invalidHrefexpectedError], options: componentsAndSpecialLink },
- { code: ' ', errors: [invalidHrefErrorMessage], options: componentsAndSpecialLink },
- { code: ' ', errors: [invalidHrefErrorMessage], options: componentsAndSpecialLink },
+ { code: ' ', errors: [invalidHrefexpectedError], options: componentsAndSpecialLink },
+ { code: ' ', errors: [invalidHrefexpectedError], options: componentsAndSpecialLink },
{
code: ' ',
errors: [invalidHrefexpectedError],
@@ -408,149 +409,149 @@ ruleTester.run('anchor-is-valid', rule, {
// WITH ASPECTS TESTS
// NO HREF
- { code: ' ', options: noHrefAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefPreferButtonAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefPreferButtonAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefPreferButtonAspect, errors: [noHrefErrorMessage] },
- { code: ' ', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
+ { code: ' ', options: noHrefAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefPreferButtonAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefPreferButtonAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefPreferButtonAspect, errors: [noHrefexpectedError] },
+ { code: ' ', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
// INVALID HREF
- { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
+ { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: preferButtonInvalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
{
code: ' ;',
options: preferButtonInvalidHrefAspect,
- errors: [invalidHrefErrorMessage],
+ errors: [invalidHrefexpectedError],
},
- { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
- { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefErrorMessage] },
+ { code: ' ;', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
+ { code: ' ;', options: noHrefInvalidHrefAspect, errors: [invalidHrefexpectedError] },
{
code: ' ;',
options: preferButtonInvalidHrefAspect,
- errors: [invalidHrefErrorMessage],
+ errors: [invalidHrefexpectedError],
},
// SHOULD BE BUTTON
- { code: ' void 0} />', options: preferButtonAspect, errors: [preferButtonErrorMessage] },
+ { code: ' void 0} />', options: preferButtonAspect, errors: [preferButtonexpectedError] },
{
code: ' void 0} />',
options: preferButtonInvalidHrefAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
- { code: ' void 0} />', options: noHrefPreferButtonAspect, errors: [preferButtonErrorMessage] },
- { code: ' void 0} />', options: noHrefAspect, errors: [noHrefErrorMessage] },
- { code: ' void 0} />', options: noHrefInvalidHrefAspect, errors: [noHrefErrorMessage] },
- { code: ' void 0} />', options: preferButtonAspect, errors: [preferButtonErrorMessage] },
+ { code: ' void 0} />', options: noHrefPreferButtonAspect, errors: [preferButtonexpectedError] },
+ { code: ' void 0} />', options: noHrefAspect, errors: [noHrefexpectedError] },
+ { code: ' void 0} />', options: noHrefInvalidHrefAspect, errors: [noHrefexpectedError] },
+ { code: ' void 0} />', options: preferButtonAspect, errors: [preferButtonexpectedError] },
{
code: ' void 0} />',
options: noHrefPreferButtonAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
{
code: ' void 0} />',
options: preferButtonInvalidHrefAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
- { code: ' void 0} />', options: invalidHrefAspect, errors: [invalidHrefErrorMessage] },
+ { code: ' void 0} />', options: invalidHrefAspect, errors: [invalidHrefexpectedError] },
{
code: ' void 0} />',
options: noHrefInvalidHrefAspect,
- errors: [invalidHrefErrorMessage],
+ errors: [invalidHrefexpectedError],
},
{
code: ' void 0} />',
options: preferButtonAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
{
code: ' void 0} />',
options: noHrefPreferButtonAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
{
code: ' void 0} />',
options: preferButtonInvalidHrefAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
{
code: ' void 0} />',
options: invalidHrefAspect,
- errors: [invalidHrefErrorMessage],
+ errors: [invalidHrefexpectedError],
},
{
code: ' void 0} />',
options: noHrefInvalidHrefAspect,
- errors: [invalidHrefErrorMessage],
+ errors: [invalidHrefexpectedError],
},
{
code: ' void 0} />',
options: preferButtonAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
{
code: ' void 0} />',
options: noHrefPreferButtonAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
{
code: ' void 0} />',
options: preferButtonInvalidHrefAspect,
- errors: [preferButtonErrorMessage],
+ errors: [preferButtonexpectedError],
},
{
code: ' void 0} />',
options: invalidHrefAspect,
- errors: [invalidHrefErrorMessage],
+ errors: [invalidHrefexpectedError],
},
{
code: ' void 0} />',
options: noHrefInvalidHrefAspect,
- errors: [invalidHrefErrorMessage],
+ errors: [invalidHrefexpectedError],
},
// CUSTOM COMPONENTS AND SPECIALLINK AND ASPECT
{
code: ' ',
options: componentsAndSpecialLinkAndNoHrefAspect,
- errors: [noHrefErrorMessage],
+ errors: [noHrefexpectedError],
},
{
code: ' ',
options: componentsAndSpecialLinkAndNoHrefAspect,
- errors: [noHrefErrorMessage],
+ errors: [noHrefexpectedError],
},
{
code: ' ',
options: componentsAndSpecialLinkAndNoHrefAspect,
- errors: [noHrefErrorMessage],
+ errors: [noHrefexpectedError],
},
{
code: ' ',
options: componentsAndSpecialLinkAndNoHrefAspect,
- errors: [noHrefErrorMessage],
+ errors: [noHrefexpectedError],
},
{
code: ' ',
options: componentsAndSpecialLinkAndNoHrefAspect,
- errors: [noHrefErrorMessage],
+ errors: [noHrefexpectedError],
},
{
code: ' ',
options: componentsAndSpecialLinkAndNoHrefAspect,
- errors: [noHrefErrorMessage],
+ errors: [noHrefexpectedError],
},
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js b/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js
index 6c251cf23..5310ac9ac 100644
--- a/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js
+++ b/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js
@@ -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: ' ;',
},
@@ -79,8 +80,8 @@ ruleTester.run('aria-activedescendant-has-tabindex', rule, {
{
code: ' ;',
},
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{
code: '
;',
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),
});
diff --git a/__tests__/src/rules/aria-props-test.js b/__tests__/src/rules/aria-props-test.js
index 89aa9864d..1236fa7c7 100644
--- a/__tests__/src/rules/aria-props-test.js
+++ b/__tests__/src/rules/aria-props-test.js
@@ -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';
@@ -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: '
' },
{ code: '
' },
@@ -53,8 +54,8 @@ ruleTester.run('aria-props', rule, {
{ code: '
' },
{ code: ' ' },
{ code: ' ' },
- ].concat(basicValidityTests).map(parserOptionsMapper),
- invalid: [
+ )).concat(basicValidityTests).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: '
', errors: [errorMessage('aria-')] },
{
code: '
',
@@ -64,5 +65,5 @@ ruleTester.run('aria-props', rule, {
code: '
',
errors: [errorMessage('aria-skldjfaria-klajsd')],
},
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/aria-proptypes-test.js b/__tests__/src/rules/aria-proptypes-test.js
index f9ff1c8f7..67be3304a 100644
--- a/__tests__/src/rules/aria-proptypes-test.js
+++ b/__tests__/src/rules/aria-proptypes-test.js
@@ -11,6 +11,7 @@ import { aria } from 'aria-query';
import { RuleTester } from 'eslint';
import expect from 'expect';
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
+import parsers from '../../__util__/helpers/parsers';
import rule from '../../../src/rules/aria-proptypes';
const { validityCheck } = rule;
@@ -29,22 +30,24 @@ 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}.` };
}
};
@@ -58,7 +61,7 @@ describe('validityCheck', () => {
});
ruleTester.run('aria-proptypes', rule, {
- valid: [
+ valid: parsers.all([].concat(
// DON'T TEST INVALID ARIA-* PROPS
{ code: '
' },
{ code: '
' },
@@ -211,8 +214,8 @@ ruleTester.run('aria-proptypes', rule, {
{ code: '
' },
{ code: '
' },
{ code: '
' },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
// BOOLEAN
{ code: '
', errors: [errorMessage('aria-hidden')] },
{ code: '
', errors: [errorMessage('aria-hidden')] },
@@ -302,5 +305,5 @@ ruleTester.run('aria-proptypes', rule, {
code: '
',
errors: [errorMessage('aria-relevant')],
},
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/aria-role-test.js b/__tests__/src/rules/aria-role-test.js
index cf1ffccf9..410749666 100644
--- a/__tests__/src/rules/aria-role-test.js
+++ b/__tests__/src/rules/aria-role-test.js
@@ -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';
// -----------------------------------------------------------------------------
@@ -56,7 +57,7 @@ const customDivSettings = {
};
ruleTester.run('aria-role', rule, {
- valid: [
+ valid: parsers.all([].concat(
// Variables should pass, as we are only testing literals.
{ code: '
' },
{ code: '
' },
@@ -81,9 +82,9 @@ ruleTester.run('aria-role', rule, {
{
code: ' ',
},
- ].concat(validTests).map(parserOptionsMapper),
+ )).concat(validTests).map(parserOptionsMapper),
- invalid: [
+ invalid: parsers.all([].concat(
{ code: '
', errors: [errorMessage] },
{ code: '
', errors: [errorMessage] },
{ code: '
', errors: [errorMessage] },
@@ -104,5 +105,5 @@ ruleTester.run('aria-role', rule, {
options: ignoreNonDOMSchema,
settings: customDivSettings,
},
- ].concat(invalidTests).map(parserOptionsMapper),
+ )).concat(invalidTests).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/aria-unsupported-elements-test.js b/__tests__/src/rules/aria-unsupported-elements-test.js
index 1e1b94212..31b348841 100644
--- a/__tests__/src/rules/aria-unsupported-elements-test.js
+++ b/__tests__/src/rules/aria-unsupported-elements-test.js
@@ -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';
// -----------------------------------------------------------------------------
@@ -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.concat(ariaValidityTests))).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(invalidRoleValidityTests.concat(invalidAriaValidityTests)))
.map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/autocomplete-valid-test.js b/__tests__/src/rules/autocomplete-valid-test.js
index 49f194067..57b1257c0 100644
--- a/__tests__/src/rules/autocomplete-valid-test.js
+++ b/__tests__/src/rules/autocomplete-valid-test.js
@@ -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: ' ;' },
// // PASSED AUTOCOMPLETE
@@ -63,8 +64,8 @@ ruleTester.run('autocomplete-valid', rule, {
{ code: ' ;', errors: inappropriateAutocomplete },
{ code: ' ;', errors: inappropriateAutocomplete },
{ code: ' ;', errors: inappropriateAutocomplete, options: [{ inputComponents: ['Foo'] }] },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
// FAILED "autocomplete-valid"
{ code: ' ;', errors: invalidAutocomplete },
{ code: ' ;', errors: invalidAutocomplete },
@@ -72,5 +73,5 @@ ruleTester.run('autocomplete-valid', rule, {
{ code: ' ;', errors: invalidAutocomplete },
{ code: ' ;', errors: invalidAutocomplete, options: [{ inputComponents: ['Bar'] }] },
{ code: ' ', errors: invalidAutocomplete, settings: componentsSettings },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/click-events-have-key-events-test.js b/__tests__/src/rules/click-events-have-key-events-test.js
index 5460504f6..683a71b7b 100644
--- a/__tests__/src/rules/click-events-have-key-events-test.js
+++ b/__tests__/src/rules/click-events-have-key-events-test.js
@@ -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: ' void 0} onKeyDown={foo}/>;' },
{ code: '
void 0} onKeyUp={foo} />;' },
{ code: '
void 0} onKeyPress={foo}/>;' },
@@ -52,8 +53,8 @@ ruleTester.run('click-events-have-key-events', rule, {
{ code: '
' },
{ code: '
' },
{ code: '
' },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: '
void 0} />;', errors: [expectedError] },
{
code: '
void 0} role={undefined} />;',
@@ -72,5 +73,5 @@ ruleTester.run('click-events-have-key-events', rule, {
{ code: '
void 0} />', errors: [expectedError] },
{ code: ' void 0} />', errors: [expectedError] },
{ code: '', errors: [expectedError], settings: { 'jsx-a11y': { components: { Footer: 'footer' } } } },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/control-has-associated-label-test.js b/__tests__/src/rules/control-has-associated-label-test.js
index fd2950830..73bf2be6e 100644
--- a/__tests__/src/rules/control-has-associated-label-test.js
+++ b/__tests__/src/rules/control-has-associated-label-test.js
@@ -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';
@@ -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: ' ' },
{ code: ' ' },
- ]
+ ))
.map(parserOptionsMapper),
- invalid: [
+ invalid: parsers.all([].concat(
{ code: ' ', errors: [expectedError] },
- ]
+ ))
.map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/heading-has-content-test.js b/__tests__/src/rules/heading-has-content-test.js
index a2a201be0..f9955440e 100644
--- a/__tests__/src/rules/heading-has-content-test.js
+++ b/__tests__/src/rules/heading-has-content-test.js
@@ -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: '
;' },
{ code: 'Foo ' },
@@ -64,8 +65,8 @@ ruleTester.run('heading-has-content', rule, {
// CUSTOM ELEMENT TESTS FOR COMPONENTS SETTINGS
{ code: 'Foo ', settings: componentsSettings },
{ code: ' ' },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
// DEFAULT ELEMENT TESTS
{ code: ' ', errors: [expectedError] },
{ code: ' ', errors: [expectedError] },
@@ -80,5 +81,5 @@ ruleTester.run('heading-has-content', rule, {
// CUSTOM ELEMENT TESTS FOR COMPONENTS SETTINGS
{ code: ' ', errors: [expectedError], settings: componentsSettings },
{ code: ' ', errors: [expectedError], settings: componentsSettings },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/html-has-lang-test.js b/__tests__/src/rules/html-has-lang-test.js
index ba9e58d0a..4af612b9c 100644
--- a/__tests__/src/rules/html-has-lang-test.js
+++ b/__tests__/src/rules/html-has-lang-test.js
@@ -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: '
;' },
{ code: ' ' },
{ code: '
' },
@@ -31,11 +32,11 @@ ruleTester.run('html-has-lang', rule, {
{ code: '
' },
{ code: '
' },
{ code: '
', errors: [expectedError], settings: { 'jsx-a11y': { components: { HTMLTop: 'html' } } } },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: '
', errors: [expectedError] },
{ code: '
', errors: [expectedError] },
{ code: ' ', errors: [expectedError] },
{ code: ' ', errors: [expectedError], settings: { 'jsx-a11y': { components: { HTMLTop: 'html' } } } },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/iframe-has-title-test.js b/__tests__/src/rules/iframe-has-title-test.js
index 716be75e0..0bf60311f 100644
--- a/__tests__/src/rules/iframe-has-title-test.js
+++ b/__tests__/src/rules/iframe-has-title-test.js
@@ -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: '
;' },
{ code: '' },
{ code: '' },
{ code: ' ' },
{ code: ' ', settings: componentsSettings },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: '', errors: [expectedError] },
{ code: '', errors: [expectedError] },
{ code: '', errors: [expectedError] },
@@ -50,5 +51,5 @@ ruleTester.run('html-has-lang', rule, {
{ code: '', errors: [expectedError] },
{ code: '', errors: [expectedError] },
{ code: ' ', errors: [expectedError], settings: componentsSettings },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/img-redundant-alt-test.js b/__tests__/src/rules/img-redundant-alt-test.js
index 868577a07..ccacb210c 100644
--- a/__tests__/src/rules/img-redundant-alt-test.js
+++ b/__tests__/src/rules/img-redundant-alt-test.js
@@ -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: ' ;' },
{ code: ' ' },
{ code: ' ' },
@@ -73,8 +74,8 @@ ruleTester.run('img-redundant-alt', rule, {
{ code: ' ;' },
{ code: ' ' },
{ code: ' ', settings: componentsSettings },
- ).map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: ' ;', errors: [expectedError] },
{ code: ' ;', errors: [expectedError] },
{ code: ' ;', errors: [expectedError] },
@@ -128,5 +129,5 @@ ruleTester.run('img-redundant-alt', rule, {
{ code: ' ;', options: array, errors: [expectedError] },
{ code: ' ;', options: array, errors: [expectedError] },
{ code: ' ;', options: array, errors: [expectedError] },
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/interactive-supports-focus-test.js b/__tests__/src/rules/interactive-supports-focus-test.js
index 19bac9f57..3220942ac 100644
--- a/__tests__/src/rules/interactive-supports-focus-test.js
+++ b/__tests__/src/rules/interactive-supports-focus-test.js
@@ -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),
});
diff --git a/__tests__/src/rules/label-has-associated-control-test.js b/__tests__/src/rules/label-has-associated-control-test.js
index 9d1ee028f..d0b4c3b31 100644
--- a/__tests__/src/rules/label-has-associated-control-test.js
+++ b/__tests__/src/rules/label-has-associated-control-test.js
@@ -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';
@@ -149,18 +150,18 @@ const neverValid = [
];
// 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 +170,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 +190,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),
});
diff --git a/__tests__/src/rules/label-has-for-test.js b/__tests__/src/rules/label-has-for-test.js
index 9fffa6093..9b4bd1478 100644
--- a/__tests__/src/rules/label-has-for-test.js
+++ b/__tests__/src/rules/label-has-for-test.js
@@ -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';
// -----------------------------------------------------------------------------
@@ -50,7 +51,7 @@ const optionsChildrenAllowed = [{
}];
ruleTester.run('label-has-for', rule, {
- valid: [
+ valid: parsers.all([].concat(
// DEFAULT ELEMENT 'label' TESTS
{ code: '
' },
{ code: ' ' },
@@ -90,8 +91,8 @@ ruleTester.run('label-has-for', rule, {
{ code: '{children} ', options: optionsChildrenAllowed },
{ code: '{ labelText }
', options: optionsRequiredEvery },
{ code: '{ labelText } ', options: optionsRequiredEvery },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
// DEFAULT ELEMENT 'label' TESTS
{ code: ' ', errors: [expectedEveryError], options: optionsRequiredEvery },
{ code: ' ', errors: [expectedEveryError], options: optionsRequiredEvery },
@@ -218,5 +219,5 @@ ruleTester.run('label-has-for', rule, {
errors: [expectedEveryError],
options: optionsRequiredEvery,
},
- ].map(parserOptionsMapper),
+ )).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/lang-test.js b/__tests__/src/rules/lang-test.js
index ef785a8b3..eaab8da44 100644
--- a/__tests__/src/rules/lang-test.js
+++ b/__tests__/src/rules/lang-test.js
@@ -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';
// -----------------------------------------------------------------------------
@@ -31,7 +32,7 @@ const componentsSettings = {
};
ruleTester.run('lang', rule, {
- valid: [
+ valid: parsers.all([].concat(
{ code: '
;' },
{ code: '
;' },
{ code: '
;' },
@@ -45,11 +46,11 @@ ruleTester.run('lang', rule, {
{ code: ' ' },
{ code: ' ' },
{ code: ' ', settings: componentsSettings },
- ].map(parserOptionsMapper),
- invalid: [
+ )).map(parserOptionsMapper),
+ invalid: parsers.all([].concat(
{ code: ' ', errors: [expectedError] },
{ code: '