Skip to content

Commit

Permalink
Adjust some tests to match eslint v9 config
Browse files Browse the repository at this point in the history
  • Loading branch information
MatiPl01 committed Apr 28, 2024
1 parent 240d551 commit fb91d5a
Show file tree
Hide file tree
Showing 109 changed files with 1,411 additions and 1,070 deletions.
13 changes: 7 additions & 6 deletions lib/util/Components.js
Original file line number Diff line number Diff line change
Expand Up @@ -637,14 +637,15 @@ function componentRule(rule, context) {
let componentNode;
// Get the component path
const componentPath = [];
while (node) {
if (node.property && node.property.type === 'Identifier') {
componentPath.push(node.property.name);
let currentNode = node;
while (currentNode) {
if (currentNode.property && currentNode.property.type === 'Identifier') {
componentPath.push(currentNode.property.name);
}
if (node.object && node.object.type === 'Identifier') {
componentPath.push(node.object.name);
if (currentNode.object && currentNode.object.type === 'Identifier') {
componentPath.push(currentNode.object.name);
}
node = node.object;
currentNode = currentNode.object;
}
componentPath.reverse();
const componentName = componentPath.slice(0, componentPath.length - 1).join('.');
Expand Down
4 changes: 3 additions & 1 deletion lib/util/annotations.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

'use strict';

const eslintUtil = require('./eslint');

/**
* Checks if we are declaring a `props` argument with a flow type annotation.
* @param {ASTNode} node The AST node being checked.
Expand All @@ -19,7 +21,7 @@ function isAnnotatedFunctionPropsDeclaration(node, context) {

const typeNode = node.params[0].type === 'AssignmentPattern' ? node.params[0].left : node.params[0];

const tokens = context.getFirstTokens(typeNode, 2);
const tokens = eslintUtil.getFirstTokens(typeNode, context, 2);
const isAnnotated = typeNode.typeAnnotation;
const isDestructuredProps = typeNode.type === 'ObjectPattern';
const isProps = tokens[0].value === 'props' || (tokens[1] && tokens[1].value === 'props');
Expand Down
8 changes: 8 additions & 0 deletions lib/util/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,17 @@ function markVariableAsUsed(name, node, context) {
: context.markVariableAsUsed(name);
}

function getFirstTokens(node, context, count) {
const sourceCode = getSourceCode(context);
return sourceCode.getFirstTokens
? sourceCode.getFirstTokens(node, count)
: context.getFirstTokens(node, count);
}

module.exports = {
getSourceCode,
getScope,
getAncestors,
markVariableAsUsed,
getFirstTokens,
};
2 changes: 1 addition & 1 deletion lib/util/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,7 @@ module.exports = function propTypesInstructions(context, components, utils) {
*/
function isAnnotatedClassPropsDeclaration(node) {
if (node && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')) {
const tokens = context.getFirstTokens(node, 2);
const tokens = eslintUtil.getFirstTokens(node, context, 2);
if (
node.typeAnnotation && (
tokens[0].value === 'props'
Expand Down
2 changes: 1 addition & 1 deletion lib/util/usedPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
throw new Error(`${node.type} ASTNodes are not handled by markPropTypesAsUsed`);
}

const component = components.get(utils.getParentComponent());
const component = components.get(utils.getParentComponent(node));
const usedPropTypes = (component && component.usedPropTypes) || [];
let ignoreUnusedPropTypesValidation = (component && component.ignoreUnusedPropTypesValidation) || false;

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-react",
"version": "7.34.1",
"version": "7.34.0",
"author": "Yannick Croissant <yannick.croissant+npm@gmail.com>",
"description": "React specific linting rules for ESLint",
"main": "index.js",
Expand Down Expand Up @@ -57,7 +57,7 @@
"@typescript-eslint/parser": "^2.34.0 || ^3.10.1 || ^4.0.0 || ^5.0.0",
"aud": "^2.0.4",
"babel-eslint": "^8 || ^9 || ^10.1.0",
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 | ^9",
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-doc-generator": "^1.7.0",
"eslint-plugin-eslint-plugin": "^2.3.0 || ^3.5.3 || ^4.0.1 || ^5.0.5",
Expand All @@ -78,7 +78,7 @@
"typescript-eslint-parser": "^20.1.1"
},
"peerDependencies": {
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
},
"engines": {
"node": ">=4"
Expand Down
183 changes: 183 additions & 0 deletions tests/helpers/parsers-old.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
'use strict';

const path = require('path');
const semver = require('semver');
const entries = require('object.entries');
const version = require('eslint/package.json').version;
const flatMap = require('array.prototype.flatmap');
const tsParserVersion = require('@typescript-eslint/parser/package.json').version;

const disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is not useful on v4.1+ of the TS parser
? (x) => Object.assign({}, x, { features: [].concat(x.features, 'no-ts-new') })
: (x) => x;

function minEcmaVersion(features, parserOptions) {
const minEcmaVersionForFeatures = {
'class fields': 2022,
'optional chaining': 2020,
'nullish coalescing': 2020,
};
const result = Math.max.apply(
Math,
[].concat(
(parserOptions && parserOptions.ecmaVersion) || [],
flatMap(entries(minEcmaVersionForFeatures), (entry) => {
const f = entry[0];
const y = entry[1];
return features.has(f) ? y : [];
})
).map((y) => (y > 5 && y < 2015 ? y + 2009 : y)) // normalize editions to years
);
return Number.isFinite(result) ? result : undefined;
}

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'),
disableNewTS,
skipDueToMultiErrorSorting: semver.satisfies(process.versions.node, '^8 || ^9'),
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 }],
],
parserOpts: {
allowSuperOutsideMethod: false,
allowReturnOutsideFunction: false,
},
},
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') {
test = { code: test };
}
if ('parser' in test) {
delete test.features;
return test;
}
const features = new Set([].concat(test.features || []));
delete test.features;

const es = minEcmaVersion(features, test.parserOptions);

function addComment(testObject, parser) {
const extras = [].concat(
`features: [${Array.from(features).join(',')}]`,
`parser: ${parser}`,
testObject.parserOptions ? `parserOptions: ${JSON.stringify(testObject.parserOptions)}` : [],
testObject.options ? `options: ${JSON.stringify(testObject.options)}` : [],
testObject.settings ? `settings: ${JSON.stringify(testObject.settings)}` : []
);

const extraComment = `\n// ${extras.join(', ')}`;

// Augment expected fix code output with extraComment
const nextCode = { code: testObject.code + extraComment };
const nextOutput = testObject.output && { output: testObject.output + extraComment };

// Augment expected suggestion outputs with extraComment
// `errors` may be a number (expected number of errors) or an array of
// error objects.
const nextErrors = testObject.errors
&& typeof testObject.errors !== 'number'
&& {
errors: testObject.errors.map(
(errorObject) => {
const nextSuggestions = errorObject.suggestions && {
suggestions: errorObject.suggestions.map((suggestion) => Object.assign({}, suggestion, {
output: suggestion.output + extraComment,
})),
};

return Object.assign({}, errorObject, nextSuggestions);
}
),
};

return Object.assign(
{},
testObject,
nextCode,
nextOutput,
nextErrors
);
}

const skipBase = (features.has('class fields') && semver.satisfies(version, '< 8'))
|| (es >= 2020 && semver.satisfies(version, '< 6'))
|| features.has('no-default')
|| features.has('bind operator')
|| features.has('do expressions')
|| features.has('decorators')
|| features.has('flow')
|| features.has('ts')
|| features.has('types')
|| (features.has('fragment') && semver.satisfies(version, '< 5'));

const skipBabel = features.has('no-babel');
const skipOldBabel = skipBabel
|| features.has('no-babel-old')
|| features.has('optional chaining')
|| 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') // TODO: make these pass on eslint 5
|| features.has('no-ts')
|| features.has('flow')
|| features.has('jsx namespace')
|| features.has('bind operator')
|| features.has('do expressions');
const tsOld = !skipTS && !features.has('no-ts-old');
const tsNew = !skipTS && !features.has('no-ts-new');

return [].concat(
skipBase ? [] : addComment(
Object.assign({}, test, typeof es === 'number' && {
parserOptions: Object.assign({}, test.parserOptions, { ecmaVersion: es }),
}),
'default'
),
skipOldBabel ? [] : addComment(Object.assign({}, test, {
parser: parsers.BABEL_ESLINT,
parserOptions: parsers.babelParserOptions(test, features),
}), '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/parser') : []
);
});

return t;
},
};

module.exports = parsers;

0 comments on commit fb91d5a

Please sign in to comment.