-
-
Notifications
You must be signed in to change notification settings - Fork 638
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Tests] migrate helper parsers function from
eslint-plugin-react
Co-authored-by: Ross Rosales <52366381+ROSSROSALES@users.noreply.github.com> Co-authored-by: Jordan Harband <ljharb@gmail.com>
- Loading branch information
1 parent
9688ad8
commit ce4d57f
Showing
42 changed files
with
534 additions
and
280 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { version } from 'eslint/package.json'; | ||
import semver from '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}`)); | ||
|
||
export default getESLintCoreRule; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
import path from 'path'; | ||
import semver from 'semver'; | ||
import entries from 'object.entries'; | ||
import { version } from 'eslint/package.json'; | ||
import flatMap from 'array.prototype.flatmap'; | ||
|
||
let tsParserVersion; | ||
try { | ||
// eslint-disable-next-line import/no-unresolved, global-require | ||
tsParserVersion = require('@typescript-eslint/parser/package.json').version; | ||
} catch (e) { /**/ } | ||
|
||
const disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is not useful on v4.1+ of the TS parser | ||
? (x) => ({ ...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( | ||
...[].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, | ||
babelParserOptions: function parserOptions(test, features) { | ||
return { | ||
...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: { | ||
|
||
...test.parserOptions && test.parserOptions.ecmaFeatures, | ||
jsx: true, | ||
modules: true, | ||
legacyDecorators: features.has('decorators'), | ||
}, | ||
}; | ||
}, | ||
all: function all(tests) { | ||
const t = flatMap(tests, (test) => { | ||
/* eslint no-param-reassign: 0 */ | ||
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) => ({ ...suggestion, output: suggestion.output + extraComment })), | ||
}; | ||
|
||
return { ...errorObject, ...nextSuggestions }; | ||
}, | ||
), | ||
}; | ||
|
||
return { | ||
|
||
...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( | ||
{ | ||
...test, | ||
...typeof es === 'number' && { | ||
parserOptions: { ...test.parserOptions, ecmaVersion: es }, | ||
}, | ||
}, | ||
'default', | ||
), | ||
skipOldBabel ? [] : addComment({ | ||
...test, | ||
parser: parsers.BABEL_ESLINT, | ||
parserOptions: parsers.babelParserOptions(test, features), | ||
}, 'babel-eslint'), | ||
skipNewBabel ? [] : addComment({ | ||
...test, | ||
parser: parsers['@BABEL_ESLINT'], | ||
parserOptions: parsers.babelParserOptions(test, features), | ||
}, '@babel/eslint-parser'), | ||
tsOld ? addComment({ ...test, parser: parsers.TYPESCRIPT_ESLINT }, 'typescript-eslint') : [], | ||
tsNew ? addComment({ ...test, parser: parsers['@TYPESCRIPT_ESLINT'] }, '@typescript-eslint/parser') : [], | ||
); | ||
}); | ||
return t; | ||
}, | ||
}; | ||
|
||
export default parsers; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.