Skip to content

Commit c18e479

Browse files
authored
test: add basic typescript-eslint integration tests (#17219)
* test: add basic typescript-eslint integration tests * remove redundant ESLint 9 check
1 parent 4d39e9d commit c18e479

3 files changed

Lines changed: 137 additions & 1 deletion

File tree

eslint/babel-eslint-parser/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
"@types/estree": "^1.0.5",
5050
"@typescript-eslint/scope-manager": "^6.19.0",
5151
"dedent": "^1.5.3",
52-
"eslint": "^9.21.0"
52+
"eslint": "^9.21.0",
53+
"typescript-eslint": "8.26.1"
5354
},
5455
"conditions": {
5556
"BABEL_8_BREAKING": [
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import path from "node:path";
2+
import { parseForESLint } from "../lib/index.cjs";
3+
import { ESLint } from "eslint";
4+
import { itDummy, commonJS } from "$repo-utils";
5+
6+
const ESLINT_VERSION = ESLint.version;
7+
const isESLint9 = ESLINT_VERSION.startsWith("9.");
8+
const { require } = commonJS(import.meta.url);
9+
10+
const PROPS_TO_REMOVE = [
11+
// typescript-eslint generates start/end in the loc object, while Babel generate both start/end and loc
12+
{ key: "start", type: "Node" },
13+
{ key: "end", type: "Node" },
14+
15+
{ key: "importKind", type: "Node" },
16+
{ key: "exportKind", type: "Node" },
17+
{ key: "variance", type: "Node" },
18+
{ key: "typeArguments", type: "Node" },
19+
{ key: "filename", type: null },
20+
{ key: "identifierName", type: null },
21+
// For legacy estree AST
22+
{ key: "attributes", type: "ImportExpression" },
23+
];
24+
25+
function deeplyRemoveProperties(obj, props) {
26+
for (const [k, v] of Object.entries(obj)) {
27+
if (
28+
props.some(
29+
({ key, type }) =>
30+
key === k &&
31+
((type === "Node" && obj.type) || type === obj.type || type == null),
32+
)
33+
) {
34+
delete obj[k];
35+
continue;
36+
}
37+
38+
if (typeof v === "object") {
39+
if (Array.isArray(v)) {
40+
for (const el of v) {
41+
if (el != null) {
42+
deeplyRemoveProperties(el, props);
43+
}
44+
}
45+
}
46+
47+
if (v != null) {
48+
deeplyRemoveProperties(v, props);
49+
}
50+
}
51+
}
52+
}
53+
54+
// Only ESLint 9 or above will be tested
55+
(isESLint9 ? describe : describe.skip)(
56+
"Babel should output the same AST as TypeScript-Estree",
57+
() => {
58+
/**
59+
* @type {import("@typescript-eslint/typescript-estree")}
60+
*/
61+
let tsEstree;
62+
63+
/**
64+
* @type {import("@typescript-eslint/typescript-estree").TSESTreeOptions}
65+
*/
66+
const tsEstreeOptions = {
67+
filePath: "typescript-estree.test.js-test-input.tsx",
68+
jsx: true,
69+
tokens: true,
70+
loc: true,
71+
range: true,
72+
comment: true,
73+
sourceType: "module",
74+
};
75+
76+
function parseAndAssertSame(code, babelEcmaFeatures = null) {
77+
const tsEstreeAST = tsEstree.parse(code, tsEstreeOptions);
78+
const babelAST = parseForESLint(code, {
79+
eslintVisitorKeys: true,
80+
eslintScopeManager: true,
81+
ecmaFeatures: babelEcmaFeatures,
82+
requireConfigFile: false,
83+
babelOptions: {
84+
configFile: false,
85+
parserOpts: {
86+
plugins: ["jsx", "typescript"],
87+
},
88+
},
89+
}).ast;
90+
91+
deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE);
92+
expect(babelAST).toEqual(tsEstreeAST);
93+
}
94+
95+
beforeAll(() => {
96+
// Use the version of TS-Espree that is a dependency of
97+
// the version of typescript-eslint we are testing against.
98+
const tsEstreePath = require.resolve(
99+
"@typescript-eslint/typescript-estree",
100+
{
101+
paths: [path.dirname(require.resolve("typescript-eslint"))],
102+
},
103+
);
104+
105+
tsEstree = require(tsEstreePath);
106+
});
107+
108+
it.each([
109+
["empty", ""],
110+
111+
["boolean", "true"],
112+
["boolean", "false"],
113+
114+
["numeric", "0"],
115+
// ["bigint", "0n"],
116+
117+
["regexp without flag", `/foo/;`],
118+
["regexp u flag", `/foo/dgimsuy;`],
119+
["regexp v flag", `/foo/dgimsvy;`],
120+
121+
["logical NOT", `!0`],
122+
["bitwise NOT", `~0`],
123+
])("%s: %s", (_, input) => {
124+
parseAndAssertSame(input);
125+
});
126+
},
127+
);
128+
129+
(isESLint9 ? describe.skip : describe)(
130+
"typescript-estree test for older ESLint versions",
131+
() => {
132+
itDummy("is skipped", () => {});
133+
},
134+
);

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ __metadata:
419419
eslint-scope: "condition:BABEL_8_BREAKING ? ^7.1.1 : "
420420
eslint-visitor-keys: "condition:BABEL_8_BREAKING ? ^3.3.0 : ^2.1.0"
421421
semver: "condition:BABEL_8_BREAKING ? ^7.3.4 : ^6.3.1"
422+
typescript-eslint: "npm:8.26.1"
422423
peerDependencies:
423424
"@babel/core": ^7.11.0
424425
eslint: ^7.5.0 || ^8.0.0 || ^9.0.0

0 commit comments

Comments
 (0)