feat(coverage): support new TypeScript fixture layout (#26226)

Update the coverage harness and fixture consumers for TypeScript's merged `tsc/testdata` layout, including separate compiler and conformance baseline directories. Handle strict/checkJs baseline variants and exclude fixtures without any reference baseline. Update fixture revisions, conformance snapshots, and the existing NAPI token-test exclusion paths. Remove the temporary snapshot path translation from the parent PR.

Local conformance reproduced the updated snapshots, and all 237,025 parser NAPI tests passed with token, range/parent, and lazy-transfer modes enabled. The snapshots retain the false failures for the two TS2339 fixtures without special-case exclusions.
This commit is contained in:
camc314 committed 2026-09-18 08:35:21 +00:00
1 parent f8f31e43c3
commit 1fac65563b
35 files changed
+7511 -722

No files matched your search

+3 -3
View File
@@ -10,10 +10,10 @@ import { existsSync, mkdirSync } from "node:fs";
import { dirname, join } from "node:path";
// Submodule commit SHAs - updated automatically by .github/workflows/update_submodules.yml
const TEST262_SHA = "be13516fb6441b950ba8a3df97eb34062c186972";
const TEST262_SHA = "419d3e0a2273ba01a3bfcbec423f2801425b8e93";
const BABEL_SHA = "1eac4481473df52fbbcb452c4dca8d79039dbb63";
const TYPESCRIPT_SHA = "b465fdbfe175304d9b977da137b2c178ae1091d3";
const ESTREE_CONFORMANCE_SHA = "8d4e1faac9f350f914af9b8a6ec02c2d31ca799c";
const TYPESCRIPT_SHA = "f3b04fe05642d53b4ff126a4af05fe2587b43748";
const ESTREE_CONFORMANCE_SHA = "97c081298c39e1e698742610ddb4e981f8c26fb4";
const NODE_COMPAT_TABLE_SHA = "499beb6f1daa36f10c26b85a7f3ec3b3448ded23";
const repoRoot = join(import.meta.dirname, "..", "..");
+2 -2
View File
@@ -215,8 +215,8 @@ describeRangeParent.concurrent("range & parent TypeScript", () => {
// These fixtures' ASTs match TS-ESLint, so only their token tests are skipped.
// https://github.com/typescript-eslint/typescript-eslint/issues/12820
const TS_TOKENS_SKIP_PATHS = new Set([
"tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts.md",
"tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts.md",
"tsc/testdata/tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts.md",
"tsc/testdata/tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts.md",
]);
const tsTokensFixturePaths = tsFixturePaths.filter((path) => !TS_TOKENS_SKIP_PATHS.has(path));
+6 -7
View File
@@ -32,16 +32,15 @@ const fixturePaths = (
.flat()
.sort();
// `oxc-parser` deserializes the AST with recursive JS functions, and these fixtures nest binary
// expressions deeply enough to overflow the stack.
// They sit right on the limit, so they fail intermittently rather than every time.
// That is a limit of the parser rather than of the printer.
//
// `napi/parser`'s tests never meet them. Their TypeScript fixture list comes from the `estree-conformance` submodule,
// which holds no recording for either file.
const SKIPPED_PATHS = new Set([
// `oxc-parser` deserializes the AST with recursive JS functions, and these fixtures nest binary
// expressions deeply enough to overflow the stack. They sit right on the limit, so they fail
// intermittently rather than every time. That is a limit of the parser rather than the printer.
"compiler/binderBinaryExpressionStress.ts",
"compiler/binderBinaryExpressionStressJs.ts",
// Rust preserves the raw brace-escaped surrogate spelling, while the JS printer receives the
// decoded string value and prints the equivalent code point.
"compiler/braceEscapedSurrogatePairLiteralType.ts",
]);
describe.concurrent("TypeScript", () => {
+4 -1
View File
@@ -25,7 +25,10 @@ export const ROOT_DIR_PATH = pathJoin(import.meta.dirname, "../../../..");
// The fixture suites, all of them git submodules of this repo. `just submodules` clones them.
export const TEST262_DIR_PATH = pathJoin(ROOT_DIR_PATH, "tasks/coverage/test262/test");
export const TS_CASES_DIR_PATH = pathJoin(ROOT_DIR_PATH, "tasks/coverage/typescript/tests/cases");
export const TS_CASES_DIR_PATH = pathJoin(
ROOT_DIR_PATH,
"tasks/coverage/typescript/tsc/testdata/tests/cases",
);
export const JSX_DIR_PATH = pathJoin(
ROOT_DIR_PATH,
"tasks/coverage/estree-conformance/tests/acorn-jsx/pass",
@@ -1,5 +1,5 @@
commit: be13516f
commit: 419d3e0a
codegen_test262 Summary:
AST Parsed : 47435/47435 (100.00%)
Positive Passed: 47435/47435 (100.00%)
AST Parsed : 47440/47440 (100.00%)
Positive Passed: 47440/47440 (100.00%)
@@ -1,5 +1,7 @@
commit: b465fdbf
commit: f3b04fe0
codegen_typescript Summary:
AST Parsed : 9783/9783 (100.00%)
Positive Passed: 9783/9783 (100.00%)
AST Parsed : 9657/9657 (100.00%)
Positive Passed: 9656/9657 (99.99%)
Normal: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/braceEscapedSurrogatePairLiteralType.ts
@@ -1,4 +1,4 @@
commit: 8d4e1faa
commit: 97c08129
estree_acorn_jsx Summary:
AST Parsed : 39/39 (100.00%)
@@ -1,4 +1,4 @@
commit: 8d4e1faa
commit: 97c08129
estree_acorn_jsx_tokens Summary:
AST Parsed : 39/39 (100.00%)
+3 -3
View File
@@ -1,8 +1,8 @@
commit: be13516f
commit: 419d3e0a
estree_test262 Summary:
AST Parsed : 47433/47433 (100.00%)
Positive Passed: 47424/47433 (99.98%)
AST Parsed : 47438/47438 (100.00%)
Positive Passed: 47429/47438 (99.98%)
Mismatch: tasks/coverage/test262/test/language/expressions/assignment/fn-name-lhs-cover.js
Mismatch: tasks/coverage/test262/test/language/expressions/assignment/target-cover-id.js
@@ -1,5 +1,5 @@
commit: be13516f
commit: 419d3e0a
estree_test262_tokens Summary:
AST Parsed : 47170/47170 (100.00%)
Positive Passed: 47170/47170 (100.00%)
AST Parsed : 47175/47175 (100.00%)
Positive Passed: 47175/47175 (100.00%)
@@ -1,16 +1,36 @@
commit: b465fdbf
commit: f3b04fe0
estree_typescript Summary:
AST Parsed : 9723/9723 (100.00%)
Positive Passed: 9707/9723 (99.84%)
AST Parsed : 9578/9579 (99.99%)
Positive Passed: 9553/9579 (99.73%)
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/braceEscapedSurrogatePairLiteralType.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/extendedUnicodeEscapeSequenceIdentifiers.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/jsDeclarationEmitDoesNotReuseUnrelatedJSDocImport.ts
Fatal error: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/jsdocThisTagWithThisParameter.ts
Identifier expected. 'this' is a reserved word that cannot be used here.
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/jsxEntityDecoderAfterNonEntityAmpersand.tsx
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/jsxHexEntityUppercaseMarker.tsx
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/jsxNumericEntityLoneSurrogate.tsx
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/moduleDetectionIsolatedModulesCjsFileScope.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/moduleNodeImportRequireEmit.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/sideEffectImports2.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/taggedTemplateNestedInvalidEscape.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/tripleSlashTypesReferenceWithMissingExports.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/unicodeEscapesInNames01.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/unicodeEscapesInNames03.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/conformance/externalModules/moduleResolutionWithoutExtension7.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/conformance/externalModules/moduleResolutionWithoutExtension8.ts
@@ -1,5 +1,7 @@
commit: b465fdbf
commit: f3b04fe0
estree_typescript_tokens Summary:
AST Parsed : 9721/9721 (100.00%)
Positive Passed: 9721/9721 (100.00%)
AST Parsed : 9576/9577 (99.99%)
Positive Passed: 9576/9577 (99.99%)
Fatal error: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/jsdocThisTagWithThisParameter.ts
Identifier expected. 'this' is a reserved word that cannot be used here.
@@ -1,8 +1,8 @@
commit: be13516f
commit: 419d3e0a
formatter_test262 Summary:
AST Parsed : 47435/47435 (100.00%)
Positive Passed: 47431/47435 (99.99%)
AST Parsed : 47440/47440 (100.00%)
Positive Passed: 47436/47440 (99.99%)
Mismatch: tasks/coverage/test262/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR-LF.js
Mismatch: tasks/coverage/test262/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR.js
@@ -1,8 +1,8 @@
commit: b465fdbf
commit: f3b04fe0
formatter_typescript Summary:
AST Parsed : 9783/9783 (100.00%)
Positive Passed: 9769/9783 (99.86%)
AST Parsed : 9657/9657 (100.00%)
Positive Passed: 9643/9657 (99.86%)
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/amdLikeInputDeclarationEmit.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/commentsAfterSpread.ts
+3 -3
View File
@@ -1,5 +1,5 @@
commit: be13516f
commit: 419d3e0a
lexer_test262 Summary:
AST Parsed : 52086/52086 (100.00%)
Positive Passed: 52086/52086 (100.00%)
AST Parsed : 52093/52093 (100.00%)
Positive Passed: 52093/52093 (100.00%)
@@ -1,8 +1,8 @@
commit: b465fdbf
commit: f3b04fe0
lexer_typescript Summary:
AST Parsed : 12419/12419 (100.00%)
Positive Passed: 12416/12419 (99.98%)
AST Parsed : 12415/12415 (100.00%)
Positive Passed: 12412/12415 (99.98%)
Tokens: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/slashBeforeVariableDeclaration1.ts
Tokens: tasks/coverage/typescript/tsc/testdata/tests/cases/conformance/jsx/unicodeEscapesInJsxtags.tsx
@@ -1,8 +1,8 @@
commit: be13516f
commit: 419d3e0a
minifier_test262 Summary:
AST Parsed : 45024/45024 (100.00%)
Positive Passed: 45020/45024 (99.99%)
AST Parsed : 45029/45029 (100.00%)
Positive Passed: 45025/45029 (99.99%)
Compress: tasks/coverage/test262/test/language/statements/class/elements/private-accessor-is-visible-in-computed-properties.js
Compress: tasks/coverage/test262/test/language/statements/class/elements/private-field-is-visible-in-computed-properties.js
+20 -4
View File
@@ -1,9 +1,9 @@
commit: be13516f
commit: 419d3e0a
parser_test262 Summary:
AST Parsed : 47435/47435 (100.00%)
Positive Passed: 47435/47435 (100.00%)
Negative Passed: 4651/4651 (100.00%)
AST Parsed : 47440/47440 (100.00%)
Positive Passed: 47440/47440 (100.00%)
Negative Passed: 4653/4653 (100.00%)
× '0'-prefixed octal literals and octal escape sequences are deprecated
╭─[test262/test/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict.js:19:4]
@@ -24443,6 +24443,14 @@ Negative Passed: 4651/4651 (100.00%)
╰────
help: Quantifiers must follow an expression. To match literally, escape it with `\`
× Invalid regular expression: Numbers out of order in braced quantifier
╭─[test262/test/language/literals/regexp/invalid-quantifier-out-of-order.js:26:3]
25 │
26 │ /a{2,1}/;
· ─────
╰────
help: In `{n,m}`, the minimum `n` must be less than or equal to the maximum `m`
× Invalid regular expression: Invalid braced quantifier
╭─[test262/test/language/literals/regexp/invalid-range-lookbehind.js:21:9]
20 │
@@ -25067,6 +25075,14 @@ Negative Passed: 4651/4651 (100.00%)
╰────
help: Quantifiers must follow an expression. To match literally, escape it with `\`
× Invalid regular expression: Numbers out of order in braced quantifier
╭─[test262/test/language/literals/regexp/u-invalid-quantifier-out-of-order.js:23:3]
22 │
23 │ /a{2,1}/u;
· ─────
╰────
help: In `{n,m}`, the minimum `n` must be less than or equal to the maximum `m`
× Invalid regular expression: Lone quantifier found, expected with `Atom`
╭─[test262/test/language/literals/regexp/u-invalid-range-lookahead.js:21:8]
20 │
File diff suppressed because it is too large. Load diff
@@ -1,8 +1,8 @@
commit: be13516f
commit: 419d3e0a
semantic_test262 Summary:
AST Parsed : 47435/47435 (100.00%)
Positive Passed: 47317/47435 (99.75%)
AST Parsed : 47440/47440 (100.00%)
Positive Passed: 47322/47440 (99.75%)
semantic Error: tasks/coverage/test262/test/language/expressions/class/cpn-class-expr-fields-computed-property-name-from-arrow-function-expression.js
Scope flags mismatch:
after transform: ScopeId(2): ScopeFlags(StrictMode | Function | Arrow)
File diff suppressed because it is too large. Load diff
@@ -1,5 +1,5 @@
commit: be13516f
commit: 419d3e0a
transformer_test262 Summary:
AST Parsed : 47435/47435 (100.00%)
Positive Passed: 47435/47435 (100.00%)
AST Parsed : 47440/47440 (100.00%)
Positive Passed: 47440/47440 (100.00%)
@@ -1,8 +1,10 @@
commit: b465fdbf
commit: f3b04fe0
transformer_typescript Summary:
AST Parsed : 9783/9783 (100.00%)
Positive Passed: 9763/9783 (99.80%)
AST Parsed : 9657/9657 (100.00%)
Positive Passed: 9636/9657 (99.78%)
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/braceEscapedSurrogatePairLiteralType.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/classOverloadForFunction.ts
Mismatch: tasks/coverage/typescript/tsc/testdata/tests/cases/compiler/exportSpecifierForAGlobal.ts
@@ -1,4 +1,4 @@
commit: b465fdbf
commit: f3b04fe0
---
NOTE: If you are seeing this file with Git diffs, please follow the instructions below to review the changes.
@@ -16,6 +16,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1009
1010
1011
1012
1013
1014
1015
@@ -47,13 +48,11 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1052
1053
1054
1055
1058
1061
1062
1063
1064
1065
1066
1068
1069
@@ -114,7 +113,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1145
1146
1147
1148
1155
1156
1160
@@ -165,10 +163,8 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1214
1215
1216
1218
1221
1222
1223
1225
1228
1229
@@ -190,14 +186,11 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1247
1248
1249
1250
1251
1253
1254
1255
1257
1258
1259
1260
1262
1263
@@ -275,6 +268,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1368
1375
1378
1379
1380
1381
1382
@@ -301,10 +295,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1451
1453
1454
1455
1456
1463
1464
1470
1471
1472
@@ -338,6 +328,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1510
1511
1512
1514
1515
1516
1517
@@ -372,6 +363,11 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
1546
1547
1548
1550
1551
1555
1557
1558
2011
2206
2207
@@ -397,19 +393,16 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2320
2322
2323
2328
2331
2332
2335
2336
2337
2339
2340
2341
2343
2344
2345
2346
2347
2348
2349
@@ -440,6 +433,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2376
2377
2378
2379
2383
2384
2385
@@ -453,7 +447,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2393
2394
2395
2396
2397
2398
2401
@@ -503,10 +496,8 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2454
2456
2457
2458
2459
2460
2461
2462
2463
2464
@@ -531,8 +522,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2492
2493
2495
2496
2497
2498
2499
2500
@@ -552,7 +541,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2514
2515
2516
2522
2523
2524
2526
@@ -569,7 +557,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2540
2542
2545
2548
2550
2551
2552
@@ -602,9 +589,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2592
2593
2595
2596
2597
2598
2604
2607
2608
@@ -615,7 +600,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2614
2615
2616
2617
2628
2629
2630
@@ -634,7 +618,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2654
2655
2657
2659
2660
2661
2662
@@ -666,7 +649,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2693
2694
2695
2696
2698
2699
2700
@@ -696,7 +678,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2729
2730
2731
2732
2736
2737
2739
@@ -729,20 +710,19 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2786
2790
2791
2792
2795
2796
2797
2799
2800
2801
2802
2803
2804
2806
2807
2808
2809
2810
2812
2813
2814
@@ -763,14 +743,12 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
2845
2846
2848
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
@@ -795,6 +773,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
4023
4025
4032
4060
4081
4094
4104
@@ -815,20 +794,16 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
4123
5009
5011
5023
5024
5052
5053
5055
5056
5059
5061
5062
5063
5064
5066
5067
5069
5070
5071
5074
5076
5085
@@ -839,20 +814,13 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
5091
5095
5097
5098
5101
5102
5103
5105
5107
5108
5109
5110
6046
6053
6054
6059
6082
6131
6133
6137
6138
@@ -863,14 +831,13 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
6196
6198
6199
6200
6205
6229
6231
6232
6234
6263
6379
6424
6504
6807
7005
@@ -878,9 +845,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
7008
7009
7010
7012
7013
7014
7015
7016
7017
@@ -912,6 +877,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
7059
7060
7061
7080
8002
8003
8004
@@ -926,8 +892,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
8016
8017
8020
8021
8022
8023
8024
8026
@@ -938,8 +902,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
8037
8038
8039
9005
9006
9007
9008
9009
@@ -956,6 +918,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
9021
9022
9023
9025
9026
9037
9038
@@ -991,7 +954,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
18024
18026
18027
18028
18029
18030
18033
@@ -1001,7 +963,6 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
18041
18042
18043
18045
18046
18047
18048
@@ -1014,4 +975,7 @@ Q. Is it possible for `oxc_parser` to detect and report this error during static
18058
18059
18060
18061
18061
18062
18063
18064
+1 -5
View File
@@ -290,10 +290,6 @@ pub fn snapshot_results(name: &str, test_root: &Path, results: &[CoverageResult]
}
}
// Use the upcoming TypeScript fixture layout in snapshots while still loading the old layout.
// Normalize the complete output so paths embedded in diagnostics are updated too.
let out = out.replace("typescript/tests/", "typescript/tsc/testdata/tests/");
let path = snap_root().join(format!("{}.snap", name.to_lowercase()));
snapshot.save(&path, &out);
}
@@ -312,7 +308,7 @@ pub struct AppArgs {
const TEST262_PATH: &str = "test262/test";
const BABEL_PATH: &str = "babel/packages/babel-parser/test/fixtures";
const TYPESCRIPT_PATH: &str = "typescript/tests/cases";
const TYPESCRIPT_PATH: &str = typescript::CASES_PATH;
const MISC_PATH: &str = "misc";
const ESTREE_ACORN_JSX_PATH: &str = "estree-conformance/tests/acorn-jsx";
+4 -1
View File
@@ -208,8 +208,11 @@ fn load_typescript(filter: Option<&str>) -> Vec<TypeScriptFile> {
!supported || unsupported
};
walk_and_read(Path::new("typescript/tests/cases"), filter, skip_path)
let files = walk_and_read(Path::new(typescript::CASES_PATH), filter, skip_path);
let reference_baselines = typescript::ReferenceBaselines::new();
files
.into_par_iter()
.filter(|(path, _)| reference_baselines.contains(path))
.map(|(path, code)| {
let content = typescript::meta::TestCaseContent::make_units_from_test(&path, &code);
let should_fail = content
+1 -1
View File
@@ -23,7 +23,7 @@ fn main() {
std::thread::available_parallelism().map_or(1, NonZeroUsize::get)
};
// Match Linux's default main-thread stack (8 MB) so deeply-nested expressions
// (e.g. typescript/tests/cases/compiler/binderBinaryExpressionStressJs.ts)
// (e.g. typescript/tsc/testdata/tests/cases/compiler/binderBinaryExpressionStressJs.ts)
// don't overflow macOS's 2 MB worker default.
ThreadPoolBuilder::new()
.num_threads(thread_count)
+8 -7
View File
@@ -899,12 +899,13 @@ fn run_estree_acorn_jsx_impl(
// Skip paths for TypeScript ESTree tests
static TS_SKIP_PATHS: &[&str] = &[
// Skip cases which are failing in parser conformance tests
"typescript/tests/cases/compiler/arrayFromAsync.ts",
"typescript/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts",
"typescript/tests/cases/conformance/es2019/importMeta/importMeta.ts",
"typescript/tests/cases/conformance/esDecorators/esDecorators-decoratorExpression.1.ts",
"typescript/tsc/testdata/tests/cases/compiler/arrayFromAsync.ts",
"typescript/tsc/testdata/tests/cases/compiler/regexInvalidUtf8WithUnicodeFlag.ts",
"typescript/tsc/testdata/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts",
"typescript/tsc/testdata/tests/cases/conformance/es2019/importMeta/importMeta.ts",
"typescript/tsc/testdata/tests/cases/conformance/esDecorators/esDecorators-decoratorExpression.1.ts",
// Skip tests where TS-ESLint is incorrect
"typescript/tests/cases/conformance/es6/templates/templateStringMultiline3.ts",
"typescript/tsc/testdata/tests/cases/conformance/es6/templates/templateStringMultiline3.ts",
];
// Additional skip paths for the TypeScript ESTree *token* tests.
@@ -913,8 +914,8 @@ static TS_TOKENS_SKIP_PATHS: &[&str] = &[
// TS-ESLint drops the first `<` of a `<<` which opens a type argument list,
// e.g. `ReturnType<<T>(x: T) => number>`. Oxc correctly emits both `<` tokens.
// <https://github.com/typescript-eslint/typescript-eslint/issues/12820>
"typescript/tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts",
"typescript/tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts",
"typescript/tsc/testdata/tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts",
"typescript/tsc/testdata/tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts",
];
pub fn run_estree_typescript(files: &[TypeScriptFile]) -> Vec<CoverageResult> {
@@ -167,6 +167,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"1361", // 'D' cannot be used as a value because it was imported using 'import type'.
"1362", // 'Foo' cannot be used as a value because it was exported using 'export type'.
"1378", // Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
"1379", // An import alias cannot reference a declaration that was exported using 'export type'.
"1380", // An import alias cannot reference a declaration that was imported using 'import type'.
"1432", // Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
"1448", // 'CC' resolves to a type-only declaration and must be re-exported using a type-only re-export when 'isolatedModules' is enabled.
@@ -235,6 +236,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"2367", // This comparison appears to be unintentional because the types '0' and '1' have no overlap.
"2370", // A rest parameter must be of an array type.
"2375", // Type '{ value: undefined; }' is not assignable to type 'A' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
"2379", // Argument of type '{ y: undefined; }' is not assignable to parameter of type '{ y?: string; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
"2403", // Subsequent variable declarations must have the same type. Variable 'x' must be of type 'any', but here has type 'any[]'.
"2407", // The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'Color.Blue'.
"2409", // Return type of constructor signature must be assignable to the instance type of the class.
@@ -441,6 +443,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"2806", // Private accessor was defined without a getter.
"2807", // This syntax requires an imported helper named '__spreadArray' with 3 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'.
"2808", // A get accessor must be at least as accessible as the setter
"2810", // Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.
"2812", // Property 'textContent' does not exist on type 'Element'. Try changing the 'lib' compiler option to include 'dom'.
"2813", // Class declaration cannot implement overload list for 'c2'.
"2814", // Function with bodies can only merge with classes that are ambient.
@@ -486,6 +489,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"4023", // Exported variable 'foo' has or is using name 'Foo' from external module "type" but cannot be named.
"4025", // Exported variable 'b' has or is using private name 'a'.
"4032", // Property 'val' of exported interface has or is using name 'I' from private module '"a"'.
"4060", // Return type of exported function has or is using private name 'T'.
"4081", // Exported type alias 'MyClass' has or is using private name 'myClass'.
"4094", // Property '_assertIsStripped' of exported anonymous class type may not be private or protected.
"4104", // The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.
@@ -505,6 +509,8 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"4122", // This member cannot have a JSDoc comment with an '@override' tag because it is not declared in the base class 'A'.
"4123", // This member cannot have a JSDoc comment with an 'override' tag because it is not declared in the base class 'A'. Did you mean 'doSomething'?
"5009", // Cannot find the common subdirectory path for the input files.
"5023", // Unknown compiler option 'noImplicitUseStrict'.
"5024", // Compiler option 'files' requires a value of type Array.
"5052", // Option 'checkJs' cannot be specified without specifying option 'allowJs'.
"5053", // Option 'mapRoot' cannot be specified with option 'inlineSourceMap'.
"5055", // Cannot write file 'a.d.ts' because it would overwrite input file.
@@ -534,6 +540,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"5108", // Option 'target=ES3' has been removed. Please remove it from your configuration.
"5109", // Option 'moduleResolution' must be set to 'Node16' (or left unspecified) when option 'module' is set to 'Node18'.
"5110", // Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
"6046", // Argument for '--target' option must be: 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'es2022', 'es2023', 'es2024', 'es2025', 'esnext'.
"6053", // File 'invalid.ts' not found.
"6054", // File 'b.js.map' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'.
"6082", // Only 'amd' and 'system' modules are supported alongside --outFile.
@@ -554,6 +561,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"6234", // This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
"6263", // Module './dir/native.node' was resolved to 'dir/native.d.node.ts', but '--allowArbitraryExtensions' is not set.
"6379", // Composite projects may not disable incremental compilation.
"6424", // Multiple 'module.exports' assignments cannot be serialized for declaration emit.
"7005", // Variable 'x' implicitly has an 'any' type.
"7006", // Parameter 'x' implicitly has an 'any' type.
"7008", // Member 'v' implicitly has an 'any' type.
@@ -590,6 +598,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"7055", // 'h', which lacks return-type annotation, implicitly has an 'any' yield type.
"7056", // The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.
"7057", // 'yield' expression implicitly results in an 'any' type because its containing generator lacks a return-type annotation.
"7080", // Declaration emit elides private members, but '#a' refers to a private member. Write an explicit type here.
"8021", // JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.
"8022", // JSDoc '@extends' is not attached to a class.
"8023", // JSDoc '@extends Mismatch' does not match the 'extends B' clause.
@@ -618,6 +627,7 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"9021", // ExtenDeclads clause can't contain an expression with --isolatedDeclarations.
"9022", // InferDeclaence from class expressions is not supported with --isolatedDeclarations.
"9023", // AssigDeclaning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.
"9025", // Declaration emit for this parameter requires implicitly adding undefined to its type. This is not supported with --isolatedDeclarations.
"9026", // DeclaDeclaration emit for this file requires preserving this import for augmentations. This is not supported with --isolatedDeclarations.
"9037", // DefauDeclalt exports can't be inferred with --isolatedDeclarations.
"9038", // CompuDeclated property names on class or object literals cannot be inferred with --isolatedDeclarations.
@@ -636,6 +646,8 @@ pub static NOT_SUPPORTED_ERROR_CODES: phf::Set<&'static str> = phf::phf_set![
"18049", // 'x' is possibly 'null' or 'undefined'.
"18055", // 'A.a' has a string type, but must have syntactically recognizable string syntax when 'isolatedModules' is enabled.
"18057", // String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'.
"18062", // Regular expression pattern modifiers are only available when targeting 'es2025' or later.
"18063", // Duplicate named capturing groups are only available when targeting 'es2025' or later.
];
// spellchecker:on
@@ -4,13 +4,14 @@ use oxc_tasks_common::Snapshot;
use rustc_hash::{FxHashMap, FxHashSet};
use walkdir::WalkDir;
use super::{BASELINES_PATH, CASES_PATH};
use crate::{snap_root, workspace_root};
const TESTS_ROOT: &str = "typescript/tests";
const TYPESCRIPT_REPO_PATH: &str = "typescript";
pub fn save_reviewed_tsc_diagnostics_codes() {
// Collected codes are based on current TypeScript version in submodule.
let snapshot = Snapshot::new(&workspace_root().join(TESTS_ROOT), true);
let snapshot = Snapshot::new(&workspace_root().join(TYPESCRIPT_REPO_PATH), true);
let mut contents = vec![];
contents.extend([
@@ -32,12 +33,10 @@ pub fn save_reviewed_tsc_diagnostics_codes() {
}
fn collect_diagnostics_codes() -> Vec<u32> {
let ts_repo_dir = workspace_root().join(TESTS_ROOT);
let baselines_dir = ts_repo_dir.join("baselines/reference");
let baselines_dir = workspace_root().join(BASELINES_PATH);
// First, collect all `.errors.txt` files from `tests/baselines/reference`.
// At this point, snapshots for tests other than `compiler` and `conformance` are also included.
// NOTE: Some `.errors.txt` files are located in subdirectories, but we do not need them
// First, collect all `.errors.txt` files from `testdata/baselines/reference`.
// Baselines are grouped by the `compiler` and `conformance` suites.
let all_errors_text_paths = collect_errors_txt_files(&baselines_dir);
// Each test case refers to a `.errors.txt` file with the same name as the test file.
@@ -48,8 +47,9 @@ fn collect_diagnostics_codes() -> Vec<u32> {
errors_map.entry(test_id).or_default().push(errors_text_path);
}
// Now, collect all test files from `tests/cases/compiler` and `tests/cases/conformance`.
let all_test_paths = collect_test_files(&ts_repo_dir.join("cases"));
// Now, collect all test files from `testdata/tests/cases/compiler` and
// `testdata/tests/cases/conformance`.
let all_test_paths = collect_test_files(&workspace_root().join(CASES_PATH));
// If the test is expected to produce an error, a `.errors.txt` file should exist.
// Keep `.errors.txt` files that have a corresponding test file.
@@ -87,14 +87,18 @@ fn collect_diagnostics_codes() -> Vec<u32> {
fn collect_errors_txt_files(baselines_dir: &Path) -> Vec<String> {
let mut files = Vec::new();
if let Ok(entries) = fs::read_dir(baselines_dir) {
for entry in entries.flatten() {
if let Ok(file_type) = entry.file_type()
&& !file_type.is_dir()
&& let Some(file_name) = entry.file_name().to_str()
&& file_name.ends_with(".errors.txt")
for dir_name in ["compiler", "conformance"] {
let dir_path = baselines_dir.join(dir_name);
for entry in WalkDir::new(&dir_path)
.into_iter()
.filter_map(Result::ok)
.filter(|entry| !entry.file_type().is_dir())
{
if let Ok(relative_path) = entry.path().strip_prefix(baselines_dir)
&& let Some(path_str) = relative_path.to_str()
&& path_str.ends_with(".errors.txt")
{
files.push(file_name.to_string());
files.push(path_str.to_string());
}
}
}
@@ -161,6 +165,8 @@ const SUPPORTED_VARIANTS: &[&str] = &[
"module=",
"target=",
"jsx=",
"checkjs=true",
"strict=true",
"preserveconstenums=",
"usedefineforclassfields=",
"experimentaldecorators=",
+17 -6
View File
@@ -14,7 +14,7 @@ use oxc::{
span::{SourceType, Span},
};
use crate::workspace_root;
use super::baseline_root;
// Returns a match for a test option. Test options have the form `// @name: value`
static META_OPTIONS: Lazy<Regex> = lazy_regex!(
@@ -31,7 +31,8 @@ static TS_IGNORE_PATTERN: Lazy<Regex> = lazy_regex!(r"(?://|/\*).*?(@ts-ignore|@
pub struct CompilerSettings {
pub modules: Vec<String>,
pub targets: Vec<String>,
pub strict: bool,
pub strict: Vec<bool>,
pub check_js: Vec<bool>,
pub jsx: Vec<String>, // 'react', 'preserve'
pub declaration: bool,
pub emit_declaration_only: bool,
@@ -50,7 +51,8 @@ impl CompilerSettings {
Self {
modules: Self::split_value_options(options.get("module")),
targets: Self::split_value_options(options.get("target")),
strict: Self::value_to_boolean(options.get("strict"), false),
strict: Self::split_boolean_options(options.get("strict"), false),
check_js: Self::split_boolean_options(options.get("checkjs"), false),
jsx: Self::split_value_options(options.get("jsx")),
declaration: Self::value_to_boolean(options.get("declaration"), false),
emit_declaration_only: Self::value_to_boolean(
@@ -192,8 +194,8 @@ impl TestCaseContent {
let test_unit_data = test_unit_data
.into_iter()
// Some snapshot units contain an invalid file with just a message, not even a comment!
// e.g. typescript/tests/cases/compiler/extendsUntypedModule.ts
// e.g. typescript/tests/cases/conformance/moduleResolution/untypedModuleImport.ts
// e.g. typescript/tsc/testdata/tests/cases/compiler/extendsUntypedModule.ts
// e.g. typescript/tsc/testdata/tests/cases/conformance/moduleResolution/untypedModuleImport.ts
// Based on some config, it's not expected to be read in the first place.
.filter(|unit| {
// `unit.content.trim().starts_with()` is insufficient when dealing with the first unit.
@@ -355,17 +357,26 @@ impl TestCaseContent {
}
let file_name = path.file_stem().unwrap().to_string_lossy();
let root = workspace_root().join("typescript/tests/baselines/reference");
let root = baseline_root(path);
let mut suffixes = vec![];
// TypeScript writes baseline suffixes in alphabetical key order, e.g.
// `(alwaysstrict=true,target=es5).errors.txt`. Keep the same ordering here so
// the lookup matches.
suffixes.extend(create_suffixes("alwaysstrict", &options.always_strict));
// `checkJs` only changes checker diagnostics, not parser diagnostics. When a test
// requests both variants, use the enabled baseline as the representative variant.
if options.check_js.len() > 1 && options.check_js.contains(&true) {
suffixes.push(vec!["checkjs=true".to_string()]);
}
suffixes
.extend(create_suffixes("experimentaldecorators", &options.experimental_decorators));
suffixes.extend(create_suffixes("jsx", &options.jsx));
suffixes.extend(create_suffixes("module", &options.modules));
suffixes.extend(create_suffixes("preserveconstenums", &options.preserve_const_enums));
// As with `checkJs`, use the enabled baseline when both `strict` variants are present.
if options.strict.len() > 1 && options.strict.contains(&true) {
suffixes.push(vec!["strict=true".to_string()]);
}
suffixes.extend(create_suffixes("target", &options.targets));
suffixes.extend(create_suffixes(
"usedefineforclassfields",
+82
View File
@@ -1,3 +1,12 @@
use std::{
fs,
path::{Path, PathBuf},
};
use rustc_hash::{FxHashMap, FxHashSet};
use crate::workspace_root;
pub mod constants;
mod diagnostics_code_collector;
pub mod error_baseline;
@@ -7,3 +16,76 @@ pub mod transpile_runner;
pub mod type_symbol_baseline;
pub use diagnostics_code_collector::save_reviewed_tsc_diagnostics_codes;
pub const CASES_PATH: &str = "typescript/tsc/testdata/tests/cases";
pub const BASELINES_PATH: &str = "typescript/tsc/testdata/baselines/reference";
pub fn baseline_root(test_path: &Path) -> PathBuf {
let mut components = test_path.components();
components
.find(|component| component.as_os_str() == "cases")
.expect("TypeScript test path should contain `cases`");
let suite = components.next().expect("TypeScript test path should contain a suite");
workspace_root().join(BASELINES_PATH).join(suite)
}
/// Tests for which upstream actually produced a reference baseline. Native TSC leaves skipped
/// fixtures in the cases directory, so a missing error baseline alone does not imply success.
pub struct ReferenceBaselines(FxHashMap<PathBuf, FxHashSet<String>>);
impl ReferenceBaselines {
pub fn new() -> Self {
let suites = ["compiler", "conformance"]
.into_iter()
.map(|suite| {
let root = workspace_root().join(BASELINES_PATH).join(suite);
let tests = fs::read_dir(&root)
.expect("TypeScript reference baselines should exist")
.map(|entry| entry.expect("TypeScript reference baseline should be readable"))
.filter_map(|entry| {
let name = entry.file_name();
reference_test_name(name.to_str()?).map(str::to_owned)
})
.collect();
(root, tests)
})
.collect();
Self(suites)
}
pub fn contains(&self, test_path: &Path) -> bool {
let Some(name) = test_path.file_stem().and_then(|name| name.to_str()) else {
return false;
};
self.0.get(&baseline_root(test_path)).is_some_and(|tests| tests.contains(name))
}
}
fn reference_test_name(name: &str) -> Option<&str> {
let stem = [
".errors.txt",
".trace.json",
".sourcemap.txt",
".js.map",
".js",
".types",
".symbols",
".contentmapper",
]
.into_iter()
.find_map(|suffix| name.strip_suffix(suffix))?;
Some(stem.split_once('(').map_or(stem, |(name, _)| name))
}
#[test]
fn reference_baseline_names() {
assert_eq!(reference_test_name("decoratorOnClass6.es6.js"), Some("decoratorOnClass6.es6"));
assert_eq!(
reference_test_name("example(strict=true,target=es2015).errors.txt"),
Some("example")
);
assert_eq!(reference_test_name("example.js.map"), Some("example"));
assert_eq!(reference_test_name("example.types"), Some("example"));
assert_eq!(reference_test_name("example.trace.json"), Some("example"));
assert_eq!(reference_test_name("example.ts"), None);
}
@@ -13,21 +13,22 @@ use oxc::{
use rayon::prelude::*;
use walkdir::WalkDir;
use super::meta::{Baseline, BaselineFile, TestCaseContent};
use super::{
BASELINES_PATH, CASES_PATH,
meta::{Baseline, BaselineFile, TestCaseContent},
};
use crate::{CoverageResult, TestResult, print_coverage, snapshot_results, workspace_root};
const TESTS_ROOT: &str = "typescript/tests";
pub fn run(filter: Option<&str>, detail: bool) {
let results = run_transpile(filter);
print_coverage("transpile", &results, detail);
if filter.is_none() {
snapshot_results("transpile", Path::new("typescript/tests/cases/transpile"), &results);
snapshot_results("transpile", &Path::new(CASES_PATH).join("transpile"), &results);
}
}
fn run_transpile(filter: Option<&str>) -> Vec<CoverageResult> {
let test_root = workspace_root().join(TESTS_ROOT).join("cases").join("transpile");
let test_root = workspace_root().join(CASES_PATH).join("transpile");
let paths: Vec<_> = WalkDir::new(&test_root)
.into_iter()
@@ -60,12 +61,10 @@ fn run_transpile(filter: Option<&str>) -> Vec<CoverageResult> {
fn compare_baseline(path: &Path, content: &TestCaseContent) -> TestResult {
// Get expected baseline
let rel_path = path
.strip_prefix(workspace_root().join(TESTS_ROOT).join("cases/transpile"))
.unwrap_or(path);
let rel_path =
path.strip_prefix(workspace_root().join(CASES_PATH).join("transpile")).unwrap_or(path);
let filename = change_extension(rel_path.to_str().unwrap_or_default());
let baseline_path =
workspace_root().join(TESTS_ROOT).join("baselines/reference/transpile").join(&filename);
let baseline_path = workspace_root().join(BASELINES_PATH).join("transpile").join(&filename);
let expected = BaselineFile::parse(&baseline_path);
let actual = run_isolated_declarations(path, content);
@@ -26,10 +26,13 @@ use oxc::{
use rayon::prelude::*;
use similar::{ChangeTag, TextDiff};
use super::scanner::{
self, BRACKET_LINE, LINE_DELIMITER, full_start, line_and_character, line_of_position,
use super::{
baseline_root,
scanner::{
self, BRACKET_LINE, LINE_DELIMITER, full_start, line_and_character, line_of_position,
},
};
use crate::{CoverageResult, TestResult, TypeScriptFile, workspace_root};
use crate::{CoverageResult, TestResult, TypeScriptFile};
/// Emitted for nodes oxc cannot resolve (members, `this`/`super`, lib globals) and for every
/// node in the `.types` scaffold. Must never equal a real `Symbol(...)` or type string.
@@ -197,10 +200,10 @@ fn iterate_unit(unit_name: &str, content: &str, results: &[TypeWriterResult]) ->
out
}
/// The `tests/cases/...` header path (strips the leading `typescript/` component).
/// The `tests/cases/...` header path (strips the repository and testdata components).
fn header_path(path: &Path) -> String {
let s = path.to_string_lossy();
s.strip_prefix("typescript/").unwrap_or(&s).to_string()
s.strip_prefix("typescript/tsc/testdata/").unwrap_or(&s).to_string()
}
/// Port of `generateBaseline`: walk every unit, emit the `//// [path] ////` header + sections.
@@ -305,9 +308,7 @@ fn run_baseline(files: &[TypeScriptFile], kind: BaselineKind) -> Vec<CoverageRes
return None;
}
let stem = Path::new(&f.path).file_stem()?.to_string_lossy().into_owned();
let baseline_path = workspace_root()
.join("typescript/tests/baselines/reference")
.join(format!("{stem}.{ext}"));
let baseline_path = baseline_root(&f.path).join(format!("{stem}.{ext}"));
// Only score files that ship a baseline of this kind.
let baseline = std::fs::read_to_string(&baseline_path).ok()?;
@@ -14,10 +14,10 @@ import { dirname, extname, join } from "path";
const __dirname = new URL(".", import.meta.url).pathname;
// https://github.com/microsoft/TypeScript/blob/8da951cbb629b648753454872df4e1754982aef1/tests/cases/conformance/decorators/class
// https://github.com/microsoft/TypeScript/blob/0e32aa196a8f1814fb6a4fa294e2f49029d6de88/tsc/testdata/tests/cases/conformance/decorators/class
const typescriptTestFolderPath = join(
__dirname,
"../../../../../coverage/typescript/tests/cases/conformance/decorators/class",
"../../../../../coverage/typescript/tsc/testdata/tests/cases/conformance/decorators/class",
);
const oxcTestFolderPath = join(__dirname, "typescript");