Skip to content

Commit 5cff58e

Browse files
committed
[Tests] add parsers.all helper
1 parent 3b76fb3 commit 5cff58e

1 file changed

Lines changed: 158 additions & 0 deletions

File tree

tests/src/parsers.js

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
'use strict';
2+
3+
// const path = require('path');
4+
const semver = require('semver');
5+
const version = require('eslint/package.json').version;
6+
const flatMap = require('array.prototype.flatmap');
7+
const tsParserVersion = require('@typescript-eslint/parser/package.json').version;
8+
9+
const disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is not useful on v4.1+ of the TS parser
10+
? (x) => Object.assign({}, x, { features: [].concat(x.features, 'no-ts-new') })
11+
: (x) => x;
12+
13+
// const NODE_MODULES = '../../node_modules';
14+
15+
// TODO: consolidate
16+
import { parsers as utilsParsers } from './utils';
17+
18+
const parsers = {
19+
...utilsParsers,
20+
disableNewTS,
21+
babelParserOptions: function parserOptions(test, features) {
22+
return Object.assign({}, test.parserOptions, {
23+
requireConfigFile: false,
24+
babelOptions: {
25+
presets: [
26+
'@babel/preset-react',
27+
],
28+
plugins: [
29+
'@babel/plugin-syntax-do-expressions',
30+
'@babel/plugin-syntax-function-bind',
31+
['@babel/plugin-syntax-decorators', { legacy: true }],
32+
],
33+
parserOpts: {
34+
allowSuperOutsideMethod: false,
35+
allowReturnOutsideFunction: false,
36+
},
37+
},
38+
ecmaFeatures: Object.assign(
39+
{},
40+
test.parserOptions && test.parserOptions.ecmaFeatures,
41+
{
42+
jsx: true,
43+
modules: true,
44+
legacyDecorators: features.has('decorators'),
45+
},
46+
),
47+
});
48+
},
49+
all: function all(tests) {
50+
const t = flatMap(tests, (test) => {
51+
if (typeof test === 'string') {
52+
test = { code: test };
53+
}
54+
if ('parser' in test) {
55+
delete test.features;
56+
return test;
57+
}
58+
const features = new Set([].concat(test.features || []));
59+
delete test.features;
60+
const es = test.parserOptions && test.parserOptions.ecmaVersion;
61+
62+
function addComment(testObject, parser) {
63+
const extras = [].concat(
64+
`features: [${Array.from(features).join(',')}]`,
65+
`parser: ${parser}`,
66+
testObject.parserOptions ? `parserOptions: ${JSON.stringify(testObject.parserOptions)}` : [],
67+
testObject.options ? `options: ${JSON.stringify(testObject.options)}` : [],
68+
testObject.settings ? `settings: ${JSON.stringify(testObject.settings)}` : [],
69+
);
70+
71+
const extraComment = `\n// ${extras.join(', ')}`;
72+
73+
// Augment expected fix code output with extraComment
74+
const nextCode = { code: testObject.code + extraComment };
75+
const nextOutput = testObject.output && { output: testObject.output + extraComment };
76+
77+
// Augment expected suggestion outputs with extraComment
78+
// `errors` may be a number (expected number of errors) or an array of
79+
// error objects.
80+
const nextErrors = testObject.errors
81+
&& typeof testObject.errors !== 'number'
82+
&& {
83+
errors: testObject.errors.map(
84+
(errorObject) => {
85+
const nextSuggestions = errorObject.suggestions && {
86+
suggestions: errorObject.suggestions.map((suggestion) => Object.assign({}, suggestion, {
87+
output: suggestion.output + extraComment,
88+
})),
89+
};
90+
91+
return Object.assign({}, errorObject, nextSuggestions);
92+
},
93+
),
94+
};
95+
96+
return Object.assign(
97+
{},
98+
testObject,
99+
nextCode,
100+
nextOutput,
101+
nextErrors,
102+
);
103+
}
104+
105+
const skipBase = (features.has('class fields') && semver.satisfies(version, '< 8'))
106+
|| (es >= 2020 && semver.satisfies(version, '< 6'))
107+
|| features.has('no-default')
108+
|| features.has('bind operator')
109+
|| features.has('do expressions')
110+
|| features.has('decorators')
111+
|| features.has('flow')
112+
|| features.has('ts')
113+
|| features.has('types')
114+
|| (features.has('fragment') && semver.satisfies(version, '< 5'));
115+
116+
const skipBabel = features.has('no-babel');
117+
const skipOldBabel = skipBabel || features.has('no-babel-old') || semver.satisfies(version, '>= 8');
118+
const skipNewBabel = skipBabel
119+
|| features.has('no-babel-new')
120+
|| !semver.satisfies(version, '^7.5.0') // require('@babel/eslint-parser/package.json').peerDependencies.eslint
121+
|| features.has('flow')
122+
|| features.has('types')
123+
|| features.has('ts');
124+
const skipTS = semver.satisfies(version, '<= 5') // TODO: make these pass on eslint 5
125+
|| features.has('no-ts')
126+
|| features.has('flow')
127+
|| features.has('jsx namespace')
128+
|| features.has('bind operator')
129+
|| features.has('do expressions');
130+
const tsOld = !skipTS && !features.has('no-ts-old');
131+
const tsNew = !skipTS && !features.has('no-ts-new');
132+
133+
return [].concat(
134+
skipBase ? [] : addComment(
135+
Object.assign({}, test, features.has('class fields') && {
136+
parserOptions: Object.assign({}, test.parserOptions, {
137+
ecmaVersion: Math.max((test.parserOptions && test.parserOptions.ecmaVersion) || 0, 2022),
138+
}),
139+
}),
140+
'default',
141+
),
142+
skipOldBabel ? [] : addComment(Object.assign({}, test, {
143+
parser: parsers.BABEL_ESLINT,
144+
parserOptions: parsers.babelParserOptions(test, features),
145+
}), 'babel-eslint'),
146+
skipNewBabel ? [] : addComment(Object.assign({}, test, {
147+
parser: parsers['@BABEL_ESLINT'],
148+
parserOptions: parsers.babelParserOptions(test, features),
149+
}), '@babel/eslint-parser'),
150+
tsOld ? addComment(Object.assign({}, test, { parser: parsers.TYPESCRIPT_ESLINT }), 'typescript-eslint') : [],
151+
tsNew ? addComment(Object.assign({}, test, { parser: parsers['@TYPESCRIPT_ESLINT'] }), '@typescript-eslint/parser') : [],
152+
);
153+
});
154+
return t;
155+
},
156+
};
157+
158+
module.exports = parsers;

0 commit comments

Comments
 (0)