@cldmv/vitest-runner 1.2.0 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,219 +0,0 @@
1
- /**
2
- * @fileoverview Child-process spawning helpers for running vitest.
3
- * @module vitest-runner/src/core/spawn
4
- */
5
-
6
- import { spawn } from "node:child_process";
7
- import { parseVitestOutput } from "./parse.mjs";
8
- import { buildNodeOptions } from "../utils/env.mjs";
9
-
10
- /**
11
- * @typedef {Object} SpawnBaseOptions
12
- * @property {string} cwd - Working directory for the child process.
13
- * @property {string} vitestBin - Absolute path to the vitest binary.
14
- * @property {string|undefined} vitestConfig - Vitest config path (omit to let vitest auto-detect).
15
- * @property {number|undefined} maxOldSpaceMb - Optional `--max-old-space-size` ceiling.
16
- * @property {string[]} [conditions=[]] - Additional `--conditions` flags.
17
- * @property {string} [nodeEnv='development'] - Value for `NODE_ENV`.
18
- */
19
-
20
- /**
21
- * Build the environment object for a vitest child process.
22
- * @param {Pick<SpawnBaseOptions, 'maxOldSpaceMb'|'conditions'|'nodeEnv'>} opts
23
- * @returns {NodeJS.ProcessEnv}
24
- */
25
- function buildEnv({ maxOldSpaceMb, conditions = [], nodeEnv = "development" }) {
26
- const env = { ...process.env };
27
- if (!env.NODE_ENV) env.NODE_ENV = nodeEnv;
28
-
29
- const nodeOptions = buildNodeOptions({ maxOldSpaceMb, conditions, base: env.NODE_OPTIONS ?? "" });
30
- if (nodeOptions) env.NODE_OPTIONS = nodeOptions;
31
-
32
- return env;
33
- }
34
-
35
- /**
36
- * Build the base argument list `[vitestBin, ...configArgs, 'run']`.
37
- * @param {string} vitestBin
38
- * @param {string|undefined} vitestConfig
39
- * @returns {string[]}
40
- */
41
- function buildBaseArgs(vitestBin, vitestConfig) {
42
- const configArgs = vitestConfig ? ["--config", vitestConfig] : [];
43
- return [vitestBin, ...configArgs, "run"];
44
- }
45
-
46
- /**
47
- * @typedef {Object} SingleFileResult
48
- * @property {string} file - Test file path.
49
- * @property {number} code - Process exit code.
50
- * @property {number} duration - Run duration in milliseconds.
51
- * @property {number} testFilesPass
52
- * @property {number} testFilesFail
53
- * @property {number} testsPass
54
- * @property {number} testsFail
55
- * @property {number} testsSkip
56
- * @property {number|null} heapMb
57
- * @property {string[]} errors
58
- * @property {string} rawOutput
59
- */
60
-
61
- /**
62
- * Run a single Vitest test file in a child process and return parsed results.
63
- *
64
- * @param {string} filePath - Test file path (relative to `cwd` or absolute).
65
- * @param {SpawnBaseOptions & { vitestArgs?: string[], streamOutput?: boolean }} opts
66
- * @returns {Promise<SingleFileResult>}
67
- * @example
68
- * const result = await runSingleFile('src/tests/foo.test.vitest.mjs', {
69
- * cwd: '/project',
70
- * vitestBin: '/project/node_modules/.bin/vitest',
71
- * vitestConfig: '/project/vitest.config.ts',
72
- * });
73
- */
74
- export function runSingleFile(filePath, opts) {
75
- const {
76
- cwd,
77
- vitestBin,
78
- vitestConfig,
79
- maxOldSpaceMb,
80
- conditions = [],
81
- nodeEnv = "development",
82
- vitestArgs = [],
83
- streamOutput = true
84
- } = opts;
85
-
86
- return new Promise((resolve) => {
87
- const startTime = Date.now();
88
- const args = [...buildBaseArgs(vitestBin, vitestConfig), ...vitestArgs, filePath];
89
- const env = buildEnv({ maxOldSpaceMb, conditions, nodeEnv });
90
-
91
- const child = spawn(process.execPath, args, { cwd, stdio: ["ignore", "pipe", "pipe"], env });
92
-
93
- let stdout = "";
94
- let stderr = "";
95
-
96
- child.stdout?.on("data", (data) => {
97
- stdout += data.toString();
98
- if (streamOutput) process.stdout.write(data);
99
- });
100
-
101
- child.stderr?.on("data", (data) => {
102
- stderr += data.toString();
103
- if (streamOutput) process.stderr.write(data);
104
- });
105
-
106
- child.on("close", (code) => {
107
- const spawnDuration = Date.now() - startTime;
108
- const output = `${stdout}\n${stderr}`;
109
- const parsed = parseVitestOutput(output);
110
-
111
- resolve({
112
- file: filePath,
113
- code: code ?? 1,
114
- // c8 ignore next -- false branch verified manually; V8 ternary probe mismatch inside object literal
115
- duration: parsed.duration > 0 ? parsed.duration : spawnDuration,
116
- testFilesPass: parsed.testFilesPass,
117
- testFilesFail: parsed.testFilesFail,
118
- testsPass: parsed.testsPass,
119
- testsFail: parsed.testsFail,
120
- testsSkip: parsed.testsSkip,
121
- heapMb: parsed.heapMb,
122
- errors: parsed.errors,
123
- rawOutput: output
124
- });
125
- });
126
-
127
- child.on("error", (err) => {
128
- resolve({
129
- file: filePath,
130
- code: 1,
131
- duration: Date.now() - startTime,
132
- testFilesPass: 0,
133
- testFilesFail: 1,
134
- testsPass: 0,
135
- testsFail: 0,
136
- testsSkip: 0,
137
- heapMb: null,
138
- errors: [err.message],
139
- rawOutput: err.toString()
140
- });
141
- });
142
- });
143
- }
144
-
145
- /**
146
- * Run Vitest directly (all files in one process) with inherited stdio.
147
- *
148
- * @param {SpawnBaseOptions & { vitestArgs?: string[] }} opts
149
- * @returns {Promise<number>} Process exit code.
150
- * @example
151
- * const code = await runVitestDirect({
152
- * cwd: '/project',
153
- * vitestBin: '/project/node_modules/.bin/vitest',
154
- * vitestArgs: ['--reporter=verbose'],
155
- * });
156
- */
157
- export function runVitestDirect(opts) {
158
- const { cwd, vitestBin, vitestConfig, maxOldSpaceMb, conditions = [], nodeEnv = "development", vitestArgs = [] } = opts;
159
-
160
- return new Promise((resolve) => {
161
- const args = [...buildBaseArgs(vitestBin, vitestConfig), ...vitestArgs];
162
- const env = buildEnv({ maxOldSpaceMb, conditions, nodeEnv });
163
-
164
- const child = spawn(process.execPath, args, { cwd, stdio: "inherit", env });
165
- child.on("close", (code) => resolve(code ?? 1));
166
- child.on("error", () => resolve(1));
167
- });
168
- }
169
-
170
- /**
171
- * Merge blob reports from individual coverage runs into a single coverage report
172
- * using `vitest --mergeReports`.
173
- *
174
- * @param {string} blobsDir - Directory containing the `.blob` files to merge.
175
- * @param {SpawnBaseOptions & { extraCoverageArgs?: string[], quietOutput?: boolean }} opts
176
- * @returns {Promise<{ exitCode: number, output: string }>}
177
- * @example
178
- * const { exitCode } = await runMergeReports('/project/.vitest-blobs', {
179
- * cwd: '/project',
180
- * vitestBin: '/project/node_modules/.bin/vitest',
181
- * });
182
- */
183
- export function runMergeReports(blobsDir, opts) {
184
- const {
185
- cwd,
186
- vitestBin,
187
- vitestConfig,
188
- maxOldSpaceMb,
189
- conditions = [],
190
- nodeEnv = "development",
191
- extraCoverageArgs = [],
192
- quietOutput = false
193
- } = opts;
194
-
195
- return new Promise((resolve) => {
196
- const configArgs = vitestConfig ? ["--config", vitestConfig] : [];
197
- const mergeReporterArgs = quietOutput ? ["--color"] : [];
198
-
199
- const args = [vitestBin, ...configArgs, "--mergeReports", blobsDir, "--run", "--coverage", ...mergeReporterArgs, ...extraCoverageArgs];
200
-
201
- const env = buildEnv({ maxOldSpaceMb, conditions, nodeEnv });
202
- const child = spawn(process.execPath, args, {
203
- cwd,
204
- stdio: quietOutput ? ["ignore", "pipe", "pipe"] : "inherit",
205
- env
206
- });
207
-
208
- let stdout = "";
209
- let stderr = "";
210
-
211
- if (quietOutput) {
212
- child.stdout?.on("data", (data) => (stdout += data.toString()));
213
- child.stderr?.on("data", (data) => (stderr += data.toString()));
214
- }
215
-
216
- child.on("close", (code) => resolve({ exitCode: code ?? 1, output: `${stdout}\n${stderr}` }));
217
- child.on("error", () => resolve({ exitCode: 1, output: "" }));
218
- });
219
- }