Skip to content

Commit

Permalink
[New] support eslint v9
Browse files Browse the repository at this point in the history
Co-authored-by: Gareth Jones <jones258@gmail.com>
Co-authored-by: michael faith <michaelfaith@users.noreply.github.com>
  • Loading branch information
2 people authored and ljharb committed Apr 7, 2024
1 parent d27a639 commit d66cde0
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 32 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/node-4+.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
- macos-latest
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
eslint:
- 9
- 8
- 7
- 6
Expand Down Expand Up @@ -63,34 +64,58 @@ jobs:
env:
TS_PARSER: 2
exclude:
- node-version: 16
eslint: 9
- node-version: 15
eslint: 9
- node-version: 15
eslint: 8
- node-version: 14
eslint: 9
- node-version: 13
eslint: 9
- node-version: 13
eslint: 8
- node-version: 12
eslint: 9
- node-version: 11
eslint: 9
- node-version: 11
eslint: 8
- node-version: 10
eslint: 9
- node-version: 10
eslint: 8
- node-version: 9
eslint: 9
- node-version: 9
eslint: 8
- node-version: 9
eslint: 7
- node-version: 8
eslint: 9
- node-version: 8
eslint: 8
- node-version: 8
eslint: 7
- node-version: 7
eslint: 9
- node-version: 7
eslint: 8
- node-version: 7
eslint: 7
- node-version: 7
eslint: 6
- node-version: 6
eslint: 9
- node-version: 6
eslint: 8
- node-version: 6
eslint: 7
- node-version: 6
eslint: 6
- node-version: 5
eslint: 9
- node-version: 5
eslint: 8
- node-version: 5
Expand All @@ -99,6 +124,8 @@ jobs:
eslint: 6
- node-version: 5
eslint: 5
- node-version: 4
eslint: 9
- node-version: 4
eslint: 8
- node-version: 4
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
## [Unreleased]

