Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce false negative cases of typescript parser tests #10979

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
71 changes: 71 additions & 0 deletions scripts/parser-tests/typescript/error-codes.js
@@ -0,0 +1,71 @@
/*
This file includes the code of TS Diagnostics error that should also be thrown from babel-parser.
The TypeScript parser is highly tolerant on errors so these error would not produce parseDiagnostics which can be checked
in the parser test runner. We check these error codes against the stderr log in the build/typescript/tests/baselines/reference

Note that babel-parser should not throw for the TypeChecking Diagnostics

The commented out diagnostic codes will introduce false positive cases that should be addressed in separate PRs.
*/

module.exports = [
// "TS1005", // '{0}' expected.
"TS1009", // Trailing comma not allowed.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeScript does not push parseDiagnostics for all and not limited to these errors. 🤷

"TS1014", // A rest parameter must be last in a parameter list.
"TS1019", // An index signature parameter cannot have a question mark.
"TS1028", // Accessibility modifier already seen.
"TS1029", // '{0}' modifier must precede '{1}' modifier.
"TS1030", // '{0}' modifier already seen.
"TS1031", // '{0}' modifier cannot appear on a class element.
"TS1042", // '{0}' modifier cannot be used here.
"TS1048", // A rest parameter cannot have an initializer.
"TS1053", // A 'set' accessor cannot have rest parameter.
"TS1054", // A 'get' accessor cannot have parameters.
// "TS1071", // '{0}' modifier cannot appear on an index signature.
"TS1089", // '{0}' modifier cannot appear on a constructor declaration.
"TS1090", // '{0}' modifier cannot appear on a parameter.
"TS1100", // Invalid use of 'arguments' in strict mode.
"TS1101", // 'with' statements are not allowed in strict mode.
"TS1104", // A 'continue' statement can only be used within an enclosing iteration statement.
"TS1105", // A 'break' statement can only be used within an enclosing iteration or switch statement.
"TS1107", // Jump target cannot cross function boundary.
"TS1108", // A 'return' statement can only be used within a function body.
"TS1113", // A 'default' clause cannot appear more than once in a 'switch' statement.
"TS1115", // A 'continue' statement can only jump to a label of an enclosing iteration statement.
"TS1116", // A 'break' statement can only jump to a label of an enclosing statement.
"TS1123", // Variable declaration list cannot be empty.
"TS1141", // String literal expected.
"TS1142", // Line break not permitted here.
"TS1162", // An object member cannot be declared optional.
"TS1163", // A 'yield' expression is only allowed in a generator body.
"TS1184", // Modifiers cannot appear here.
"TS1191", // An import declaration cannot have modifiers.
"TS1196", // Catch clause variable cannot have a type annotation.
"TS1197", // Catch clause variable cannot have an initializer.
"TS1200", // Line terminator not permitted before arrow.
"TS1312", // '=' can only be used in an object literal property inside a destructuring assignment.
// "TS1212", // Identifier expected. '{0}' is a reserved word in strict mode."
// "TS1213", // Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.
// "TS1214", // Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.
"TS1246", // An interface property cannot have an initializer.
"TS1247", // A type literal property cannot have an initializer.
"TS1248", // A class member cannot have the 'const' keyword.
"TS1308", // 'await' expression is only allowed within an async function.
"TS2337", // Super calls are not permitted outside constructors or in nested functions inside constructors.
// "TS2300", // Duplicate identifier '{0}'.
"TS2364", // The left-hand side of an assignment expression must be a variable or a property access.
// "TS2371", // A parameter initializer is only allowed in a function or constructor implementation.
// "TS2393", // Duplicate function implementation.
"TS2396", // Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters.
// "TS2440", // Import declaration conflicts with local declaration of '{0}'.
// "TS2451", // Cannot redeclare block-scoped variable '{0}'.
"TS2452", // An enum member cannot have a numeric name.
"TS2566", // A rest element cannot have a property name.
"TS2481", // Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{0}'.
// "TS2567", // Enum declarations can only merge with namespace or other enum declarations.
"TS2659", // 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher.
"TS2660", // 'super' can only be referenced in members of derived classes or object literal expressions.
"TS2699", // Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'.
"TS8018", // Octal literals are not allowed in enums members initializer.
// "TS17012", // '{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?
];
35 changes: 29 additions & 6 deletions scripts/parser-tests/typescript/index.js
@@ -1,7 +1,8 @@
const path = require("path");
const fs = require("fs").promises;
const ts = require("typescript");
const ts = require("../../../build/typescript");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the bundled typescript bin since the dev dependency could be out-of-dated.

const TestRunner = require("../utils/parser-test-runner");
const parsingErrorCodes = require("./error-codes");

async function* loadTests(dir) {
const names = await fs.readdir(dir);
Expand All @@ -20,18 +21,38 @@ const plugins = [
"dynamicImport",
];

const TSTestsPath = path.join(__dirname, "../../../build/typescript/tests");

// Check if the baseline errors contain the codes that should also be thrown from babel-parser
async function baselineContainsParserErrorCodes(testName) {
try {
const baselineErrors = await fs.readFile(
path.join(
TSTestsPath,
"baselines/reference",
testName.replace(/\.ts|\.tsx/, ".errors.txt")
),
"utf8"
);
return parsingErrorCodes.some(code => baselineErrors.includes(code));
} catch (e) {
if (e.code !== "ENOENT") {
throw e;
}
return false;
}
}

const runner = new TestRunner({
testDir: path.join(
__dirname,
"../../../build/typescript/tests/cases/compiler"
),
testDir: path.join(TSTestsPath, "./cases/compiler"),
whitelist: path.join(__dirname, "whitelist.txt"),
logInterval: 50,
shouldUpdate: process.argv.includes("--update-whitelist"),

async *getTests() {
for await (const test of loadTests(this.testDir)) {
const isTSX = test.name.slice(-4) === ".tsx";

const ast = ts.createSourceFile(
test.name,
test.contents,
Expand All @@ -44,7 +65,9 @@ const runner = new TestRunner({
contents: test.contents,
fileName: test.name,
id: test.name,
expectedError: ast.parseDiagnostics.length > 0,
expectedError:
ast.parseDiagnostics.length > 0 ||
(await baselineContainsParserErrorCodes(test.name)),
sourceType: "module",
plugins: isTSX ? plugins.concat("jsx") : plugins,
};
Expand Down