Skip to content

Commit aa25003

Browse files
committed
build: update to eslint v9
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.
1 parent a08fbcc commit aa25003

13 files changed

+137
-92
lines changed

.flowconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
<PROJECT_ROOT>/lib/.*
44
<PROJECT_ROOT>/docs/.*
55
<PROJECT_ROOT>/reports/.*
6+
<PROJECT_ROOT>/examples/.*
67
[options]
78
suppress_type=$FlowFixMe

.github/workflows/node-4+.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,26 @@ jobs:
2525
matrix:
2626
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
2727
eslint:
28+
- 9
2829
- 8
2930
- 7
3031
- 6
3132
- 5
3233
- 4
3334
- 3
3435
exclude:
36+
- node-version: 16
37+
eslint: 9
38+
- node-version: 15
39+
eslint: 9
40+
- node-version: 13
41+
eslint: 9
42+
- node-version: 11
43+
eslint: 9
44+
- node-version: 10
45+
eslint: 9
46+
- node-version: 9
47+
eslint: 9
3548
- node-version: 15
3649
eslint: 8
3750
- node-version: 13
@@ -90,7 +103,7 @@ jobs:
90103
steps:
91104
- uses: actions/checkout@v4
92105
with:
93-
fetch-depth: 0
106+
fetch-depth: 0
94107
- uses: ljharb/actions/node/install@main
95108
name: 'nvm install ${{ matrix.node-version }} && npm install'
96109
env:
Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,53 @@
1+
import { version as eslintVersion } from 'eslint/package.json';
2+
import semver from 'semver';
3+
4+
const usingLegacy = semver.major(eslintVersion) < 9;
5+
16
const defaultParserOptions = {
2-
ecmaVersion: 2018,
37
ecmaFeatures: {
48
experimentalObjectRestSpread: true,
59
jsx: true,
610
},
711
};
812

13+
const defaultLegacyParserOptions = {
14+
...defaultParserOptions,
15+
ecmaVersion: 2018,
16+
};
17+
18+
const defaultLanguageOptions = {
19+
ecmaVersion: 'latest',
20+
parserOptions: {
21+
...defaultParserOptions,
22+
},
23+
};
24+
925
export default function parserOptionsMapper({
1026
code,
1127
errors,
1228
options = [],
13-
parserOptions = {},
14-
settings,
29+
languageOptions = {},
30+
settings = {},
1531
}) {
16-
return {
17-
code,
18-
errors,
19-
options,
20-
parserOptions: {
21-
...defaultParserOptions,
22-
...parserOptions,
23-
},
24-
settings,
25-
};
32+
return usingLegacy
33+
? {
34+
code,
35+
errors,
36+
options,
37+
parserOptions: {
38+
...defaultLegacyParserOptions,
39+
...languageOptions,
40+
},
41+
settings,
42+
}
43+
: {
44+
code,
45+
errors,
46+
options,
47+
languageOptions: {
48+
...defaultLanguageOptions,
49+
...languageOptions,
50+
},
51+
settings,
52+
};
2653
}

