Skip to content

Commit

Permalink
Reduce false negative cases of typescript parser tests (#10979)
Browse files Browse the repository at this point in the history
* tests: read baesline errors for typescript parsing error

* chore: add error codes

* chore: tune the regex
  • Loading branch information
JLHwung authored and nicolo-ribaudo committed Jan 10, 2020
1 parent 80aa7dc commit 9fec528
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 116 deletions.
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.
"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");
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(/\.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

0 comments on commit 9fec528

Please sign in to comment.