137 lines
3.4 KiB
JavaScript
137 lines
3.4 KiB
JavaScript
const fs = require("fs").promises;
|
|
const path = require("path");
|
|
const merge = require("mergeiterator");
|
|
const TestRunner = require("../utils/parser-test-runner");
|
|
|
|
const flowOptionsMapping = {
|
|
esproposal_class_instance_fields: "classProperties",
|
|
esproposal_class_static_fields: "classProperties",
|
|
esproposal_export_star_as: "exportNamespaceFrom",
|
|
esproposal_decorators: "decorators-legacy",
|
|
esproposal_nullish_coalescing: "nullishCoalescingOperator",
|
|
esproposal_optional_chaining: "optionalChaining",
|
|
types: "flowComments",
|
|
intern_comments: false,
|
|
};
|
|
|
|
function getPlugins(test) {
|
|
const flowOptions = { all: true };
|
|
|
|
const plugins = [
|
|
"dynamicImport",
|
|
["flow", flowOptions],
|
|
"flowComments",
|
|
"jsx",
|
|
"classProperties",
|
|
"classPrivateProperties",
|
|
"classPrivateMethods",
|
|
"bigInt",
|
|
"numericSeparator",
|
|
];
|
|
|
|
if (!test.options) return plugins;
|
|
|
|
for (const [option, enabled] of Object.entries(test.options)) {
|
|
if (!enabled) {
|
|
const idx = plugins.indexOf(flowOptionsMapping[option]);
|
|
if (idx !== -1) plugins.splice(idx, 1);
|
|
} else if (option === "enums") {
|
|
flowOptions.enums = true;
|
|
} else if (!(option in flowOptionsMapping)) {
|
|
throw new Error("Parser options not mapped " + option);
|
|
} else if (flowOptionsMapping[option]) {
|
|
plugins.push(flowOptionsMapping[option]);
|
|
}
|
|
}
|
|
|
|
return plugins;
|
|
}
|
|
|
|
async function* readdirRecursive(root, dir = ".") {
|
|
const names = await fs.readdir(path.join(root, dir));
|
|
|
|
const dirs = [];
|
|
|
|
for (const name of names) {
|
|
const file = path.join(dir, name);
|
|
const stats = await fs.stat(path.join(root, file));
|
|
if (!stats.isDirectory()) {
|
|
if (!file) continue;
|
|
yield file;
|
|
} else {
|
|
dirs.push(readdirRecursive(root, file));
|
|
}
|
|
}
|
|
|
|
yield* merge(dirs);
|
|
}
|
|
|
|
async function* loadTests(root) {
|
|
for await (const file of readdirRecursive(root)) {
|
|
if (file.slice(-3) === ".js") {
|
|
const noExt = path.join(root, file).slice(0, -3);
|
|
|
|
const [contents, tree, options] = await Promise.all([
|
|
fs.readFile(noExt + ".js", "utf8"),
|
|
fs.readFile(noExt + ".tree.json", "utf8").catch(() => null),
|
|
fs.readFile(noExt + ".options.json", "utf8").catch(() => null),
|
|
]);
|
|
|
|
yield {
|
|
file,
|
|
contents,
|
|
tree: JSON.parse(tree),
|
|
options: JSON.parse(options),
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
const runner = new TestRunner({
|
|
testDir: path.join(__dirname, "../../../build/flow/src/parser/test/flow"),
|
|
allowlist: path.join(__dirname, "allowlist.txt"),
|
|
shouldUpdate: process.argv.includes("--update-allowlist"),
|
|
|
|
async *getTests() {
|
|
for await (const test of loadTests(this.testDir)) {
|
|
const shouldSuccess =
|
|
test.tree && (!test.tree.errors || !test.tree.errors.length);
|
|
|
|
yield {
|
|
contents: test.contents,
|
|
fileName: test.file,
|
|
id: test.file,
|
|
expectedError: !shouldSuccess,
|
|
plugins: getPlugins(test),
|
|
};
|
|
}
|
|
},
|
|
|
|
parse(test, parser) {
|
|
try {
|
|
parser(test.contents, {
|
|
sourceType: "module",
|
|
plugins: test.plugins,
|
|
});
|
|
} catch (e) {
|
|
// lets retry in script mode
|
|
if (!test.expectedError) {
|
|
try {
|
|
parser(test.contents, {
|
|
sourceType: "script",
|
|
plugins: test.plugins,
|
|
});
|
|
return;
|
|
} catch {}
|
|
}
|
|
|
|
throw e;
|
|
}
|
|
},
|
|
});
|
|
|
|
runner.run().catch(err => {
|
|
console.error(err);
|
|
process.exitCode = 1;
|
|
});
|