mirror of
https://github.com/hanzoai/babel.git
synced 2026-09-24 16:56:45 +00:00
* test: migrate regenerator test runner to jest * perf: parallelize the test tasks * fix: specify test runner and environment * Revert "perf: parallelize the test tasks" This reverts commit 2de536c1e5a1a190ffefd22e4153fdce5c2f9534. * chore: add comment why these tests can not be parallelized * remove yargs resolution * override c8/yargs resolution * refactor: programmatically run Jest tests * update jest versions
381 lines
11 KiB
JavaScript
381 lines
11 KiB
JavaScript
/**
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import {
|
|
readFile,
|
|
writeFileSync,
|
|
copyFileSync,
|
|
mkdirSync,
|
|
readFileSync,
|
|
} from "node:fs";
|
|
import { join } from "node:path";
|
|
import { spawn } from "node:child_process";
|
|
import { transformSync } from "@babel/core";
|
|
import checkDuplicatedNodes from "@babel/helper-check-duplicate-nodes";
|
|
|
|
import { commonJS } from "$repo-utils";
|
|
|
|
import pluginTransformRegenerator from "../lib/index.js";
|
|
|
|
import pluginTransformClasses from "@babel/plugin-transform-classes";
|
|
import pluginTransformForOf from "@babel/plugin-transform-for-of";
|
|
import pluginTransformBlockScoping from "@babel/plugin-transform-block-scoping";
|
|
import pluginTransformArrowFunctions from "@babel/plugin-transform-arrow-functions";
|
|
import pluginTransformParameters from "@babel/plugin-transform-parameters";
|
|
import pluginProposalFunctionSent from "@babel/plugin-proposal-function-sent";
|
|
import * as jest from "jest";
|
|
|
|
const { __dirname } = commonJS(import.meta.url);
|
|
|
|
// https://github.com/facebook/regenerator/blob/cb755fd82c648cbc5307a5a2d61cdd598e698fc4/packages/preset/index.js#L9
|
|
const regeneratorPreset = [
|
|
pluginProposalFunctionSent,
|
|
pluginTransformClasses,
|
|
pluginTransformArrowFunctions,
|
|
pluginTransformBlockScoping,
|
|
pluginTransformForOf,
|
|
pluginTransformRegenerator,
|
|
];
|
|
|
|
function convert(es6File, es5File, callback) {
|
|
const transformOptions = {
|
|
plugins: regeneratorPreset,
|
|
parserOpts: {
|
|
strictMode: false,
|
|
},
|
|
ast: true,
|
|
configFile: false,
|
|
};
|
|
|
|
readFile(join(__dirname, es6File), "utf-8", function (err, es6) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
|
|
const { code: es5, ast } = transformSync(es6, transformOptions);
|
|
writeFileSync(join(__dirname, es5File), es5);
|
|
try {
|
|
checkDuplicatedNodes(ast);
|
|
} catch (err) {
|
|
err.message =
|
|
"Occurred while transforming: " + es6File + "\n" + err.message;
|
|
throw err;
|
|
}
|
|
callback();
|
|
});
|
|
}
|
|
|
|
function convertOldHelper(es6File, es5File, callback) {
|
|
const transformOptions = {
|
|
plugins: regeneratorPreset,
|
|
parserOpts: {
|
|
strictMode: false,
|
|
},
|
|
ast: true,
|
|
configFile: false,
|
|
};
|
|
|
|
readFile(join(__dirname, es6File), "utf-8", function (err, es6) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
|
|
let es5, ast;
|
|
process.env.FORCE_OLD_REGENERATOR = true;
|
|
try {
|
|
({ code: es5, ast } = transformSync(es6, transformOptions));
|
|
} finally {
|
|
delete process.env.FORCE_OLD_REGENERATOR;
|
|
}
|
|
writeFileSync(join(__dirname, es5File), es5);
|
|
try {
|
|
checkDuplicatedNodes(ast);
|
|
} catch (err) {
|
|
err.message =
|
|
"Occurred while transforming: " + es6File + "\n" + err.message;
|
|
throw err;
|
|
}
|
|
callback();
|
|
});
|
|
}
|
|
|
|
function enqueue(cmd, args = []) {
|
|
describe("regenerator", () => {
|
|
if (typeof cmd === "function") {
|
|
it(`${cmd.name} (${args.join(", ")})`, () =>
|
|
new Promise((resolve, reject) =>
|
|
cmd(...args, err => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve();
|
|
}
|
|
}),
|
|
));
|
|
} else if (cmd === "jest") {
|
|
// Matches https://github.com/facebook/regenerator/blob/cb755fd82c648cbc5307a5a2d61cdd598e698fc4/.github/workflows/node.js.yml#L19
|
|
describe("jest", () => {
|
|
const testFiles = args.map(file => join(__dirname, file));
|
|
it(`${args.join(" ")}`, async () => {
|
|
const options = {
|
|
projects: [join(__dirname, "regenerator-fixtures")],
|
|
config: join(__dirname, "regenerator-fixtures", "jest.config.js"),
|
|
testMatch: testFiles,
|
|
testPathPattern: testFiles,
|
|
};
|
|
try {
|
|
// Each test file is run in a separate process to avoid interference between tests (e.g. shared.js exports writable Symbol).
|
|
const { results } = await jest.runCLI(options, options.projects);
|
|
if (!results.success) {
|
|
throw new Error("Jest tests failed");
|
|
}
|
|
} catch (err) {
|
|
throw new Error("Jest tests failed", { cause: err });
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
it(`${cmd} ${args.join(" ")}`, () =>
|
|
new Promise((resolve, reject) => {
|
|
const cp = spawn(cmd, args, { cwd: __dirname });
|
|
let stderr = "";
|
|
cp.stderr.on("data", chunk => {
|
|
stderr += chunk;
|
|
});
|
|
cp.on("exit", async err => {
|
|
if (err) {
|
|
reject(new Error("Exited with " + err + "\n" + stderr));
|
|
} else {
|
|
resolve();
|
|
}
|
|
});
|
|
}));
|
|
}
|
|
});
|
|
}
|
|
|
|
try {
|
|
mkdirSync(join(__dirname, "regenerator-fixtures/tmp"));
|
|
} catch {}
|
|
// TODO: Remove fallback after dropping Node.js 6
|
|
// "minNodeVersion": "8.0.0" <-- For Ctrl+F when dropping node 6
|
|
(copyFileSync || ((from, to) => writeFileSync(to, readFileSync(from))))(
|
|
join(__dirname, "./regenerator-fixtures/shared.js"),
|
|
join(__dirname, "./regenerator-fixtures/tmp/shared.js"),
|
|
);
|
|
|
|
enqueue(convert, [
|
|
"./regenerator-fixtures/tests.es6.js",
|
|
"./regenerator-fixtures/tmp/tests.es5.js",
|
|
]);
|
|
|
|
enqueue(convertOldHelper, [
|
|
"./regenerator-fixtures/tests.es6.js",
|
|
"./regenerator-fixtures/tmp/tests.es5-old.js",
|
|
]);
|
|
|
|
enqueue(convert, [
|
|
"./regenerator-fixtures/tests-node4.es6.js",
|
|
"./regenerator-fixtures/tmp/tests-node4.es5.js",
|
|
]);
|
|
|
|
enqueue(convert, [
|
|
"./regenerator-fixtures/non-native.js",
|
|
"./regenerator-fixtures/tmp/non-native.es5.js",
|
|
]);
|
|
|
|
enqueue(convert, [
|
|
"./regenerator-fixtures/async.js",
|
|
"./regenerator-fixtures/tmp/async.es5.js",
|
|
]);
|
|
|
|
enqueue(convertOldHelper, [
|
|
"./regenerator-fixtures/async.js",
|
|
"./regenerator-fixtures/tmp/async.es5-old.js",
|
|
]);
|
|
|
|
enqueue(convert, [
|
|
"./regenerator-fixtures/class.js",
|
|
"./regenerator-fixtures/tmp/class.es5.js",
|
|
]);
|
|
|
|
enqueue(convertWithRegeneratorPluginOnly, [
|
|
"./regenerator-fixtures/class.js",
|
|
"./regenerator-fixtures/tmp/class.regenerator.js",
|
|
]);
|
|
|
|
enqueue(convertWithRegeneratorPluginOnly, [
|
|
"./regenerator-fixtures/tests.no-symbol.js",
|
|
"./regenerator-fixtures/tmp/no-symbol.es5.js",
|
|
]);
|
|
|
|
Error.stackTraceLimit = 1000;
|
|
|
|
/**
|
|
* Convert without using the preset (which also transforms things like classes and arrows)
|
|
*/
|
|
function convertWithRegeneratorPluginOnly(inputFile, outputFile, callback) {
|
|
const transformOptions = {
|
|
plugins: [pluginTransformRegenerator],
|
|
parserOpts: {
|
|
sourceType: "module",
|
|
allowImportExportEverywhere: true,
|
|
allowReturnOutsideFunction: true,
|
|
allowSuperOutsideMethod: true,
|
|
strictMode: false,
|
|
plugins: ["*", "jsx", "flow"],
|
|
},
|
|
ast: true,
|
|
configFile: false,
|
|
};
|
|
|
|
readFile(join(__dirname, inputFile), "utf-8", function (err, input) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
|
|
const { code: output, ast } = transformSync(input, transformOptions);
|
|
writeFileSync(join(__dirname, outputFile), output);
|
|
try {
|
|
checkDuplicatedNodes(ast);
|
|
} catch (err) {
|
|
err.message =
|
|
"Occurred while transforming: " + inputFile + "\n" + err.message;
|
|
throw err;
|
|
}
|
|
callback();
|
|
});
|
|
}
|
|
|
|
function convertWithParamsTransform(es6File, es5File, callback) {
|
|
const transformOptions = {
|
|
plugins: [pluginTransformParameters, ...regeneratorPreset],
|
|
parserOpts: {
|
|
sourceType: "module",
|
|
allowImportExportEverywhere: true,
|
|
allowReturnOutsideFunction: true,
|
|
allowSuperOutsideMethod: true,
|
|
strictMode: false,
|
|
plugins: ["*", "jsx", "flow"],
|
|
},
|
|
ast: true,
|
|
configFile: false,
|
|
};
|
|
|
|
readFile(join(__dirname, es6File), "utf-8", function (err, es6) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
|
|
const { code: es5, ast } = transformSync(es6, transformOptions);
|
|
writeFileSync(join(__dirname, es5File), es5);
|
|
try {
|
|
checkDuplicatedNodes(ast);
|
|
} catch (err) {
|
|
err.message =
|
|
"Occurred while transforming: " + es6File + "\n" + err.message;
|
|
throw err;
|
|
}
|
|
callback();
|
|
});
|
|
}
|
|
|
|
enqueue(convertWithParamsTransform, [
|
|
"./regenerator-fixtures/regression.js",
|
|
"./regenerator-fixtures/tmp/regression.es5.js",
|
|
]);
|
|
|
|
function convertWithCustomPromiseReplacer(es6File, es5File, callback) {
|
|
const transformOptions = {
|
|
plugins: [
|
|
function (babel) {
|
|
return {
|
|
visitor: {
|
|
FunctionExpression: {
|
|
exit(path) {
|
|
const stmt = path.get("body.body").find(function (stmt) {
|
|
return (
|
|
stmt.isLabeledStatement() &&
|
|
stmt
|
|
.get("label")
|
|
.isIdentifier({ name: "babelInjectPromise" })
|
|
);
|
|
});
|
|
if (!stmt) return;
|
|
|
|
path.traverse({
|
|
ReferencedIdentifier(path) {
|
|
if (path.node.name === "Promise") {
|
|
path.replaceWith(
|
|
babel.types.cloneNode(stmt.node.body.expression),
|
|
);
|
|
}
|
|
},
|
|
});
|
|
},
|
|
},
|
|
},
|
|
};
|
|
},
|
|
...regeneratorPreset,
|
|
],
|
|
parserOpts: {
|
|
strictMode: false,
|
|
},
|
|
ast: true,
|
|
configFile: false,
|
|
};
|
|
|
|
readFile(join(__dirname, es6File), "utf-8", function (err, es6) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
|
|
const { code: es5, ast } = transformSync(es6, transformOptions);
|
|
writeFileSync(join(__dirname, es5File), es5);
|
|
try {
|
|
checkDuplicatedNodes(ast);
|
|
} catch (err) {
|
|
err.message =
|
|
"Occurred while transforming: " + es6File + "\n" + err.message;
|
|
callback(err);
|
|
}
|
|
callback();
|
|
});
|
|
}
|
|
|
|
enqueue(convertWithCustomPromiseReplacer, [
|
|
"./regenerator-fixtures/async-custom-promise.js",
|
|
"./regenerator-fixtures/tmp/async-custom-promise.es5.js",
|
|
]);
|
|
|
|
enqueue(convert, [
|
|
"./regenerator-fixtures/replaceWith-falsy.js",
|
|
"./regenerator-fixtures/tmp/replaceWith-falsy.es5.js",
|
|
]);
|
|
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/tests.es5.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/tests.es5-old.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/tests-node4.es5.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/non-native.es5.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/async.es5.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/async.es5-old.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/async-custom-promise.es5.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/regression.es5.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tests.transform.js"]);
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/class.regenerator.js"]);
|
|
|
|
enqueue("jest", ["./regenerator-fixtures/tests-node4.es6.js"]);
|
|
|
|
enqueue("jest", [
|
|
"./regenerator-fixtures/non-writable-tostringtag-property.js",
|
|
]);
|
|
|
|
enqueue("jest", ["./regenerator-fixtures/frozen-intrinsics.js"]);
|
|
|
|
enqueue("jest", ["./regenerator-fixtures/tmp/no-symbol.es5.js"]);
|