UNPKG

testplane

Version:

Tests framework based on mocha and wdio

181 lines 6.66 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerReplModuleHooks = void 0; const nodeModule = __importStar(require("node:module")); const commander_1 = require("@gemini-testing/commander"); const node_fs_1 = require("node:fs"); const node_path_1 = __importDefault(require("node:path")); const node_url_1 = require("node:url"); const pirates_1 = require("pirates"); const repl_options_1 = require("../cli/repl-options"); const repl_instrumentation_1 = require("./repl-instrumentation"); const logger = __importStar(require("./logger")); const TESTPLANE_REPL_MODULE_HOOK = Symbol.for("testplane.repl.module.hook"); const TRANSFORM_CODE_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"]; const registerReplModuleHooks = () => { const processWithHook = process; if (processWithHook[TESTPLANE_REPL_MODULE_HOOK]) { return; } const program = (0, repl_options_1.addReplOptions)(new commander_1.Command("testplane").allowUnknownOption().option("-h, --help")); program.parse(process.argv); if (!(0, repl_options_1.isReplModeEnabled)(program)) { return; } const hook = registerNodeModuleHooks() || registerPiratesHook(); processWithHook[TESTPLANE_REPL_MODULE_HOOK] = hook; }; exports.registerReplModuleHooks = registerReplModuleHooks; function registerNodeModuleHooks() { const registerHooks = nodeModule.registerHooks; if (typeof registerHooks !== "function") { return null; } const hooks = registerHooks({ load(url, context, nextLoad) { let result; try { result = nextLoad(url, context); } catch (err) { // https://github.com/nodejs/node/issues/57327 // Fixed for REPL instrumentation in Node 24.13.0; older versions mishandle CJS sources with mixed sync/async hooks. return instrumentLoadAfterFailedLoad(url, context, err); } return instrumentLoadResult(url, result); }, }); return { revert: () => hooks.deregister() }; } function registerPiratesHook() { const revert = (0, pirates_1.addHook)((code, sourceFile) => safeInstrumentRepl(code, sourceFile), { exts: TRANSFORM_CODE_EXTENSIONS, ignoreNodeModules: true, }); return { revert }; } function instrumentLoadAfterFailedLoad(url, context, err) { const sourceFile = getSourceFileFromUrl(url); if (!isInvalidLoadSourceError(err) || !sourceFile || !shouldReadSourceFile(sourceFile)) { throw err; } const source = readSourceFile(sourceFile); if (source === null) { throw err; } return { format: getFallbackFormat(context, sourceFile), shortCircuit: true, source: shouldHandleSourceFile(sourceFile) ? safeInstrumentRepl(source, sourceFile) : source, }; } function instrumentLoadResult(url, result) { const sourceFile = getSourceFileFromUrl(url); if (!sourceFile || !shouldHandleSourceFile(sourceFile)) { return result; } const resultSource = result.source; const source = resultSource === null || resultSource === undefined ? readSourceFile(sourceFile) : moduleSourceToString(resultSource); if (source === null) { return result; } return { ...result, source: safeInstrumentRepl(source, sourceFile) }; } function safeInstrumentRepl(source, sourceFile) { try { return (0, repl_instrumentation_1.instrumentReplIfNeeded)(source, sourceFile); } catch (err) { logger.warn(`Failed to instrument ${sourceFile} for REPL mode: ${err.message}.`); return source; } } function readSourceFile(sourceFile) { try { return (0, node_fs_1.readFileSync)(sourceFile, "utf8"); } catch { return null; } } function isInvalidLoadSourceError(err) { if (!(err instanceof Error)) { return false; } const error = err; return (error.code === "ERR_INVALID_RETURN_PROPERTY_VALUE" && error.message.includes('"source"') && error.message.includes('"load" hook')); } function shouldReadSourceFile(sourceFile) { return TRANSFORM_CODE_EXTENSIONS.includes(node_path_1.default.extname(sourceFile)); } function getFallbackFormat(context, sourceFile) { if (context.format) { return context.format; } switch (node_path_1.default.extname(sourceFile)) { case ".mjs": return "module"; case ".mts": return "module-typescript"; case ".ts": case ".tsx": case ".cts": return "commonjs-typescript"; default: return "commonjs"; } } function getSourceFileFromUrl(url) { try { return url.startsWith("file:") ? (0, node_url_1.fileURLToPath)(url) : null; } catch { return null; } } function shouldHandleSourceFile(sourceFile) { return shouldReadSourceFile(sourceFile) && !sourceFile.includes(`${node_path_1.default.sep}node_modules${node_path_1.default.sep}`); } function moduleSourceToString(source) { if (typeof source === "string") { return source; } if (source instanceof ArrayBuffer) { return Buffer.from(source).toString(); } if (ArrayBuffer.isView(source)) { return Buffer.from(source.buffer, source.byteOffset, source.byteLength).toString(); } return null; } //# sourceMappingURL=repl-module-hooks.js.map