### Added
- support eslint v9 ([#2996], thanks [@G-Rath] [@michaelfaith])
- [`order`]: allow validating named imports ([#3043], thanks [@manuth])

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"chai": "^4.3.10",
"cross-env": "^4.0.0",
"escope": "^3.6.0",
"eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8",
"eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9",
"eslint-doc-generator": "^1.6.1",
"eslint-import-resolver-node": "file:./resolvers/node",
"eslint-import-resolver-typescript": "^1.0.2 || ^1.1.1",
Expand Down Expand Up @@ -106,7 +106,7 @@
"typescript-eslint-parser": "^15 || ^20 || ^22"
},
"peerDependencies": {
"eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
"eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
},
"dependencies": {
"@rtsao/scc": "^1.1.0",
Expand Down
3 changes: 3 additions & 0 deletions tests/files/issue210.config.flat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.languageOptions = {
sourceType: 'module',
}
28 changes: 28 additions & 0 deletions tests/files/just-json-files/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var jsonPlugin = require('eslint-plugin-json');

if (!jsonPlugin.processors.json) {
jsonPlugin.processors.json = jsonPlugin.processors['.json'];
}

module.exports = [
{
files: ['tests/files/just-json-files/*.json'],
plugins:{
json: jsonPlugin,
},
processor: 'json/json',
rules: Object.assign(
{},
{
'import/no-unused-modules': [
'error',
{
'missingExports': false,
'unusedExports': true,
},
],
},
jsonPlugin.configs.recommended.rules
)
},
];
53 changes: 36 additions & 17 deletions tests/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,29 @@ describe('CLI regression tests', function () {
let cli;
before(function () {
if (ESLint) {
eslint = new ESLint({
useEslintrc: false,
overrideConfigFile: './tests/files/issue210.config.js',
rulePaths: ['./src/rules'],
overrideConfig: {
rules: {
named: 2,
if (semver.satisfies(eslintPkg.version, '>= 9')) {
eslint = new ESLint({
overrideConfigFile: './tests/files/issue210.config.flat.js',
overrideConfig: {
rules: {
'import/named': 2,
},
},
},
plugins: { 'eslint-plugin-import': importPlugin },
});
plugins: { 'eslint-plugin-import': importPlugin },
});
} else {
eslint = new ESLint({
useEslintrc: false,
overrideConfigFile: './tests/files/issue210.config.js',
rulePaths: ['./src/rules'],
overrideConfig: {
rules: {
named: 2,
},
},
plugins: { 'eslint-plugin-import': importPlugin },
});
}
} else {
cli = new CLIEngine({
useEslintrc: false,
Expand Down Expand Up @@ -56,13 +68,20 @@ describe('CLI regression tests', function () {
this.skip();
} else {
if (ESLint) {
eslint = new ESLint({
useEslintrc: false,
overrideConfigFile: './tests/files/just-json-files/.eslintrc.json',
rulePaths: ['./src/rules'],
ignore: false,
plugins: { 'eslint-plugin-import': importPlugin },
});
if (semver.satisfies(eslintPkg.version, '>= 9')) {
eslint = new ESLint({
overrideConfigFile: './tests/files/just-json-files/eslint.config.js',
plugins: { 'eslint-plugin-import': importPlugin },
});
} else {
eslint = new ESLint({
useEslintrc: false,
overrideConfigFile: './tests/files/just-json-files/.eslintrc.json',
rulePaths: ['./src/rules'],
ignore: false,
plugins: { 'eslint-plugin-import': importPlugin },
});
}
} else {
cli = new CLIEngine({
useEslintrc: false,
Expand Down
46 changes: 44 additions & 2 deletions tests/src/rule-tester.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,47 @@
import { RuleTester } from 'eslint';
import { version as eslintVersion } from 'eslint/package.json';
import semver from 'semver';

export const usingFlatConfig = semver.major(eslintVersion) >= 9;

export function withoutAutofixOutput(test) {
return { ...test, output: test.code };
return { ...test, ...usingFlatConfig || { output: test.code } };
}

class FlatCompatRuleTester extends RuleTester {
constructor(testerConfig = { parserOptions: { sourceType: 'script' } }) {
super(FlatCompatRuleTester._flatCompat(testerConfig));
}

run(ruleName, rule, tests) {
super.run(ruleName, rule, {
valid: tests.valid.map((t) => FlatCompatRuleTester._flatCompat(t)),
invalid: tests.invalid.map((t) => FlatCompatRuleTester._flatCompat(t)),
});
}

static _flatCompat(config) {
if (!config || !usingFlatConfig || typeof config !== 'object') {
return config;
}

const { parser, parserOptions = {}, languageOptions = {}, ...remainingConfig } = config;
const { ecmaVersion, sourceType, ...remainingParserOptions } = parserOptions;
const parserObj = typeof parser === 'string' ? require(parser) : parser;

return {
...remainingConfig,
languageOptions: {
...languageOptions,
...parserObj ? { parser: parserObj } : {},
...ecmaVersion ? { ecmaVersion } : {},
...sourceType ? { sourceType } : {},
parserOptions: {
...remainingParserOptions,
},
},
};
}
}

export { RuleTester } from 'eslint';
export { FlatCompatRuleTester as RuleTester };
4 changes: 2 additions & 2 deletions tests/src/rules/named.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { test, SYNTAX_CASES, getTSParsers, testFilePath, testVersion, parsers } from '../utils';
import { RuleTester } from '../rule-tester';
import { RuleTester, usingFlatConfig } from '../rule-tester';
import path from 'path';

import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve';
Expand Down Expand Up @@ -32,7 +32,7 @@ ruleTester.run('named', rule, {
settings: { 'import/resolve': { extensions: ['.js', '.jsx'] } } }),

// validate that eslint-disable-line silences this properly
test({ code: 'import {a, b, d} from "./common"; // eslint-disable-line named' }),
test({ code: `import {a, b, d} from "./common"; // eslint-disable-line ${usingFlatConfig ? 'rule-to-test/' : ''}named` }),

test({ code: 'import { foo, bar } from "./re-export-names"' }),

Expand Down
2 changes: 1 addition & 1 deletion tests/src/rules/namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { test, SYNTAX_CASES, getTSParsers, testVersion, testFilePath, parsers }
import { RuleTester } from '../rule-tester';
import flatMap from 'array.prototype.flatmap';

const ruleTester = new RuleTester({ env: { es6: true } });
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
const rule = require('rules/namespace');

function error(name, namespace) {
Expand Down
16 changes: 8 additions & 8 deletions tests/src/rules/no-unused-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ describe('dynamic imports', function () {

// test for unused exports with `import()`
ruleTester.run('no-unused-modules', rule, {
valid: [
test({
valid: [].concat(
testVersion('< 9', () => ({
options: unusedExportsOptions,
code: `
export const a = 10
Expand All @@ -300,10 +300,10 @@ describe('dynamic imports', function () {
`,
parser: parsers.BABEL_OLD,
filename: testFilePath('./no-unused-modules/exports-for-dynamic-js.js'),
}),
],
invalid: [
test({
})),
),
invalid: [].concat(
testVersion('< 9', () => ({
options: unusedExportsOptions,
code: `
export const a = 10
Expand All @@ -319,8 +319,8 @@ describe('dynamic imports', function () {
error(`exported declaration 'b' not used within other modules`),
error(`exported declaration 'c' not used within other modules`),
error(`exported declaration 'default' not used within other modules`),
] }),
],
] })),
),
});
typescriptRuleTester.run('no-unused-modules', rule, {
valid: [
Expand Down

0 comments on commit d66cde0

Please sign in to comment.