__tests__/src/rules/anchor-is-valid-test.js

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,9 @@ ruleTester.run('anchor-is-valid', rule, {
272272
options: noHrefAspect,
273273
},
274274

275-
// CUSTOM COMPONENTS AND SPECIALLINK AND ASPECT
275+
// CUSTOM COMPONENTS AND SPECIAL LINK AND ASPECT
276276
{ code: '<Anchor hrefLeft={undefined} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
277277
{ code: '<Anchor hrefLeft={null} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
278-
{ code: '<Anchor hrefLeft={undefined} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
279-
{ code: '<Anchor hrefLeft={null} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
280-
{ code: '<Anchor hrefLeft={undefined} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
281-
{ code: '<Anchor hrefLeft={null} />', options: componentsAndSpecialLinkAndInvalidHrefAspect },
282-
283278
)).map(parserOptionsMapper),
284279
invalid: parsers.all([].concat(
285280
// DEFAULT ELEMENT 'a' TESTS
@@ -372,7 +367,7 @@ ruleTester.run('anchor-is-valid', rule, {
372367
options: specialLink,
373368
},
374369

375-
// CUSTOM BOTH COMPONENTS AND SPECIALLINK TESTS
370+
// CUSTOM BOTH COMPONENTS AND SPECIAL LINK TESTS
376371
// NO HREF
377372
{ code: '<Anchor Anchor={undefined} />', errors: [noHrefexpectedError], options: componentsAndSpecialLink },
378373
{ code: '<Anchor hrefLeft={null} />', errors: [noHrefexpectedError], options: componentsAndSpecialLink },
@@ -522,27 +517,7 @@ ruleTester.run('anchor-is-valid', rule, {
522517
errors: [invalidHrefexpectedError],
523518
},
524519

525-
// CUSTOM COMPONENTS AND SPECIALLINK AND ASPECT
526-
{
527-
code: '<Anchor hrefLeft={undefined} />',
528-
options: componentsAndSpecialLinkAndNoHrefAspect,
529-
errors: [noHrefexpectedError],
530-
},
531-
{
532-
code: '<Anchor hrefLeft={null} />',
533-
options: componentsAndSpecialLinkAndNoHrefAspect,
534-
errors: [noHrefexpectedError],
535-
},
536-
{
537-
code: '<Anchor hrefLeft={undefined} />',
538-
options: componentsAndSpecialLinkAndNoHrefAspect,
539-
errors: [noHrefexpectedError],
540-
},
541-
{
542-
code: '<Anchor hrefLeft={null} />',
543-
options: componentsAndSpecialLinkAndNoHrefAspect,
544-
errors: [noHrefexpectedError],
545-
},
520+
// CUSTOM COMPONENTS AND SPECIAL LINK AND ASPECT
546521
{
547522
code: '<Anchor hrefLeft={undefined} />',
548523
options: componentsAndSpecialLinkAndNoHrefAspect,

__tests__/src/rules/no-noninteractive-element-interactions-test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,6 @@ const neverValid = [
336336
{ code: '<tfoot onClick={() => {}} />;', errors: [expectedError] },
337337
{ code: '<thead onClick={() => {}} />;', errors: [expectedError] },
338338
{ code: '<time onClick={() => {}} />;', errors: [expectedError] },
339-
{ code: '<ol onClick={() => {}} />;', errors: [expectedError] },
340339
{ code: '<ul onClick={() => {}} />;', errors: [expectedError] },
341340
{ code: '<ul contentEditable="false" onClick={() => {}} />;', errors: [expectedError] },
342341
{ code: '<article contentEditable onClick={() => {}} />;', errors: [expectedError] },
@@ -345,7 +344,6 @@ const neverValid = [
345344
{ code: '<div role="alert" onClick={() => {}} />;', errors: [expectedError] },
346345
{ code: '<div role="alertdialog" onClick={() => {}} />;', errors: [expectedError] },
347346
{ code: '<div role="application" onClick={() => {}} />;', errors: [expectedError] },
348-
{ code: '<div role="article" onClick={() => {}} />;', errors: [expectedError] },
349347
{ code: '<div role="banner" onClick={() => {}} />;', errors: [expectedError] },
350348
{ code: '<div role="cell" onClick={() => {}} />;', errors: [expectedError] },
351349
{ code: '<div role="complementary" onClick={() => {}} />;', errors: [expectedError] },

__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@ const neverValid = [
360360
* interactive role. */
361361
{ code: '<main role="button" />;', errors: [expectedError] },
362362
{ code: '<article role="button" />;', errors: [expectedError] },
363-
{ code: '<article role="button" />;', errors: [expectedError] },
364363
{ code: '<aside role="button" />;', errors: [expectedError] },
365364
{ code: '<blockquote role="button" />;', errors: [expectedError] },
366365
{ code: '<body role="button" />;', errors: [expectedError] },
@@ -412,7 +411,6 @@ const neverValid = [
412411
* interactive role. */
413412
{ code: '<main role="menuitem" />;', errors: [expectedError] },
414413
{ code: '<article role="menuitem" />;', errors: [expectedError] },
415-
{ code: '<article role="menuitem" />;', errors: [expectedError] },
416414
{ code: '<dd role="menuitem" />;', errors: [expectedError] },
417415
{ code: '<dfn role="menuitem" />;', errors: [expectedError] },
418416
{ code: '<dt role="menuitem" />;', errors: [expectedError] },

__tests__/src/rules/no-static-element-interactions-test.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ const alwaysValid = [
8585
{ code: '<audio onClick={() => {}} />;' },
8686
{ code: '<form onClick={() => {}} />;' },
8787
{ code: '<form onSubmit={() => {}} />;' },
88-
{ code: '<link onClick={() => {}} href="#" />;' },
8988
/* HTML elements attributed with an interactive role */
9089
{ code: '<div role="button" onClick={() => {}} />;' },
9190
{ code: '<div role="checkbox" onClick={() => {}} />;' },
@@ -115,7 +114,6 @@ const alwaysValid = [
115114
{ code: '<article onDblClick={() => void 0} />;' },
116115
{ code: '<aside onClick={() => {}} />;' },
117116
{ code: '<blockquote onClick={() => {}} />;' },
118-
{ code: '<body onClick={() => {}} />;' },
119117
{ code: '<br onClick={() => {}} />;' },
120118
{ code: '<canvas onClick={() => {}} />;' },
121119
{ code: '<caption onClick={() => {}} />;' },
@@ -130,7 +128,6 @@ const alwaysValid = [
130128
{ code: '<figcaption onClick={() => {}} />;' },
131129
{ code: '<figure onClick={() => {}} />;' },
132130
{ code: '<footer onClick={() => {}} />;' },
133-
{ code: '<frame onClick={() => {}} />;' },
134131
{ code: '<h1 onClick={() => {}} />;' },
135132
{ code: '<h2 onClick={() => {}} />;' },
136133
{ code: '<h3 onClick={() => {}} />;' },
@@ -288,7 +285,6 @@ const neverValid = [
288285
{ code: '<a tabIndex="0" onClick={() => void 0} />', errors: [expectedError] },
289286
{ code: '<area onClick={() => {}} />;', errors: [expectedError] },
290287
{ code: '<acronym onClick={() => {}} />;', errors: [expectedError] },
291-
{ code: '<address onClick={() => {}} />;', errors: [expectedError] },
292288
{ code: '<applet onClick={() => {}} />;', errors: [expectedError] },
293289
{ code: '<b onClick={() => {}} />;', errors: [expectedError] },
294290
{ code: '<base onClick={() => {}} />;', errors: [expectedError] },
@@ -304,7 +300,6 @@ const neverValid = [
304300
{ code: '<content onClick={() => {}} />;', errors: [expectedError] },
305301
{ code: '<data onClick={() => {}} />;', errors: [expectedError] },
306302
{ code: '<del onClick={() => {}} />;', errors: [expectedError] },
307-
{ code: '<div onClick={() => {}} />;', errors: [expectedError] },
308303
{ code: '<em onClick={() => {}} />;', errors: [expectedError] },
309304
{ code: '<font onClick={() => {}} />;', errors: [expectedError] },
310305
{ code: '<frameset onClick={() => {}} />;', errors: [expectedError] },

__tests__/src/rules/prefer-tag-over-role-test.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const expectedError = (role, tag) => ({
1010
type: 'JSXOpeningElement',
1111
});
1212

13-
ruleTester.run('element-role', rule, {
13+
ruleTester.run('prefer-tag-over-role', rule, {
1414
valid: parsers.all([].concat(
1515
{ code: '<div />;' },
1616
{ code: '<div role="unknown" />;' },
@@ -55,10 +55,6 @@ ruleTester.run('element-role', rule, {
5555
code: '<other role="checkbox" />',
5656
errors: [expectedError('checkbox', '<input type="checkbox">')],
5757
},
58-
{
59-
code: '<other role="checkbox" />',
60-
errors: [expectedError('checkbox', '<input type="checkbox">')],
61-
},
6258
{
6359
code: '<div role="banner" />',
6460
errors: [expectedError('banner', '<header>')],
Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,88 @@
1+
import { version as eslintVersion } from 'eslint/package.json';
12
import expect from 'expect';
3+
import semver from 'semver';
24
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
35

6+
const usingLegacy = semver.major(eslintVersion) < 9;
7+
48
describe('parserOptionsMapper', () => {
59
it('should return an test case object', () => {
610
const testCase = {
711
code: '<div />',
812
errors: [],
913
options: {},
1014
};
11-
expect(parserOptionsMapper(testCase)).toEqual({
12-
code: '<div />',
13-
errors: [],
14-
options: {},
15-
parserOptions: {
16-
ecmaVersion: 2018,
17-
ecmaFeatures: {
18-
experimentalObjectRestSpread: true,
19-
jsx: true,
15+
16+
const expectedResult = usingLegacy
17+
? {
18+
code: '<div />',
19+
errors: [],
20+
options: {},
21+
parserOptions: {
22+
ecmaVersion: 2018,
23+
ecmaFeatures: {
24+
experimentalObjectRestSpread: true,
25+
jsx: true,
26+
},
2027
},
21-
},
22-
});
28+
settings: {},
29+
}
30+
: {
31+
code: '<div />',
32+
errors: [],
33+
options: {},
34+
languageOptions: {
35+
ecmaVersion: 'latest',
36+
parserOptions: {
37+
ecmaFeatures: {
38+
experimentalObjectRestSpread: true,
39+
jsx: true,
40+
},
41+
},
42+
},
43+
settings: {},
44+
};
45+
expect(parserOptionsMapper(testCase)).toEqual(expectedResult);
2346
});
2447
it('should allow for overriding parserOptions', () => {
2548
const testCase = {
2649
code: '<div />',
2750
errors: [],
2851
options: {},
29-
parserOptions: {
52+
languageOptions: {
3053
ecmaVersion: 5,
3154
},
3255
};
33-
expect(parserOptionsMapper(testCase)).toEqual({
34-
code: '<div />',
35-
errors: [],
36-
options: {},
37-
parserOptions: {
38-
ecmaVersion: 5,
39-
ecmaFeatures: {
40-
experimentalObjectRestSpread: true,
41-
jsx: true,
56+
57+
const expectedResult = usingLegacy
58+
? {
59+
code: '<div />',
60+
errors: [],
61+
options: {},
62+
parserOptions: {
63+
ecmaVersion: 5,
64+
ecmaFeatures: {
65+
experimentalObjectRestSpread: true,
66+
jsx: true,
67+
},
4268
},
43-
},
44-
});
69+
settings: {},
70+
}
71+
: {
72+
code: '<div />',
73+
errors: [],
74+
options: {},
75+
languageOptions: {
76+
ecmaVersion: 5,
77+
parserOptions: {
78+
ecmaFeatures: {
79+
experimentalObjectRestSpread: true,
80+
jsx: true,
81+
},
82+
},
83+
},
84+
settings: {},
85+
};
86+
expect(parserOptionsMapper(testCase)).toEqual(expectedResult);
4587
});
4688
});

examples/flat-cjs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
"react-dom": "^18.2.0"
1212
},
1313
"devDependencies": {
14-
"@eslint/js": "^9.5.0",
14+
"@eslint/js": "^9.9.1",
1515
"cross-env": "^7.0.3",
16-
"eslint": "^8.57.0",
16+
"eslint": "^9.9.1",
1717
"eslint-plugin-jsx-a11y": "file:../..",
1818
"globals": "^15.6.0"
1919
}

0 commit comments

Comments
 (0)