jest-runner
Advanced tools
+6
-6
@@ -13,4 +13,4 @@ /*! | ||
| /***/ "./src/runTest.ts": | ||
| /***/ ((__unused_webpack_module, exports) => { | ||
| /***/ "./src/runTest.ts" | ||
| (__unused_webpack_module, exports) { | ||
@@ -357,6 +357,6 @@ | ||
| /***/ }), | ||
| /***/ }, | ||
| /***/ "./src/types.ts": | ||
| /***/ ((__unused_webpack_module, exports) => { | ||
| /***/ "./src/types.ts" | ||
| (__unused_webpack_module, exports) { | ||
@@ -392,3 +392,3 @@ | ||
| /***/ }) | ||
| /***/ } | ||
@@ -395,0 +395,0 @@ /******/ }); |
@@ -13,4 +13,4 @@ /*! | ||
| /***/ "./src/runTest.ts": | ||
| /***/ ((__unused_webpack_module, exports) => { | ||
| /***/ "./src/runTest.ts" | ||
| (__unused_webpack_module, exports) { | ||
@@ -357,3 +357,3 @@ | ||
| /***/ }) | ||
| /***/ } | ||
@@ -360,0 +360,0 @@ /******/ }); |
+18
-18
| { | ||
| "name": "jest-runner", | ||
| "version": "30.2.0", | ||
| "version": "30.3.0", | ||
| "repository": { | ||
@@ -22,7 +22,7 @@ "type": "git", | ||
| "dependencies": { | ||
| "@jest/console": "30.2.0", | ||
| "@jest/environment": "30.2.0", | ||
| "@jest/test-result": "30.2.0", | ||
| "@jest/transform": "30.2.0", | ||
| "@jest/types": "30.2.0", | ||
| "@jest/console": "30.3.0", | ||
| "@jest/environment": "30.3.0", | ||
| "@jest/test-result": "30.3.0", | ||
| "@jest/transform": "30.3.0", | ||
| "@jest/types": "30.3.0", | ||
| "@types/node": "*", | ||
@@ -34,11 +34,11 @@ "chalk": "^4.1.2", | ||
| "jest-docblock": "30.2.0", | ||
| "jest-environment-node": "30.2.0", | ||
| "jest-haste-map": "30.2.0", | ||
| "jest-leak-detector": "30.2.0", | ||
| "jest-message-util": "30.2.0", | ||
| "jest-resolve": "30.2.0", | ||
| "jest-runtime": "30.2.0", | ||
| "jest-util": "30.2.0", | ||
| "jest-watcher": "30.2.0", | ||
| "jest-worker": "30.2.0", | ||
| "jest-environment-node": "30.3.0", | ||
| "jest-haste-map": "30.3.0", | ||
| "jest-leak-detector": "30.3.0", | ||
| "jest-message-util": "30.3.0", | ||
| "jest-resolve": "30.3.0", | ||
| "jest-runtime": "30.3.0", | ||
| "jest-util": "30.3.0", | ||
| "jest-watcher": "30.3.0", | ||
| "jest-worker": "30.3.0", | ||
| "p-limit": "^3.1.0", | ||
@@ -48,6 +48,6 @@ "source-map-support": "0.5.13" | ||
| "devDependencies": { | ||
| "@jest/test-utils": "30.2.0", | ||
| "@jest/test-utils": "30.3.0", | ||
| "@types/graceful-fs": "^4.1.9", | ||
| "@types/source-map-support": "^0.5.10", | ||
| "jest-jasmine2": "30.2.0" | ||
| "jest-jasmine2": "30.3.0" | ||
| }, | ||
@@ -60,3 +60,3 @@ "engines": { | ||
| }, | ||
| "gitHead": "855864e3f9751366455246790be2bf912d4d0dac" | ||
| "gitHead": "efb59c2e81083f8dc941f20d6d20a3af2dc8d068" | ||
| } |
| import "jest-runtime"; | ||
| import { SerializableError, Test, Test as Test$1, TestEvents, TestEvents as TestEvents$1, TestResult } from "@jest/test-result"; | ||
| import { TestWatcher, TestWatcher as TestWatcher$1 } from "jest-watcher"; | ||
| import { Config, Config as Config$1 } from "@jest/types"; | ||
| //#region src/types.d.ts | ||
| type OnTestStart = (test: Test$1) => Promise<void>; | ||
| type OnTestFailure = (test: Test$1, serializableError: SerializableError) => Promise<void>; | ||
| type OnTestSuccess = (test: Test$1, testResult: TestResult) => Promise<void>; | ||
| type TestRunnerOptions = { | ||
| serial: boolean; | ||
| }; | ||
| type TestRunnerContext = { | ||
| changedFiles?: Set<string>; | ||
| sourcesRelatedToTestsInChangedFiles?: Set<string>; | ||
| }; | ||
| type UnsubscribeFn = () => void; | ||
| interface CallbackTestRunnerInterface { | ||
| readonly isSerial?: boolean; | ||
| readonly supportsEventEmitters?: boolean; | ||
| runTests(tests: Array<Test$1>, watcher: TestWatcher$1, onStart: OnTestStart, onResult: OnTestSuccess, onFailure: OnTestFailure, options: TestRunnerOptions): Promise<void>; | ||
| } | ||
| interface EmittingTestRunnerInterface { | ||
| readonly isSerial?: boolean; | ||
| readonly supportsEventEmitters: true; | ||
| runTests(tests: Array<Test$1>, watcher: TestWatcher$1, options: TestRunnerOptions): Promise<void>; | ||
| on<Name extends keyof TestEvents$1>(eventName: Name, listener: (eventData: TestEvents$1[Name]) => void | Promise<void>): UnsubscribeFn; | ||
| } | ||
| declare abstract class BaseTestRunner { | ||
| protected readonly _globalConfig: Config$1.GlobalConfig; | ||
| protected readonly _context: TestRunnerContext; | ||
| readonly isSerial?: boolean; | ||
| abstract readonly supportsEventEmitters: boolean; | ||
| constructor(_globalConfig: Config$1.GlobalConfig, _context: TestRunnerContext); | ||
| } | ||
| declare abstract class CallbackTestRunner extends BaseTestRunner implements CallbackTestRunnerInterface { | ||
| readonly supportsEventEmitters = false; | ||
| abstract runTests(tests: Array<Test$1>, watcher: TestWatcher$1, onStart: OnTestStart, onResult: OnTestSuccess, onFailure: OnTestFailure, options: TestRunnerOptions): Promise<void>; | ||
| } | ||
| declare abstract class EmittingTestRunner extends BaseTestRunner implements EmittingTestRunnerInterface { | ||
| readonly supportsEventEmitters = true; | ||
| abstract runTests(tests: Array<Test$1>, watcher: TestWatcher$1, options: TestRunnerOptions): Promise<void>; | ||
| abstract on<Name extends keyof TestEvents$1>(eventName: Name, listener: (eventData: TestEvents$1[Name]) => void | Promise<void>): UnsubscribeFn; | ||
| } | ||
| type JestTestRunner = CallbackTestRunner | EmittingTestRunner; | ||
| //#endregion | ||
| //#region src/index.d.ts | ||
| declare class TestRunner extends EmittingTestRunner { | ||
| #private; | ||
| runTests(tests: Array<Test$1>, watcher: TestWatcher$1, options: TestRunnerOptions): Promise<void>; | ||
| on<Name extends keyof TestEvents$1>(eventName: Name, listener: (eventData: TestEvents$1[Name]) => void | Promise<void>): UnsubscribeFn; | ||
| } | ||
| //#endregion | ||
| export { CallbackTestRunner, CallbackTestRunnerInterface, Config, EmittingTestRunner, EmittingTestRunnerInterface, JestTestRunner, OnTestFailure, OnTestStart, OnTestSuccess, Test, TestEvents, TestRunnerContext, TestRunnerOptions, TestWatcher, UnsubscribeFn, TestRunner as default }; |
| import { SerializableModuleMap } from "jest-haste-map"; | ||
| import Runtime from "jest-runtime"; | ||
| import { TestResult } from "@jest/test-result"; | ||
| import { Config } from "@jest/types"; | ||
| //#region src/types.d.ts | ||
| type TestRunnerContext = { | ||
| changedFiles?: Set<string>; | ||
| sourcesRelatedToTestsInChangedFiles?: Set<string>; | ||
| }; | ||
| type SerializeSet<T> = T extends Set<infer U> ? Array<U> : T; | ||
| type TestRunnerSerializedContext = { [K in keyof TestRunnerContext]: SerializeSet<TestRunnerContext[K]> }; | ||
| //#endregion | ||
| //#region src/testWorker.d.ts | ||
| type SerializableResolver = { | ||
| config: Config.ProjectConfig; | ||
| serializableModuleMap: SerializableModuleMap; | ||
| }; | ||
| type WorkerData = { | ||
| config: Config.ProjectConfig; | ||
| globalConfig: Config.GlobalConfig; | ||
| path: string; | ||
| context: TestRunnerSerializedContext; | ||
| }; | ||
| declare function setup(setupData: { | ||
| serializableResolvers: Array<SerializableResolver>; | ||
| }): void; | ||
| declare function worker({ | ||
| config, | ||
| globalConfig, | ||
| path, | ||
| context | ||
| }: WorkerData): Promise<TestResult>; | ||
| //#endregion | ||
| export { SerializableResolver, setup, worker }; |
| import { createRequire } from "node:module"; | ||
| import exit from "exit-x"; | ||
| import HasteMap from "jest-haste-map"; | ||
| import { formatExecError, separateMessageFromStack } from "jest-message-util"; | ||
| import Runtime from "jest-runtime"; | ||
| import { messageParent } from "jest-worker"; | ||
| import { runInContext } from "node:vm"; | ||
| import chalk from "chalk"; | ||
| import * as fs from "graceful-fs"; | ||
| import * as sourcemapSupport from "source-map-support"; | ||
| import { BufferedConsole, CustomConsole, NullConsole, getConsoleOutput } from "@jest/console"; | ||
| import { createScriptTransformer } from "@jest/transform"; | ||
| import * as docblock from "jest-docblock"; | ||
| import LeakDetector from "jest-leak-detector"; | ||
| import { resolveTestEnvironment } from "jest-resolve"; | ||
| import { ErrorWithStack, interopRequireDefault, setGlobal } from "jest-util"; | ||
| //#region rolldown:runtime | ||
| var __require = /* @__PURE__ */ createRequire(import.meta.url); | ||
| //#endregion | ||
| //#region src/runTest.ts | ||
| function freezeConsole(testConsole, config) { | ||
| testConsole._log = function fakeConsolePush(_type, message) { | ||
| const error = new ErrorWithStack(`${chalk.red(`${chalk.bold("Cannot log after tests are done.")} Did you forget to wait for something async in your test?`)}\nAttempted to log "${message}".`, fakeConsolePush); | ||
| const formattedError = formatExecError(error, config, { noStackTrace: false }, void 0, true); | ||
| process.stderr.write(`\n${formattedError}\n`); | ||
| process.exitCode = 1; | ||
| }; | ||
| } | ||
| async function runTestInternal(path, globalConfig, projectConfig, resolver, context, sendMessageToJest$1) { | ||
| const testSource = fs.readFileSync(path, "utf8"); | ||
| const docblockPragmas = docblock.parse(docblock.extract(testSource)); | ||
| const customEnvironment = docblockPragmas["jest-environment"]; | ||
| const loadTestEnvironmentStart = Date.now(); | ||
| let testEnvironment = projectConfig.testEnvironment; | ||
| if (customEnvironment) { | ||
| if (Array.isArray(customEnvironment)) throw new TypeError(`You can only define a single test environment through docblocks, got "${customEnvironment.join(", ")}"`); | ||
| testEnvironment = resolveTestEnvironment({ | ||
| ...projectConfig, | ||
| requireResolveFunction: (module) => __require.resolve(module), | ||
| testEnvironment: customEnvironment | ||
| }); | ||
| } | ||
| const cacheFS = new Map([[path, testSource]]); | ||
| const transformer = await createScriptTransformer(projectConfig, cacheFS); | ||
| const TestEnvironment = await transformer.requireAndTranspileModule(testEnvironment); | ||
| const testFramework = await transformer.requireAndTranspileModule(process.env.JEST_JASMINE === "1" ? __require.resolve("jest-jasmine2") : projectConfig.testRunner); | ||
| const Runtime$1 = interopRequireDefault(projectConfig.runtime ? __require(projectConfig.runtime) : __require("jest-runtime")).default; | ||
| const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout; | ||
| const consoleFormatter = (type, message) => getConsoleOutput(BufferedConsole.write([], type, message, 4), projectConfig, globalConfig); | ||
| let testConsole; | ||
| if (globalConfig.silent) testConsole = new NullConsole(consoleOut, consoleOut, consoleFormatter); | ||
| else if (globalConfig.verbose) testConsole = new CustomConsole(consoleOut, consoleOut, consoleFormatter); | ||
| else testConsole = new BufferedConsole(); | ||
| let extraTestEnvironmentOptions; | ||
| const docblockEnvironmentOptions = docblockPragmas["jest-environment-options"]; | ||
| if (typeof docblockEnvironmentOptions === "string") extraTestEnvironmentOptions = JSON.parse(docblockEnvironmentOptions); | ||
| const environment = new TestEnvironment({ | ||
| globalConfig, | ||
| projectConfig: extraTestEnvironmentOptions ? { | ||
| ...projectConfig, | ||
| testEnvironmentOptions: { | ||
| ...projectConfig.testEnvironmentOptions, | ||
| ...extraTestEnvironmentOptions | ||
| } | ||
| } : projectConfig | ||
| }, { | ||
| console: testConsole, | ||
| docblockPragmas, | ||
| testPath: path | ||
| }); | ||
| const loadTestEnvironmentEnd = Date.now(); | ||
| if (typeof environment.getVmContext !== "function") { | ||
| console.error(`Test environment found at "${testEnvironment}" does not export a "getVmContext" method, which is mandatory from Jest 27. This method is a replacement for "runScript".`); | ||
| process.exit(1); | ||
| } | ||
| const leakDetector = projectConfig.detectLeaks ? new LeakDetector(environment) : null; | ||
| setGlobal(environment.global, "console", testConsole, "retain"); | ||
| const runtime = new Runtime$1(projectConfig, environment, resolver, transformer, cacheFS, { | ||
| changedFiles: context.changedFiles, | ||
| collectCoverage: globalConfig.collectCoverage, | ||
| collectCoverageFrom: globalConfig.collectCoverageFrom, | ||
| coverageProvider: globalConfig.coverageProvider, | ||
| sourcesRelatedToTestsInChangedFiles: context.sourcesRelatedToTestsInChangedFiles | ||
| }, path, globalConfig); | ||
| let isTornDown = false; | ||
| const tearDownEnv = async () => { | ||
| if (!isTornDown) { | ||
| runtime.teardown(); | ||
| runInContext("Error.prepareStackTrace = () => '';", environment.getVmContext()); | ||
| sourcemapSupport.resetRetrieveHandlers(); | ||
| await environment.teardown(); | ||
| isTornDown = true; | ||
| } | ||
| }; | ||
| const start = Date.now(); | ||
| const setupFilesStart = Date.now(); | ||
| for (const path$1 of projectConfig.setupFiles) { | ||
| const esm = runtime.unstable_shouldLoadAsEsm(path$1); | ||
| if (esm) await runtime.unstable_importModule(path$1); | ||
| else { | ||
| const setupFile = runtime.requireModule(path$1); | ||
| if (typeof setupFile === "function") await setupFile(); | ||
| } | ||
| } | ||
| const setupFilesEnd = Date.now(); | ||
| const sourcemapOptions = { | ||
| environment: "node", | ||
| handleUncaughtExceptions: false, | ||
| retrieveSourceMap: (source) => { | ||
| const sourceMapSource = runtime.getSourceMaps()?.get(source); | ||
| if (sourceMapSource) try { | ||
| return { | ||
| map: JSON.parse(fs.readFileSync(sourceMapSource, "utf8")), | ||
| url: source | ||
| }; | ||
| } catch {} | ||
| return null; | ||
| } | ||
| }; | ||
| runtime.requireInternalModule(__require.resolve("source-map-support")).install(sourcemapOptions); | ||
| sourcemapSupport.install(sourcemapOptions); | ||
| if (environment.global && environment.global.process && environment.global.process.exit) { | ||
| const realExit = environment.global.process.exit; | ||
| environment.global.process.exit = function exit$1(...args) { | ||
| const error = new ErrorWithStack(`process.exit called with "${args.join(", ")}"`, exit$1); | ||
| const formattedError = formatExecError(error, projectConfig, { noStackTrace: false }, void 0, true); | ||
| process.stderr.write(formattedError); | ||
| return realExit(...args); | ||
| }; | ||
| } | ||
| const collectV8Coverage = globalConfig.collectCoverage && globalConfig.coverageProvider === "v8" && typeof environment.getVmContext === "function"; | ||
| Error.stackTraceLimit = 100; | ||
| try { | ||
| await environment.setup(); | ||
| let result; | ||
| try { | ||
| if (collectV8Coverage) await runtime.collectV8Coverage(); | ||
| result = await testFramework(globalConfig, projectConfig, environment, runtime, path, sendMessageToJest$1); | ||
| } catch (error) { | ||
| let e = error; | ||
| while (typeof e === "object" && e !== null && "stack" in e) { | ||
| e.stack; | ||
| e = e?.cause; | ||
| } | ||
| throw error; | ||
| } finally { | ||
| if (collectV8Coverage) await runtime.stopCollectingV8Coverage(); | ||
| } | ||
| freezeConsole(testConsole, projectConfig); | ||
| const testCount = result.numPassingTests + result.numFailingTests + result.numPendingTests + result.numTodoTests; | ||
| const end = Date.now(); | ||
| const testRuntime = end - start; | ||
| result.perfStats = { | ||
| ...result.perfStats, | ||
| end, | ||
| loadTestEnvironmentEnd, | ||
| loadTestEnvironmentStart, | ||
| runtime: testRuntime, | ||
| setupFilesEnd, | ||
| setupFilesStart, | ||
| slow: testRuntime / 1e3 > projectConfig.slowTestThreshold, | ||
| start | ||
| }; | ||
| result.testFilePath = path; | ||
| result.console = testConsole.getBuffer(); | ||
| result.skipped = testCount === result.numPendingTests; | ||
| result.displayName = projectConfig.displayName; | ||
| const coverage = runtime.getAllCoverageInfoCopy(); | ||
| if (coverage) { | ||
| const coverageKeys = Object.keys(coverage); | ||
| if (coverageKeys.length > 0) result.coverage = coverage; | ||
| } | ||
| if (collectV8Coverage) { | ||
| const v8Coverage = runtime.getAllV8CoverageInfoCopy(); | ||
| if (v8Coverage && v8Coverage.length > 0) result.v8Coverage = v8Coverage; | ||
| } | ||
| if (globalConfig.logHeapUsage) { | ||
| globalThis.gc?.(); | ||
| result.memoryUsage = process.memoryUsage().heapUsed; | ||
| } | ||
| await tearDownEnv(); | ||
| return await new Promise((resolve) => { | ||
| setImmediate(() => resolve({ | ||
| leakDetector, | ||
| result | ||
| })); | ||
| }); | ||
| } finally { | ||
| await tearDownEnv(); | ||
| } | ||
| } | ||
| async function runTest(path, globalConfig, config, resolver, context, sendMessageToJest$1) { | ||
| const { leakDetector, result } = await runTestInternal(path, globalConfig, config, resolver, context, sendMessageToJest$1); | ||
| if (leakDetector) { | ||
| await new Promise((resolve) => setTimeout(resolve, 100)); | ||
| result.leaks = await leakDetector.isLeaking(); | ||
| } else result.leaks = false; | ||
| return result; | ||
| } | ||
| //#endregion | ||
| //#region src/testWorker.ts | ||
| process.on("uncaughtException", (err) => { | ||
| if (err.stack) console.error(err.stack); | ||
| else console.error(err); | ||
| exit(1); | ||
| }); | ||
| const formatError = (error) => { | ||
| if (typeof error === "string") { | ||
| const { message, stack } = separateMessageFromStack(error); | ||
| return { | ||
| message, | ||
| stack, | ||
| type: "Error" | ||
| }; | ||
| } | ||
| return { | ||
| code: error.code || void 0, | ||
| message: error.message, | ||
| stack: error.stack, | ||
| type: "Error" | ||
| }; | ||
| }; | ||
| const resolvers = /* @__PURE__ */ new Map(); | ||
| const getResolver = (config) => { | ||
| const resolver = resolvers.get(config.id); | ||
| if (!resolver) throw new Error(`Cannot find resolver for: ${config.id}`); | ||
| return resolver; | ||
| }; | ||
| function setup(setupData) { | ||
| for (const { config, serializableModuleMap } of setupData.serializableResolvers) { | ||
| const moduleMap = HasteMap.getStatic(config).getModuleMapFromJSON(serializableModuleMap); | ||
| resolvers.set(config.id, Runtime.createResolver(config, moduleMap)); | ||
| } | ||
| } | ||
| const sendMessageToJest = (eventName, args) => { | ||
| messageParent([eventName, args]); | ||
| }; | ||
| async function worker({ config, globalConfig, path, context }) { | ||
| try { | ||
| return await runTest(path, globalConfig, config, getResolver(config), { | ||
| ...context, | ||
| changedFiles: context.changedFiles && new Set(context.changedFiles), | ||
| sourcesRelatedToTestsInChangedFiles: context.sourcesRelatedToTestsInChangedFiles && new Set(context.sourcesRelatedToTestsInChangedFiles) | ||
| }, sendMessageToJest); | ||
| } catch (error) { | ||
| throw formatError(error); | ||
| } | ||
| } | ||
| //#endregion | ||
| export { setup, worker }; |
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 2 instances
7
-30%44744
-24.34%6
-33.33%1175
-17.49%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated
Updated