Skip to content

[New] add eslint 9 support #1009

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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