Skip to content

Commit

Permalink
build: update to eslint v9
Browse files Browse the repository at this point in the history
This change adds support for eslint v9.  All three example projects have been updated to use the latest eslint, and the root package's dev and peer deps have been updated.
In order to make this work with both v9 and older versions, I had to update the parser options helper to adjust the config passed into the `RuleTester`.
It was also necessary update jest to a newer version, in order to resolve eslint's use of `node:fs/promises`.
Note: the removed test cases are exact duplicates of other tests.  v9 fails tests when its determined to be an exact duplicate.
  • Loading branch information
michaelfaith committed Sep 1, 2024
1 parent 05a5e49 commit 903bca2
Show file tree
Hide file tree
Showing 21 changed files with 184 additions and 88 deletions.
1 change: 1 addition & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
<PROJECT_ROOT>/lib/.*
<PROJECT_ROOT>/docs/.*
<PROJECT_ROOT>/reports/.*
<PROJECT_ROOT>/examples/.*
[options]
suppress_type=$FlowFixMe
29 changes: 28 additions & 1 deletion .github/workflows/node-4+.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,40 @@ jobs:
matrix:
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
eslint:
- 9
- 8
- 7
- 6
- 5
- 4
- 3
exclude:
- node-version: 16
eslint: 9
- node-version: 15
eslint: 9
- node-version: 14
eslint: 9
- node-version: 13
eslint: 9
- node-version: 12
eslint: 9
- node-version: 11
eslint: 9
- node-version: 10
eslint: 9
- node-version: 9
eslint: 9
- node-version: 8
eslint: 9
- node-version: 7
eslint: 9
- node-version: 6
eslint: 9
- node-version: 5
eslint: 9
- node-version: 4
eslint: 9
- node-version: 15
eslint: 8
- node-version: 13
Expand Down Expand Up @@ -90,7 +117,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-depth: 0
- uses: ljharb/actions/node/install@main
name: 'nvm install ${{ matrix.node-version }} && npm install'
env:
Expand Down
3 changes: 3 additions & 0 deletions __tests__/__util__/nodeReexports/assert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import assert from 'assert';

export default assert;
3 changes: 3 additions & 0 deletions __tests__/__util__/nodeReexports/fs-promises.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import fs from 'fs/promises';

export default fs;
3 changes: 3 additions & 0 deletions __tests__/__util__/nodeReexports/fs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import fs from 'fs';

export default fs;
3 changes: 3 additions & 0 deletions __tests__/__util__/nodeReexports/path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import path from 'path';

export default path;
3 changes: 3 additions & 0 deletions __tests__/__util__/nodeReexports/url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import url from 'url';

export default url;
3 changes: 3 additions & 0 deletions __tests__/__util__/nodeReexports/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import util from 'util';

