Skip to content

Commit

Permalink
Run Babel asynchronously in fixtures (#14659)
Browse files Browse the repository at this point in the history
* Run Babel asynchronously in fixtures

* Move `checkScopeInfo` to test folder, convert to ESM

* Fix Node.js 8

* Avoid dynamic import feature detection
  • Loading branch information
nicolo-ribaudo committed Jun 15, 2022
1 parent f8785e9 commit 0c3371c
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 31 deletions.
10 changes: 8 additions & 2 deletions packages/babel-core/src/config/files/module-types.ts
Expand Up @@ -3,16 +3,22 @@ import type { Handler } from "gensync";
import path from "path";
import { pathToFileURL } from "url";
import { createRequire } from "module";
import semver from "semver";

const require = createRequire(import.meta.url);

let import_;
try {
// Node < 13.3 doesn't support import() syntax.
// Old Node.js versions don't support import() syntax.
import_ = require("./import").default;
} catch {}

export const supportsESM = !!import_;
export const supportsESM = semver.satisfies(
process.versions.node,
// older versions, starting from 10, support the dynamic
// import syntax but always return a rejected promise.
"^12.17 || >=13.2",
);

export default function* loadCjsOrMjsDefault(
filepath: string,
Expand Down
60 changes: 38 additions & 22 deletions packages/babel-helper-transform-fixture-test-runner/src/index.ts
Expand Up @@ -20,6 +20,24 @@ const require = createRequire(import.meta.url);

import checkDuplicateNodes from "@babel/helper-check-duplicate-nodes";

if (!process.env.BABEL_8_BREAKING) {
// Introduced in Node.js 8
if (!assert.rejects) {
assert.rejects = async function (block, validateError) {
try {
await block();
return Promise.reject(new Error("Promise not rejected"));
} catch (error) {
if (!validateError(error)) {
return Promise.reject(
new Error("Promise rejected with invalid error"),
);
}
}
};
}
}

const EXTERNAL_HELPERS_VERSION = "7.100.0";

const cachedScripts = new QuickLRU<
Expand All @@ -40,12 +58,20 @@ function transformWithoutConfigFile(code, opts) {
...opts,
});
}
function transformAsyncWithoutConfigFile(code, opts) {
return babel.transformAsync(code, {
configFile: false,
babelrc: false,
...opts,
});
}

function createContext() {
const context = vm.createContext({
...helpers,
process: process,
transform: transformWithoutConfigFile,
transformAsync: transformAsyncWithoutConfigFile,
setTimeout: setTimeout,
setImmediate: setImmediate,
expect,
Expand Down Expand Up @@ -194,10 +220,10 @@ export function runCodeInTestContext(
}
}

function maybeMockConsole(validateLogs, run) {
async function maybeMockConsole(validateLogs, run) {
const actualLogs = { stdout: "", stderr: "" };

if (!validateLogs) return { result: run(), actualLogs };
if (!validateLogs) return { result: await run(), actualLogs };

const spy1 = jest.spyOn(console, "log").mockImplementation(msg => {
actualLogs.stdout += `${msg}\n`;
Expand All @@ -207,14 +233,14 @@ function maybeMockConsole(validateLogs, run) {
});

try {
return { result: run(), actualLogs };
return { result: await run(), actualLogs };
} finally {
spy1.mockRestore();
spy2.mockRestore();
}
}

function run(task) {
async function run(task) {
const {
actual,
expect: expected,
Expand Down Expand Up @@ -256,8 +282,8 @@ function run(task) {

// Ignore Babel logs of exec.js files.
// They will be validated in input/output files.
({ result } = maybeMockConsole(validateLogs, () =>
babel.transformSync(execCode, execOpts),
({ result } = await maybeMockConsole(validateLogs, () =>
babel.transformAsync(execCode, execOpts),
));

checkDuplicateNodes(result.ast);
Expand All @@ -278,8 +304,8 @@ function run(task) {
if (!execCode || inputCode) {
let actualLogs;

({ result, actualLogs } = maybeMockConsole(validateLogs, () =>
babel.transformSync(inputCode, getOpts(actual)),
({ result, actualLogs } = await maybeMockConsole(validateLogs, () =>
babel.transformAsync(inputCode, getOpts(actual)),
));

const outputCode = normalizeOutput(result.code);
Expand Down Expand Up @@ -470,11 +496,8 @@ export default function (
testFn(
task.title,

function () {
function runTask() {
run(task);
}

async function () {
const runTask = () => run(task);
if ("sourceMap" in task.options === false) {
task.options.sourceMap = !!(
task.sourceMappings || task.sourceMap
Expand All @@ -499,7 +522,7 @@ export default function (
// the options object with useless options
delete task.options.throws;

assert.throws(runTask, function (err: Error) {
await assert.rejects(runTask, function (err: Error) {
assert.ok(
throwMsg === true || err.message.includes(throwMsg),
`
Expand All @@ -509,14 +532,7 @@ Actual Error: ${err.message}`,
return true;
});
} else {
if (task.exec.code) {
const result = run(task);
if (result && typeof result.then === "function") {
return result;
}
} else {
runTask();
}
return runTask();
}
},
);
Expand Down
@@ -1,3 +1,3 @@
{
"plugins": ["../../../res/checkScopeInfo.js"]
"plugins": ["../../helpers/checkScopeInfo.js"]
}
@@ -1,5 +1,5 @@
{
"plugins": ["transform-destructuring", "../../../res/checkScopeInfo.js"],
"plugins": ["transform-destructuring", "../../helpers/checkScopeInfo.js"],
"assumptions": {
"arrayLikeIsIterable": true
}
Expand Down
@@ -1,5 +1,5 @@
{
"plugins": ["transform-destructuring", "../../../res/checkScopeInfo.js"],
"plugins": ["transform-destructuring", "../../helpers/checkScopeInfo.js"],
"assumptions": {
"iterableIsArray": true
}
Expand Down
@@ -1,5 +1,5 @@
{
"plugins": ["transform-destructuring", "../../../res/checkScopeInfo.js"],
"plugins": ["transform-destructuring", "../../helpers/checkScopeInfo.js"],
"assumptions": {
"objectRestNoSymbols": true
}
Expand Down
Expand Up @@ -6,6 +6,6 @@
"transform-block-scoping",
"proposal-object-rest-spread",
"transform-regenerator",
"../../../res/checkScopeInfo.js"
"../../helpers/checkScopeInfo.js"
]
}
@@ -1,5 +1,4 @@
// checkScopeInfo.js
module.exports = () => {
export default () => {
return {
visitor: {
Program: {
Expand Down

0 comments on commit 0c3371c

Please sign in to comment.