diff --git a/CHANGELOG.md b/CHANGELOG.md index b7708d4ae6..5c06e98e78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [`no-unstable-components`]: improve handling of objects containing render function properties ([#3111] @fizwidget) * [`prop-types`], `propTypes`: add forwardRef<>, ForwardRefRenderFunction<> prop-types ([#3112] @vedadeepta) +### Changed +* [Tests] test on the new babel eslint parser ([#3113] @ljharb) + +[#3113]: https://github.com/yannickcr/eslint-plugin-react/pull/3113 [#3112]: https://github.com/yannickcr/eslint-plugin-react/pull/3112 [#3111]: https://github.com/yannickcr/eslint-plugin-react/pull/3111 [#3110]: https://github.com/yannickcr/eslint-plugin-react/pull/3110 diff --git a/package.json b/package.json index 00edeee517..6802f360b6 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,12 @@ "string.prototype.matchall": "^4.0.6" }, "devDependencies": { + "@babel/core": "^7.15.8", + "@babel/eslint-parser": "^7.15.8", + "@babel/plugin-syntax-decorators": "^7.14.5", + "@babel/plugin-syntax-do-expressions": "^7.14.5", + "@babel/plugin-syntax-function-bind": "^7.14.5", + "@babel/preset-react": "^7.14.5", "@types/eslint": "=7.2.10", "@types/estree": "^0.0.50", "@types/node": "^14.17.27", diff --git a/tests/helpers/parsers.js b/tests/helpers/parsers.js index 9f0afb9b79..deea1f229d 100644 --- a/tests/helpers/parsers.js +++ b/tests/helpers/parsers.js @@ -9,8 +9,33 @@ const NODE_MODULES = '../../node_modules'; const parsers = { BABEL_ESLINT: path.join(__dirname, NODE_MODULES, 'babel-eslint'), + '@BABEL_ESLINT': path.join(__dirname, NODE_MODULES, '@babel/eslint-parser'), TYPESCRIPT_ESLINT: path.join(__dirname, NODE_MODULES, 'typescript-eslint-parser'), '@TYPESCRIPT_ESLINT': path.join(__dirname, NODE_MODULES, '@typescript-eslint/parser'), + babelParserOptions: function parserOptions(test, features) { + return Object.assign({}, test.parserOptions, { + requireConfigFile: false, + babelOptions: { + presets: [ + '@babel/preset-react', + ], + plugins: [ + '@babel/plugin-syntax-do-expressions', + '@babel/plugin-syntax-function-bind', + ['@babel/plugin-syntax-decorators', { legacy: true }], + ], + }, + ecmaFeatures: Object.assign( + {}, + test.parserOptions && test.parserOptions.ecmaFeatures, + { + jsx: true, + modules: true, + legacyDecorators: features.has('decorators'), + } + ), + }); + }, all: function all(tests) { const t = flatMap(tests, (test) => { if (typeof test === 'string') { @@ -25,7 +50,7 @@ const parsers = { const es = test.parserOptions && test.parserOptions.ecmaVersion; function addComment(testObject, parser) { - const extraComment = `\n// features: [${Array.from(features).join(',')}], parser: ${parser}`; + const extraComment = `\n// features: [${Array.from(features).join(',')}], parser: ${parser}, parserOptions: ${testObject.parserOptions}`; return Object.assign( {}, testObject, @@ -46,9 +71,16 @@ const parsers = { || (features.has('fragment') && semver.satisfies(version, '< 5')); const skipBabel = features.has('no-babel'); - const skipTS = semver.satisfies(version, '< 5') + const skipOldBabel = skipBabel || semver.satisfies(version, '>= 8'); + const skipNewBabel = skipBabel + || features.has('no-babel-new') + || !semver.satisfies(version, '^7.5.0') // require('@babel/eslint-parser/package.json').peerDependencies.eslint || features.has('flow') + || features.has('types') + || features.has('ts'); + const skipTS = semver.satisfies(version, '< 5') || features.has('no-ts') + || features.has('flow') || features.has('jsx namespace') || features.has('bind operator') || features.has('do expressions'); @@ -57,7 +89,11 @@ const parsers = { return [].concat( skipBase ? [] : addComment(test, 'default'), - skipBabel ? [] : addComment(Object.assign({}, test, { parser: parsers.BABEL_ESLINT }), 'babel-eslint'), + skipOldBabel ? [] : addComment(Object.assign({}, test, { parser: parsers.BABEL_ESLINT }), 'babel-eslint'), + skipNewBabel ? [] : addComment(Object.assign({}, test, { + parser: parsers['@BABEL_ESLINT'], + parserOptions: parsers.babelParserOptions(test, features), + }), '@babel/eslint-parser'), tsOld ? addComment(Object.assign({}, test, { parser: parsers.TYPESCRIPT_ESLINT }), 'typescript-eslint') : [], tsNew ? addComment(Object.assign({}, test, { parser: parsers['@TYPESCRIPT_ESLINT'] }), '@typescript/eslint') : [] ); diff --git a/tests/lib/rules/jsx-curly-brace-presence.js b/tests/lib/rules/jsx-curly-brace-presence.js index 19c4c5843d..bbc163a6f2 100755 --- a/tests/lib/rules/jsx-curly-brace-presence.js +++ b/tests/lib/rules/jsx-curly-brace-presence.js @@ -441,7 +441,7 @@ ruleTester.run('jsx-curly-brace-presence', rule, { ] : []) )), - invalid: parsers.all([ + invalid: parsers.all([].concat( { code: '', output: '', @@ -561,10 +561,45 @@ ruleTester.run('jsx-curly-brace-presence', rule, { {'some-complicated-exp'} `, - features: ['no-default', 'no-ts-new'], // TODO: FIXME: remove no-default and no-ts-new and fix + features: ['no-default', 'no-ts-new', 'no-babel-new'], // TODO: FIXME: remove no-default and no-ts-new and fix options: [{ children: 'never' }], - errors: [{ messageId: 'unnecessaryCurly' }, { messageId: 'unnecessaryCurly' }], + errors: [ + { messageId: 'unnecessaryCurly', line: 3 }, + { messageId: 'unnecessaryCurly', line: 5 }, + ], }, + !semver.satisfies(eslintPkg.version, '^7.5.0') ? { // require('@babel/eslint-parser/package.json').peerDependencies.eslint + // TODO: figure out how to make all other parsers work this well + code: ` + + {'foo'} +
+ {'bar'} +
+ {'baz'} + {'some-complicated-exp'} +
+ `, + output: ` + + foo +
+ bar +
+ baz + some-complicated-exp +
+ `, + parser: parsers['@BABEL_ESLINT'], + parserOptions: parsers.babelParserOptions({}, new Set()), + options: [{ children: 'never' }], + errors: [ + { messageId: 'unnecessaryCurly', line: 3 }, + { messageId: 'unnecessaryCurly', line: 5 }, + { messageId: 'unnecessaryCurly', line: 7 }, + { messageId: 'unnecessaryCurly', line: 8 }, + ], + } : [], { code: `foo`, output: 'foo', @@ -854,6 +889,6 @@ ruleTester.run('jsx-curly-brace-presence', rule, { output: 'foo', errors: [{ messageId: 'unnecessaryCurly' }], options: ['never'], - }, - ]), + } + )), }); diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index b73b088435..f552b5dd04 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -3227,7 +3227,7 @@ ruleTester.run('no-unused-prop-types', rule, { } } `, - features: ['class fields'], + features: ['class fields', 'types'], }, { code: `