cfg-test
Version:
In-source testing using Node.js Test Runner
8 lines (7 loc) • 11.1 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/core/api.ts"],
"sourcesContent": ["import { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire, register as load } from \"node:module\";\nimport { resolve } from \"node:path\";\nimport { sep } from \"node:path\";\nimport process from \"node:process\";\nimport { pathToFileURL } from \"node:url\";\nimport type { Config } from \"./config\";\nimport { testEnv } from \"./define\";\nimport * as log from \"./log\";\n\nconst ARGV = [\"/path/to/node\", \"/path/to/file\"];\nconst fileIndex = ARGV.indexOf(\"/path/to/file\");\n\nconst cwd = process.cwd();\nconst cwdUrl = pathToFileURL(\n cwd.endsWith(sep) ? sep : (cwd + sep /*not file*/),\n);\nconst require = createRequire(cwdUrl);\nconst parentUrl = cwdUrl.toString();\n\nexport interface RegisterOptions {\n readonly argv?: readonly string[] | undefined;\n readonly execArgv?: readonly string[] | undefined;\n}\n\nexport function register(options: RegisterOptions | undefined = {}) {\n const argv = options.argv || process.argv;\n\n if (!(fileIndex in argv)) {\n return;\n }\n\n const file = resolve(argv[fileIndex]!);\n const execArgv = options.execArgv || process.execArgv;\n const nodeOptions = `,${\n process.env[\"NODE_OPTIONS\"]\n ? execArgv.concat(process.env[\"NODE_OPTIONS\"].split(/\\s/g))\n : execArgv\n },`;\n // ... --import cfg-test ...\n const isEsmMode = /,--import,cfg-test[,/]/.test(nodeOptions);\n const isWatchMode = /,--watch,/.test(nodeOptions);\n const isDTsFile = file.endsWith(\".d.ts\");\n const isTypeScript = /\\.[cm]?tsx?$/i.test(file);\n\n log.debug(() => [\n `esm mode -> ${isEsmMode}`,\n `watch mode -> ${isWatchMode}`,\n `typescript file -> ${isTypeScript}`,\n `declare file -> ${isDTsFile}`,\n `argv -> ${argv.map(a => JSON.stringify(a)).join(\" \")}`,\n `execArgv -> ${execArgv.map(a => JSON.stringify(a)).join(\" \")}`,\n `cwd -> ${JSON.stringify(cwd)}`,\n `parentUrl -> ${JSON.stringify(parentUrl)}`,\n `target file -> ${JSON.stringify(file)}`,\n ]);\n\n if (\n isEsmMode\n // @ts-expect-error\n && true !== true\n ) {\n log.error(() => [\"Cannot import `cfg-test` in CommonJS\"]);\n process.exit(1);\n }\n\n // env\n\n const env = {\n ...testEnv,\n CFG_TEST_CFG: process.env.CFG_TEST_CFG ?? `${[\n \".config/cfg-test\",\n \".config/cfg-test/config\",\n \"config/cfg-test\",\n \"config/cfg-test/config\",\n \"cfg-test\",\n ]}`,\n CFG_TEST_FILE: file,\n };\n\n if (isEsmMode) {\n Object.assign(env, {\n CFG_TEST_URL: pathToFileURL(file),\n });\n }\n\n Object.assign(env, {\n CFG_TEST_WATCH: `${isWatchMode}`,\n });\n\n const originalEnv = { ...process.env };\n\n log.debug(() =>\n Object.entries(env)\n .filter(([k, v]) => [undefined, v].includes(originalEnv[k]))\n .map(([k, v]) => `Added env.${k}=${JSON.stringify(v)} by cfg-test.`)\n );\n log.warn(() =>\n Object.entries(env)\n .filter(([k, v]) => [undefined, v].every(v => v !== originalEnv[k]))\n .map(([k, v]) => `Updated env.${k}=${JSON.stringify(v)} by cfg-test.`)\n );\n\n Object.assign(process.env, env);\n\n // utils\n\n const cfgTest: CfgTest = new Proxy(require(\"node:test\"), {\n get(target, p, receiver) {\n switch (p) {\n case \"url\":\n return process.env.CFG_TEST_URL;\n\n case \"file\":\n return process.env.CFG_TEST_FILE;\n\n case \"watch\":\n return process.env.CFG_TEST_WATCH === \"true\";\n\n case \"assert\":\n return require(\"node:assert/strict\");\n\n default:\n return Reflect.get(target, p, receiver);\n }\n },\n });\n\n global.cfgTest = cfgTest;\n\n // config\n\n let cfg: Config | undefined;\n\n for (const id of process.env.CFG_TEST_CFG!.split(\",\")) {\n const cfgPath = id.endsWith(\".json\") ? id : `${id}.json`;\n\n if (existsSync(cfgPath)) {\n cfg = JSON.parse(readFileSync(cfgPath, \"utf8\"));\n break;\n }\n }\n\n if (cfg && cfg.env) {\n for (const [key, value] of Object.entries(cfg.env)) {\n if (typeof value !== \"string\") {\n continue;\n }\n\n if (process.env[key] === undefined) {\n log.debug(() => [`Added env.${key} by config file.`]);\n } else {\n log.warn(() => [`Updated env.${key} by config file.`]);\n }\n\n process.env[key] = value;\n }\n }\n\n if (cfg && cfg.globals) {\n for (const [key, value] of Object.entries(cfg.globals)) {\n if (key in global) {\n log.warn(() => [`Updated global.${key} by config file.`]);\n } else {\n log.debug(() => [`Added global.${key} by config file.`]);\n // @ts-expect-error\n global[key] = value;\n }\n }\n }\n\n if (cfg && cfg.import) {\n if (!Array.isArray(cfg.import)) {\n cfg.import = [cfg.import];\n }\n\n for (const id of cfg.import) {\n log.debug(() => [`Imported module ${id} by config file.`]);\n load(id, parentUrl);\n }\n }\n\n if (cfg && cfg.require) {\n if (!Array.isArray(cfg.require)) {\n cfg.require = [cfg.require];\n }\n\n for (const id of cfg.require) {\n log.debug(() => [`Required module ${id} by config file.`]);\n require(id);\n }\n }\n\n const ctx = {\n log,\n argv,\n file,\n execArgv,\n isEsmMode,\n parentUrl,\n isWatchMode,\n isTypeScript,\n import(id: string): void {\n try {\n log.debug(() => [`Register ESM module ${id}.`]);\n load(id, parentUrl);\n log.debug(() => [`Registered ESM module ${id}.`]);\n } catch (e) {\n log.error(() => [`Cannot register ESM module ${id}.`]);\n throw e;\n }\n },\n require(id: string, onLoad: (mod: any) => void): void {\n try {\n log.debug(() => [`Register CJS module ${id}`]);\n const mod = require(id);\n log.debug(() => [`Loaded CJS module ${id}`]);\n onLoad(mod);\n log.debug(() => [`Registered CJS module ${id}`]);\n } catch (e) {\n log.error(() => [`Cannot register CJS module ${id}.`]);\n throw e;\n }\n },\n };\n\n if (isDTsFile) {\n if (ctx.isEsmMode) {\n ctx.import(\"cfg-test/dts-loader\");\n } else {\n // CommonJS implementation of `cfg-test/dts-loader`\n require(\"node:module\")._extensions[\".ts\"] = () => \"\";\n ctx.log.debug(() => [\"Registered CJS module cfg-test/dts-loader.\"]);\n }\n\n return;\n }\n\n return ctx;\n}\n"],
"mappings": "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",
"names": ["require", "v"]
}