export default util;
53 changes: 40 additions & 13 deletions __tests__/__util__/parserOptionsMapper.js
Original file line number Diff line number Diff line change
@@ -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,
};
}
31 changes: 3 additions & 28 deletions __tests__/src/rules/anchor-is-valid-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,9 @@ 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: parsers.all([].concat(
// DEFAULT ELEMENT 'a' TESTS
Expand Down Expand Up @@ -372,7 +367,7 @@ 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 },
Expand Down Expand Up @@ -522,27 +517,7 @@ ruleTester.run('anchor-is-valid', rule, {
errors: [invalidHrefexpectedError],
},

// CUSTOM COMPONENTS AND SPECIALLINK AND ASPECT
{
code: '<Anchor hrefLeft={undefined} />',
options: componentsAndSpecialLinkAndNoHrefAspect,
errors: [noHrefexpectedError],
},
{
code: '<Anchor hrefLeft={null} />',
options: componentsAndSpecialLinkAndNoHrefAspect,
errors: [noHrefexpectedError],
},
{
code: '<Anchor hrefLeft={undefined} />',
options: componentsAndSpecialLinkAndNoHrefAspect,
errors: [noHrefexpectedError],
},
{
code: '<Anchor hrefLeft={null} />',
options: componentsAndSpecialLinkAndNoHrefAspect,
errors: [noHrefexpectedError],
},
// CUSTOM COMPONENTS AND SPECIAL LINK AND ASPECT
{
code: '<Anchor hrefLeft={undefined} />',
options: componentsAndSpecialLinkAndNoHrefAspect,
Expand Down
4 changes: 2 additions & 2 deletions __tests__/src/rules/img-redundant-alt-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ 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" />;' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ const neverValid = [
{ 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] },
Expand All @@ -345,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] },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,6 @@ const neverValid = [
* interactive role. */
{ code: '<main role="button" />;', errors: [expectedError] },
{ code: '<article 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] },
Expand Down Expand Up @@ -412,7 +411,6 @@ 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] },
Expand Down
1 change: 0 additions & 1 deletion __tests__/src/rules/no-static-element-interactions-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,6 @@ const neverValid = [
{ 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: '<frameset onClick={() => {}} />;', errors: [expectedError] },
Expand Down
6 changes: 1 addition & 5 deletions __tests__/src/rules/prefer-tag-over-role-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const expectedError = (role, tag) => ({
type: 'JSXOpeningElement',
});

ruleTester.run('element-role', rule, {
ruleTester.run('prefer-tag-over-role', rule, {
valid: parsers.all([].concat(
{ code: '<div />;' },
{ code: '<div role="unknown" />;' },
Expand Down Expand Up @@ -55,10 +55,6 @@ 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>')],
Expand Down
88 changes: 65 additions & 23 deletions __tests__/src/util/parserOptionsMapper-test.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,88 @@
import { version as eslintVersion } from 'eslint/package.json';
import expect from 'expect';
import semver from 'semver';
import parserOptionsMapper from '../../__util__/parserOptionsMapper';

const usingLegacy = semver.major(eslintVersion) < 9;

describe('parserOptionsMapper', () => {
it('should return an test case object', () => {
const testCase = {
code: '<div />',
errors: [],
options: {},
};
expect(parserOptionsMapper(testCase)).toEqual({
code: '<div />',
errors: [],
options: {},
parserOptions: {
ecmaVersion: 2018,
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,

const expectedResult = usingLegacy
? {
code: '<div />',
errors: [],
options: {},
parserOptions: {
ecmaVersion: 2018,
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
},
},
});
settings: {},
}
: {
code: '<div />',
errors: [],
options: {},
languageOptions: {
ecmaVersion: 'latest',
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
},
},
settings: {},
};
expect(parserOptionsMapper(testCase)).toEqual(expectedResult);
});
it('should allow for overriding parserOptions', () => {
const testCase = {
code: '<div />',
errors: [],
options: {},
parserOptions: {
languageOptions: {
ecmaVersion: 5,
},
};
expect(parserOptionsMapper(testCase)).toEqual({
code: '<div />',
errors: [],
options: {},
parserOptions: {
ecmaVersion: 5,
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,

const expectedResult = usingLegacy
? {
code: '<div />',
errors: [],
options: {},
parserOptions: {
ecmaVersion: 5,
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
},
},
});
settings: {},
}
: {
code: '<div />',
errors: [],
options: {},
languageOptions: {
ecmaVersion: 5,
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
},
},
settings: {},
};
expect(parserOptionsMapper(testCase)).toEqual(expectedResult);
});
});
4 changes: 2 additions & 2 deletions examples/flat-cjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"react-dom": "^18.2.0"
},
"devDependencies": {
"@eslint/js": "^9.5.0",
"@eslint/js": "^9.9.1",
"cross-env": "^7.0.3",
"eslint": "^8.57.0",
"eslint": "^9.9.1",
"eslint-plugin-jsx-a11y": "file:../..",
"globals": "^15.6.0"
}
Expand Down
Loading

0 comments on commit 903bca2

Please sign in to comment.