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..b6412b1d31 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,6 +71,8 @@ const parsers = {
|| (features.has('fragment') && semver.satisfies(version, '< 5'));
const skipBabel = features.has('no-babel');
+ const skipOldBabel = skipBabel || semver.satisfies(version, '>= 8');
+ const skipNewBabel = skipBabel || features.has('types') || features.has('flow') || features.has('ts') || features.has('no-babel-new');
const skipTS = semver.satisfies(version, '< 5')
|| features.has('flow')
|| features.has('no-ts')
@@ -57,7 +84,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..85be2dc01a 100755
--- a/tests/lib/rules/jsx-curly-brace-presence.js
+++ b/tests/lib/rules/jsx-curly-brace-presence.js
@@ -561,9 +561,43 @@ 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 },
+ ],
+ },
+ { // 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`,
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: `