From 0c3371cd50cf45a8cc1b3dd0e4cfa3c599a26ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 15 Jun 2022 04:51:01 +0200 Subject: [PATCH] Run Babel asynchronously in fixtures (#14659) * Run Babel asynchronously in fixtures * Move `checkScopeInfo` to test folder, convert to ESM * Fix Node.js 8 * Avoid dynamic import feature detection --- .../src/config/files/module-types.ts | 10 +++- .../src/index.ts | 60 ++++++++++++------- .../test/fixtures/allowArrayLike/options.json | 2 +- .../options.json | 2 +- .../assumption-iterableIsArray/options.json | 2 +- .../options.json | 2 +- .../test/fixtures/destructuring/options.json | 2 +- .../{res => test/helpers}/checkScopeInfo.js | 3 +- 8 files changed, 52 insertions(+), 31 deletions(-) rename packages/babel-plugin-transform-destructuring/{res => test/helpers}/checkScopeInfo.js (92%) diff --git a/packages/babel-core/src/config/files/module-types.ts b/packages/babel-core/src/config/files/module-types.ts index cb19a02da21d..711c0f60079d 100644 --- a/packages/babel-core/src/config/files/module-types.ts +++ b/packages/babel-core/src/config/files/module-types.ts @@ -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, diff --git a/packages/babel-helper-transform-fixture-test-runner/src/index.ts b/packages/babel-helper-transform-fixture-test-runner/src/index.ts index be7fa4c40960..45c1f1b135cc 100644 --- a/packages/babel-helper-transform-fixture-test-runner/src/index.ts +++ b/packages/babel-helper-transform-fixture-test-runner/src/index.ts @@ -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< @@ -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, @@ -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`; @@ -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, @@ -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); @@ -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); @@ -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 @@ -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), ` @@ -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(); } }, ); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/allowArrayLike/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/allowArrayLike/options.json index 09150d2bbda3..d016758cf22f 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/allowArrayLike/options.json +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/allowArrayLike/options.json @@ -1,3 +1,3 @@ { - "plugins": ["../../../res/checkScopeInfo.js"] + "plugins": ["../../helpers/checkScopeInfo.js"] } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-arrayLikeIsIterable/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-arrayLikeIsIterable/options.json index fa4724b1f8eb..6f30b3f48ce7 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-arrayLikeIsIterable/options.json +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-arrayLikeIsIterable/options.json @@ -1,5 +1,5 @@ { - "plugins": ["transform-destructuring", "../../../res/checkScopeInfo.js"], + "plugins": ["transform-destructuring", "../../helpers/checkScopeInfo.js"], "assumptions": { "arrayLikeIsIterable": true } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-iterableIsArray/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-iterableIsArray/options.json index 363e54ba6a78..6ef8b3fafa1b 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-iterableIsArray/options.json +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-iterableIsArray/options.json @@ -1,5 +1,5 @@ { - "plugins": ["transform-destructuring", "../../../res/checkScopeInfo.js"], + "plugins": ["transform-destructuring", "../../helpers/checkScopeInfo.js"], "assumptions": { "iterableIsArray": true } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-objectRestNoSymbols/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-objectRestNoSymbols/options.json index 7eb64217e527..cef670253e91 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-objectRestNoSymbols/options.json +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/assumption-objectRestNoSymbols/options.json @@ -1,5 +1,5 @@ { - "plugins": ["transform-destructuring", "../../../res/checkScopeInfo.js"], + "plugins": ["transform-destructuring", "../../helpers/checkScopeInfo.js"], "assumptions": { "objectRestNoSymbols": true } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/options.json index 79b6aa63cec4..c26c396062b5 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/options.json +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/options.json @@ -6,6 +6,6 @@ "transform-block-scoping", "proposal-object-rest-spread", "transform-regenerator", - "../../../res/checkScopeInfo.js" + "../../helpers/checkScopeInfo.js" ] } diff --git a/packages/babel-plugin-transform-destructuring/res/checkScopeInfo.js b/packages/babel-plugin-transform-destructuring/test/helpers/checkScopeInfo.js similarity index 92% rename from packages/babel-plugin-transform-destructuring/res/checkScopeInfo.js rename to packages/babel-plugin-transform-destructuring/test/helpers/checkScopeInfo.js index 07e60c56e956..cc1534ccd6b1 100644 --- a/packages/babel-plugin-transform-destructuring/res/checkScopeInfo.js +++ b/packages/babel-plugin-transform-destructuring/test/helpers/checkScopeInfo.js @@ -1,5 +1,4 @@ -// checkScopeInfo.js -module.exports = () => { +export default () => { return { visitor: { Program: {