Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139// Derived from Node.js v24.16.0 (MIT; Copyright Node.js contributors, and Joyent, Inc. and// other Node contributors). See LICENSE-node.// node:internal/test_runner/utils.js, trimmed to what harness.ts/test.ts actually use:// the callback-invoked-twice guard, the ERR_TEST_FAILURE sniff, the counters bump and// the CLI-flag defaults. Coverage, randomize/seed, rerun-failures, --test-shard and// --test-name-pattern all read real CLI flags through getOptionValue(); none of that// parsing exists here (DESIGN: CLI flags are refused), so commandLineDefaults() is the// one place a later flag parser would feed real values in.import { testFailure, type TestFailureError } from "./test-failure";import { invalidArgValue } from "../errors";import type { Test } from "./test";
export const kMultipleCallbackInvocations = "multipleCallbackInvocations";
export interface DeferredCallback { promise: Promise<void>; cb: (err?: unknown) => void;}
/** Node's createDeferredCallback: resolves on the first call, rejects if it carried an * error, and fails the test (via the thrown ERR_TEST_FAILURE on the second call) if * the callback is invoked more than once. */export function createDeferredCallback(): DeferredCallback { let calledCount = 0; let resolve!: () => void; let reject!: (err: unknown) => void; const promise = new Promise<void>((res, rej) => { resolve = res; reject = rej; }); const cb = (err?: unknown): void => { calledCount++; if (calledCount > 1) { if (calledCount === 2) throw testFailure("callback invoked multiple times", kMultipleCallbackInvocations); return; } if (err) reject(err); else resolve(); }; return { promise, cb };}
export function isTestFailureError(err: unknown): err is TestFailureError { return Boolean(err) && typeof err === "object" && (err as { code?: string }).code === "ERR_TEST_FAILURE";}
/** Node's countCompletedTest: bumps the root's summary counters for one finished test * or suite. Skip/todo win over a failure; a suite only ever affects `suites`. */export function countCompletedTest(test: Test): void { const harness = test.root.harness!; if (test.nesting === 0) harness.counters.topLevel++; if (test.reportedType === "suite") { harness.counters.suites++; if (!test.passed && !test.isTodo) harness.success = false; return; } if (test.skipped) harness.counters.skipped++; else if (test.isTodo) harness.counters.todo++; else if (test.cancelled) { harness.counters.cancelled++; harness.success = false; } else if (!test.passed) { harness.counters.failed++; harness.success = false; } else { harness.counters.passed++; } harness.counters.tests++;}
export interface GlobalTestOptions { isTestRunner: boolean; concurrency: number | boolean; only: boolean; timeout: number; cwd: string; testUpdateSnapshots: boolean; /** Converted from run()'s testNamePatterns/testSkipPatterns (runner.ts), or null. A * later CLI parser (--test-name-pattern/--test-skip-pattern) would feed these the * same way: null here means "not filtering by name", read by test.ts's * willBeFilteredByName(). Not fed by run()'s own option today — see runner.ts's * header comment on the confirmed Node quirk this mirrors. */ testNamePatterns: RegExp[] | null; testSkipPatterns: RegExp[] | null;}
/** Node's internalBinding('util').getCallerLocation(): where the function that calls * this one was itself called from. Parses the `.stack` string rather than using * Error.prepareStackTrace/CallSite#getFileName() (src/runtime/util.ts's * getCallSites() technique): CallSite#getFileName() comes back `undefined` for a * frame inside the guest's indirect-eval'd CJS wrapper in this engine (confirmed by * probing it directly), even though the wrapper's `//# sourceURL=` comment (see * compileCjs in modules.ts) does make the guest's real path show up correctly in the * plain `.stack` string's own frame lines, which is what's parsed here instead. * Every caller invokes this directly from its own body — test()/describe()/before()/ * ... in harness.ts, and TestContext#test/before/after/beforeEach/afterEach in * test.ts — so after the message line and this function's own frame, the next frame * (index 2, 0-based) is the caller's own wrapper body, and the one after that (index * 3) is the user's actual call site. */export function getCallerLocation(): [number, number, string] | undefined { const lines = (new Error().stack ?? "").split("\n"); const line = lines[3]; if (!line) return undefined; const m = /\(([^()]+):(\d+):(\d+)\)\s*$/.exec(line) ?? /^\s*at\s+(\S+):(\d+):(\d+)\s*$/.exec(line); if (!m) return undefined; return [Number(m[2]), Number(m[3]), m[1]!];}
/** CLI flags Node reads through getOptionValue (DESIGN: no CLI flag parser here, so * every run behaves as `node file.test.js` with no --test* flags at all). A later * flag parser feeds real values in by replacing this one function. */export function commandLineDefaults(cwd: string): GlobalTestOptions { return { isTestRunner: false, concurrency: 1, only: false, timeout: Infinity, cwd, testUpdateSnapshots: false, testNamePatterns: null, testSkipPatterns: null, };}
/** Node's internal/test_runner/utils.js kPatterns/kFileExtensions/kDefaultPattern: the * glob run() falls back to when `files` and `globPatterns` are both omitted. No * --strip-types flag exists here (DESIGN: no CLI flag parser), so .ts/.mts/.cts never * join the extension list the way Node's does under that flag. */export const kDefaultPattern = "**/{test,test/**/*,test-*,*[._-]test}.{js,mjs,cjs}";
/** Node's internal/test_runner/utils.js convertStringToRegExp: a bare `/pat/flags` * string is read as a literal regex (its own flags, not case-insensitive by default); * anything else is the pattern verbatim with no flags. */export function convertStringToRegExp(str: string, name: string): RegExp { const m = /^\/(.*)\/([a-z]*)$/.exec(str); const pattern = m?.[1] ?? str; const flags = m?.[2] || ""; try { return new RegExp(pattern, flags); } catch (err) { const msg = err instanceof Error ? err.message : undefined; throw invalidArgValue(name, str, `is an invalid regular expression.${msg ? ` ${msg}` : ""}`); }}