From 3addf5254ab19d95364a8e2c9e78b0f4256f0177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20De=20Boey?= Date: Mon, 30 Aug 2021 03:06:15 +0200 Subject: [PATCH] [New] support eslint 8.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michaƫl De Boey Co-authored-by: Jordan Harband --- .eslintrc | 2 ++ .github/workflows/node-4+.yml | 23 +++++++++++++++++++++ CHANGELOG.md | 2 ++ lib/rules/jsx-equals-spacing.js | 2 +- package.json | 8 +++---- tests/helpers/getESLintCoreRule.js | 11 ++++++++++ tests/helpers/parsers.js | 11 ++++++++-- tests/lib/rules/destructuring-assignment.js | 3 --- tests/lib/rules/jsx-no-undef.js | 4 ++-- tests/lib/rules/jsx-no-useless-fragment.js | 4 +--- tests/lib/rules/jsx-uses-react.js | 4 ++-- tests/lib/rules/jsx-uses-vars.js | 6 +++--- tests/lib/rules/no-unused-prop-types.js | 6 ------ 13 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 tests/helpers/getESLintCoreRule.js diff --git a/.eslintrc b/.eslintrc index 03c2f178f9..b3af93dd31 100644 --- a/.eslintrc +++ b/.eslintrc @@ -30,9 +30,11 @@ "prefer-object-spread": 0, // until node 8 is required "prefer-rest-params": 0, // until node 6 is required "prefer-spread": 0, // until node 6 is required + "function-call-argument-newline": 1, // TODO: enable "function-paren-newline": 0, "no-plusplus": 1, "no-param-reassign": 1, + "no-unreachable-loop": 1, // TODO: enable "no-restricted-syntax": [2, { "selector": "ObjectPattern", "message": "Object destructuring is not compatible with Node v4" diff --git a/.github/workflows/node-4+.yml b/.github/workflows/node-4+.yml index fd4968e3d1..f29f2c1c2e 100644 --- a/.github/workflows/node-4+.yml +++ b/.github/workflows/node-4+.yml @@ -26,6 +26,7 @@ jobs: matrix: node-version: ${{ fromJson(needs.matrix.outputs.latest) }} eslint: + - 8 - 7 - 6 - 5 @@ -45,24 +46,46 @@ jobs: babel-eslint: 10 - node-version: 4 babel-eslint: 9 + - node-version: 15 + eslint: 8 + - node-version: 13 + eslint: 8 + - node-version: 11 + eslint: 8 + - node-version: 11 + eslint: 7 + - node-version: 10 + eslint: 8 + - node-version: 9 + eslint: 8 - node-version: 9 eslint: 7 + - node-version: 8 + eslint: 8 - node-version: 8 eslint: 7 + - node-version: 7 + eslint: 8 - node-version: 7 eslint: 7 - node-version: 7 eslint: 6 + - node-version: 6 + eslint: 8 - node-version: 6 eslint: 7 - node-version: 6 eslint: 6 + - node-version: 5 + eslint: 8 - node-version: 5 eslint: 7 - node-version: 5 eslint: 6 - node-version: 5 eslint: 5 + - node-version: 4 + eslint: 8 - node-version: 4 eslint: 7 - node-version: 4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 673f91b623..e8d25be7c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased ### Added +* support eslint 8.x ([#3059][] @MichaelDeBoey @ljharb) * [`no-unused-class-component-methods`]: Handle unused class component methods ([#2166][] @jakeleventhal @pawelnvk) * add [`no-arrow-function-lifecycle`] ([#1980][] @ngtan) * add support for `@typescript-eslint/parser` v5 (@ljharb) @@ -37,6 +38,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel [#3110]: https://github.com/yannickcr/eslint-plugin-react/pull/3110 [#3102]: https://github.com/yannickcr/eslint-plugin-react/issue/3102 [#3092]: https://github.com/yannickcr/eslint-plugin-react/pull/3092 +[#3059]: https://github.com/yannickcr/eslint-plugin-react/pull/3059 [#2863]: https://github.com/yannickcr/eslint-plugin-react/pull/2863 [#2166]: https://github.com/yannickcr/eslint-plugin-react/pull/2166 [#1980]: https://github.com/yannickcr/eslint-plugin-react/pull/1980 diff --git a/lib/rules/jsx-equals-spacing.js b/lib/rules/jsx-equals-spacing.js index 0ec17d06b4..e95ecfc15d 100644 --- a/lib/rules/jsx-equals-spacing.js +++ b/lib/rules/jsx-equals-spacing.js @@ -65,7 +65,6 @@ module.exports = { const spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value); switch (config) { - default: case 'never': if (spacedBefore) { report(context, messages.noSpaceBefore, 'noSpaceBefore', { @@ -106,6 +105,7 @@ module.exports = { }); } break; + default: } }); }, diff --git a/package.json b/package.json index 210dc79f75..075d8188e7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "description": "React specific linting rules for ESLint", "main": "index.js", "scripts": { - "lint": "eslint ./", + "lint": "eslint .", "postlint": "npm run type-check", "pretest": "npm run lint", "test": "npm run unit-test", @@ -56,8 +56,8 @@ "@typescript-eslint/parser": "^2.34.0 || ^3.10.1 || ^4.0.0 || ^5.0.0", "aud": "^1.1.5", "babel-eslint": "^8 || ^9 || ^10.1.0", - "eslint": "^3 || ^4 || ^5 || ^6 || ^7", - "eslint-config-airbnb-base": "^14.2.1", + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8", + "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-eslint-plugin": "^2.3.0 || ^3.5.3 || ^4.0.1", "eslint-plugin-import": "^2.25.2", "eslint-remote-tester": "^2.0.1", @@ -73,7 +73,7 @@ "typescript-eslint-parser": "^20.1.1" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" }, "engines": { "node": ">=4" diff --git a/tests/helpers/getESLintCoreRule.js b/tests/helpers/getESLintCoreRule.js new file mode 100644 index 0000000000..bbed38bccb --- /dev/null +++ b/tests/helpers/getESLintCoreRule.js @@ -0,0 +1,11 @@ +'use strict'; + +const version = require('eslint/package.json').version; +const semver = require('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}`)); + +module.exports = getESLintCoreRule; diff --git a/tests/helpers/parsers.js b/tests/helpers/parsers.js index 321e57dc14..4170b7ce4e 100644 --- a/tests/helpers/parsers.js +++ b/tests/helpers/parsers.js @@ -60,7 +60,7 @@ const parsers = { const es = test.parserOptions && test.parserOptions.ecmaVersion; function addComment(testObject, parser) { - const extraComment = `\n// features: [${Array.from(features).join(',')}], parser: ${parser}, parserOptions: ${testObject.parserOptions}`; + const extraComment = `\n// features: [${Array.from(features).join(',')}], parser: ${parser}, parserOptions: ${JSON.stringify(testObject.parserOptions)}`; return Object.assign( {}, testObject, @@ -98,7 +98,14 @@ const parsers = { const tsNew = !skipTS && !features.has('no-ts-new'); return [].concat( - skipBase ? [] : addComment(test, 'default'), + skipBase ? [] : addComment( + Object.assign({}, test, features.has('class fields') && { + parserOptions: Object.assign({}, test.parserOptions, { + ecmaVersion: Math.max((test.parserOptions && test.parserOptions.ecmaVersion) || 0, 2022), + }), + }), + 'default' + ), skipOldBabel ? [] : addComment(Object.assign({}, test, { parser: parsers.BABEL_ESLINT, parserOptions: parsers.babelParserOptions(test, features), diff --git a/tests/lib/rules/destructuring-assignment.js b/tests/lib/rules/destructuring-assignment.js index 1eac79122e..6f4286958e 100644 --- a/tests/lib/rules/destructuring-assignment.js +++ b/tests/lib/rules/destructuring-assignment.js @@ -646,7 +646,6 @@ ruleTester.run('destructuring-assignment', rule, { ); }; `, - parser: parsers.BABEL_ESLINT, errors: [ { messageId: 'useDestructAssignment', @@ -675,7 +674,6 @@ ruleTester.run('destructuring-assignment', rule, { }, }; `, - parser: parsers.BABEL_ESLINT, errors: [ { messageId: 'useDestructAssignment', @@ -704,7 +702,6 @@ ruleTester.run('destructuring-assignment', rule, { }; } `, - parser: parsers.BABEL_ESLINT, errors: [ { messageId: 'useDestructAssignment', diff --git a/tests/lib/rules/jsx-no-undef.js b/tests/lib/rules/jsx-no-undef.js index 7387b79c8f..665f0da454 100644 --- a/tests/lib/rules/jsx-no-undef.js +++ b/tests/lib/rules/jsx-no-undef.js @@ -29,8 +29,8 @@ const parserOptions = { // ----------------------------------------------------------------------------- const ruleTester = new RuleTester({ parserOptions }); -const linter = ruleTester.linter || eslint.linter; -linter.defineRule('no-undef', require('eslint/lib/rules/no-undef')); +const linter = ruleTester.linter || eslint.linter || eslint.Linter; +linter.defineRule('no-undef', require('../../helpers/getESLintCoreRule')('no-undef')); ruleTester.run('jsx-no-undef', rule, { valid: parsers.all([ diff --git a/tests/lib/rules/jsx-no-useless-fragment.js b/tests/lib/rules/jsx-no-useless-fragment.js index 6b104dd976..d9a5e15c31 100644 --- a/tests/lib/rules/jsx-no-useless-fragment.js +++ b/tests/lib/rules/jsx-no-useless-fragment.js @@ -8,12 +8,10 @@ // Requirements // ----------------------------------------------------------------------------- -const eslint = require('eslint'); +const RuleTester = require('eslint').RuleTester; const rule = require('../../../lib/rules/jsx-no-useless-fragment'); const parsers = require('../../helpers/parsers'); -const RuleTester = eslint.RuleTester; - const parserOptions = { ecmaVersion: 2018, ecmaFeatures: { diff --git a/tests/lib/rules/jsx-uses-react.js b/tests/lib/rules/jsx-uses-react.js index 3fcc973654..0110be18bb 100644 --- a/tests/lib/rules/jsx-uses-react.js +++ b/tests/lib/rules/jsx-uses-react.js @@ -10,7 +10,7 @@ // ----------------------------------------------------------------------------- const eslint = require('eslint'); -const rule = require('eslint/lib/rules/no-unused-vars'); +const rule = require('../../helpers/getESLintCoreRule')('no-unused-vars'); const RuleTester = eslint.RuleTester; @@ -35,7 +35,7 @@ const settings = { // ----------------------------------------------------------------------------- const ruleTester = new RuleTester({ parserOptions }); -const linter = ruleTester.linter || eslint.linter; +const linter = ruleTester.linter || eslint.linter || eslint.Linter; linter.defineRule('jsx-uses-react', require('../../../lib/rules/jsx-uses-react')); ruleTester.run('no-unused-vars', rule, { diff --git a/tests/lib/rules/jsx-uses-vars.js b/tests/lib/rules/jsx-uses-vars.js index f689faa9dd..3dc9ccdaad 100644 --- a/tests/lib/rules/jsx-uses-vars.js +++ b/tests/lib/rules/jsx-uses-vars.js @@ -10,8 +10,8 @@ // ----------------------------------------------------------------------------- const eslint = require('eslint'); -const ruleNoUnusedVars = require('eslint/lib/rules/no-unused-vars'); -const rulePreferConst = require('eslint/lib/rules/prefer-const'); +const ruleNoUnusedVars = require('../../helpers/getESLintCoreRule')('no-unused-vars'); +const rulePreferConst = require('../../helpers/getESLintCoreRule')('prefer-const'); const RuleTester = eslint.RuleTester; @@ -30,7 +30,7 @@ const parserOptions = { // ----------------------------------------------------------------------------- const ruleTester = new RuleTester({ parserOptions }); -const linter = ruleTester.linter || eslint.linter; +const linter = ruleTester.linter || eslint.linter || eslint.Linter; linter.defineRule('jsx-uses-vars', require('../../../lib/rules/jsx-uses-vars')); ruleTester.run('no-unused-vars', ruleNoUnusedVars, { diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index f552b5dd04..99c5956989 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -234,9 +234,6 @@ ruleTester.run('no-unused-prop-types', rule, { } `, features: ['class fields', 'optional chaining'], - parserOptions: { - ecmaVersion: 2020, - }, }, { code: ` @@ -775,9 +772,6 @@ ruleTester.run('no-unused-prop-types', rule, { } `, features: ['class fields', 'optional chaining'], - parserOptions: { - ecmaVersion: 2020, - }, }, { code: `