vitest 4.0.0-beta.6 → 4.0.0-beta.8
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.
- package/dist/browser.d.ts +3 -3
- package/dist/chunks/{browser.d.Cawq_X_N.d.ts → browser.d.DOMmqJQx.d.ts} +1 -1
- package/dist/chunks/{cac.WE-urWw5.js → cac.By1HvRIk.js} +7 -7
- package/dist/chunks/{cli-api.CZz3evYC.js → cli-api.C-JHgQgp.js} +383 -210
- package/dist/chunks/{config.d.CKNVOKm0.d.ts → config.d._GBBbReY.d.ts} +1 -0
- package/dist/chunks/{coverage.BPRS6xgn.js → coverage.DarITf6U.js} +7 -7
- package/dist/chunks/{index.VNI-1z5c.js → index.AzwzFtyi.js} +14 -5
- package/dist/chunks/{index.7w0eqmYM.js → index.BuwjkI-q.js} +1 -1
- package/dist/chunks/{index.BG0gqZH-.js → index.DfviD7lX.js} +16 -8
- package/dist/chunks/{moduleRunner.d.8kKUsuDg.d.ts → moduleRunner.d.CX4DuqOx.d.ts} +1 -1
- package/dist/chunks/{plugin.d.DuiQJfUL.d.ts → plugin.d.CHe6slQs.d.ts} +1 -1
- package/dist/chunks/{reporters.d.CqR9-CDJ.d.ts → reporters.d.37tJQ2uV.d.ts} +950 -995
- package/dist/chunks/{typechecker.Cd1wvxUM.js → typechecker.DSo_maXz.js} +1 -1
- package/dist/chunks/{worker.d.Db-UVmXc.d.ts → worker.d.BKu8cnnX.d.ts} +1 -1
- package/dist/chunks/{worker.d.D9QWnzAe.d.ts → worker.d.DYlqbejz.d.ts} +1 -1
- package/dist/cli.js +3 -3
- package/dist/config.d.ts +9 -9
- package/dist/coverage.d.ts +7 -7
- package/dist/coverage.js +2 -2
- package/dist/environments.js +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/module-evaluator.d.ts +3 -3
- package/dist/node.d.ts +24 -12
- package/dist/node.js +11 -16
- package/dist/reporters.d.ts +7 -7
- package/dist/reporters.js +3 -3
- package/dist/runners.d.ts +1 -1
- package/dist/worker.js +1 -1
- package/dist/workers.d.ts +3 -3
- package/dist/workers.js +1 -1
- package/package.json +10 -11
|
@@ -2,16 +2,17 @@ import fs, { promises, existsSync, readFileSync, mkdirSync, writeFileSync } from
|
|
|
2
2
|
import { relative, resolve, dirname, extname, normalize, join, basename, isAbsolute } from 'pathe';
|
|
3
3
|
import { C as CoverageProviderMap } from './coverage.D_JHT54q.js';
|
|
4
4
|
import path, { resolve as resolve$1 } from 'node:path';
|
|
5
|
-
import { noop,
|
|
5
|
+
import { noop, createDefer, slash, highlight, toArray, cleanUrl, deepMerge, KNOWN_ASSET_RE, nanoid, deepClone, isPrimitive, notNullish } from '@vitest/utils';
|
|
6
6
|
import { f as findUp, p as prompt } from './index.X0nbfr6-.js';
|
|
7
7
|
import * as vite from 'vite';
|
|
8
|
-
import { searchForWorkspaceRoot, version, mergeConfig, createServer } from 'vite';
|
|
8
|
+
import { parseAst, searchForWorkspaceRoot, version, mergeConfig, createServer } from 'vite';
|
|
9
9
|
import { A as API_PATH, c as configFiles, d as defaultBrowserPort, a as defaultPort } from './constants.D_Q9UYh-.js';
|
|
10
|
-
import
|
|
10
|
+
import nodeos__default, { tmpdir } from 'node:os';
|
|
11
|
+
import { generateHash as generateHash$1, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, generateFileHash, limitConcurrency, createFileTask as createFileTask$1, hasFailed, getTasks, getTests } from '@vitest/runner/utils';
|
|
11
12
|
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
12
|
-
import { v as version$1 } from './cac.
|
|
13
|
+
import { v as version$1 } from './cac.By1HvRIk.js';
|
|
13
14
|
import { c as createBirpc } from './index.Bgo3tNWt.js';
|
|
14
|
-
import { p as parse, s as stringify, d as printError, f as formatProjectName, w as withLabel, e as errorBanner, h as divider, i as generateCodeFrame, R as ReportersMap, B as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.
|
|
15
|
+
import { p as parse, s as stringify, d as printError, f as formatProjectName, w as withLabel, e as errorBanner, h as divider, i as generateCodeFrame, R as ReportersMap, B as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.AzwzFtyi.js';
|
|
15
16
|
import require$$0$3 from 'events';
|
|
16
17
|
import require$$1$1 from 'https';
|
|
17
18
|
import require$$2 from 'http';
|
|
@@ -23,11 +24,12 @@ import require$$7 from 'url';
|
|
|
23
24
|
import require$$0 from 'zlib';
|
|
24
25
|
import require$$0$1 from 'buffer';
|
|
25
26
|
import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
|
|
26
|
-
import { parseErrorStacktrace } from '@vitest/utils/source-map';
|
|
27
27
|
import crypto, { createHash } from 'node:crypto';
|
|
28
28
|
import { distDir, rootDir } from '../path.js';
|
|
29
|
-
import { h as hash, d as createFetchModuleFunction, n as normalizeResolvedIdToUrl, R as RandomSequencer, i as isPackageExists, g as getFilePoolName, e as isBrowserEnabled, r as resolveConfig, f as groupBy, j as getCoverageProvider, k as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.
|
|
30
|
-
import { c as convertTasksToEvents } from './typechecker.
|
|
29
|
+
import { h as hash, d as createFetchModuleFunction, n as normalizeResolvedIdToUrl, R as RandomSequencer, i as isPackageExists, g as getFilePoolName, e as isBrowserEnabled, r as resolveConfig, f as groupBy, j as getCoverageProvider, k as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.DarITf6U.js';
|
|
30
|
+
import { b as ancestor, c as convertTasksToEvents } from './typechecker.DSo_maXz.js';
|
|
31
|
+
import { TraceMap, originalPositionFor, parseErrorStacktrace } from '@vitest/utils/source-map';
|
|
32
|
+
import createDebug from 'debug';
|
|
31
33
|
import { VitestModuleEvaluator } from '#module-evaluator';
|
|
32
34
|
import { ModuleRunner } from 'vite/module-runner';
|
|
33
35
|
import { Console } from 'node:console';
|
|
@@ -36,7 +38,6 @@ import { createRequire, builtinModules, isBuiltin } from 'node:module';
|
|
|
36
38
|
import url, { pathToFileURL } from 'node:url';
|
|
37
39
|
import { i as isTTY, a as isWindows } from './env.D4Lgay0q.js';
|
|
38
40
|
import { rm, mkdir, copyFile } from 'node:fs/promises';
|
|
39
|
-
import nodeos__default, { tmpdir } from 'node:os';
|
|
40
41
|
import pm from 'picomatch';
|
|
41
42
|
import { glob, isDynamicPattern } from 'tinyglobby';
|
|
42
43
|
import MagicString from 'magic-string';
|
|
@@ -44,9 +45,9 @@ import { hoistMocksPlugin, automockPlugin } from '@vitest/mocker/node';
|
|
|
44
45
|
import { c as configDefaults } from './defaults.CXFFjsi8.js';
|
|
45
46
|
import { f as findNearestPackageData } from './resolver.Bx6lE0iq.js';
|
|
46
47
|
import * as esModuleLexer from 'es-module-lexer';
|
|
47
|
-
import { a as BenchmarkReportsMap } from './index.
|
|
48
|
+
import { a as BenchmarkReportsMap } from './index.BuwjkI-q.js';
|
|
48
49
|
import assert$1 from 'node:assert';
|
|
49
|
-
import { serializeError } from '@vitest/utils/error';
|
|
50
|
+
import { serializeError as serializeError$1 } from '@vitest/utils/error';
|
|
50
51
|
import readline from 'node:readline';
|
|
51
52
|
import { stripVTControlCharacters } from 'node:util';
|
|
52
53
|
|
|
@@ -5080,7 +5081,7 @@ catch {}
|
|
|
5080
5081
|
}
|
|
5081
5082
|
|
|
5082
5083
|
function setup(ctx, _server) {
|
|
5083
|
-
const wss = new WebSocketServer({ noServer: true }), clients = /* @__PURE__ */ new Map(), server = _server || ctx.
|
|
5084
|
+
const wss = new WebSocketServer({ noServer: true }), clients = /* @__PURE__ */ new Map(), server = _server || ctx.vite;
|
|
5084
5085
|
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
5085
5086
|
if (!request.url) return;
|
|
5086
5087
|
const { pathname } = new URL(request.url, "http://localhost");
|
|
@@ -5199,17 +5200,9 @@ class WebSocketReporter {
|
|
|
5199
5200
|
});
|
|
5200
5201
|
}
|
|
5201
5202
|
async onTaskUpdate(packs, events) {
|
|
5202
|
-
this.clients.size !== 0 &&
|
|
5203
|
-
const task = this.ctx.state.idMap.get(taskId), isBrowser = task && task.file.pool === "browser";
|
|
5204
|
-
result?.errors?.forEach((error) => {
|
|
5205
|
-
if (!isPrimitive(error)) if (isBrowser) {
|
|
5206
|
-
const project = this.ctx.getProjectByName(task.file.projectName || "");
|
|
5207
|
-
error.stacks = project.browser?.parseErrorStacktrace(error);
|
|
5208
|
-
} else error.stacks = parseErrorStacktrace(error);
|
|
5209
|
-
});
|
|
5210
|
-
}), this.clients.forEach((client) => {
|
|
5203
|
+
this.clients.size !== 0 && this.clients.forEach((client) => {
|
|
5211
5204
|
client.onTaskUpdate?.(packs, events)?.catch?.(noop);
|
|
5212
|
-
})
|
|
5205
|
+
});
|
|
5213
5206
|
}
|
|
5214
5207
|
onTestRunEnd(testModules, unhandledErrors) {
|
|
5215
5208
|
if (!this.clients.size) return;
|
|
@@ -5236,6 +5229,265 @@ var setup$1 = /*#__PURE__*/Object.freeze({
|
|
|
5236
5229
|
setup: setup
|
|
5237
5230
|
});
|
|
5238
5231
|
|
|
5232
|
+
function createDebugger(namespace) {
|
|
5233
|
+
const debug = createDebug(namespace);
|
|
5234
|
+
if (debug.enabled) return debug;
|
|
5235
|
+
}
|
|
5236
|
+
|
|
5237
|
+
const debug = createDebugger("vitest:ast-collect-info"), verbose = createDebugger("vitest:ast-collect-verbose");
|
|
5238
|
+
function astParseFile(filepath, code) {
|
|
5239
|
+
const ast = parseAst(code);
|
|
5240
|
+
if (verbose) verbose("Collecting", filepath, code);
|
|
5241
|
+
else debug?.("Collecting", filepath);
|
|
5242
|
+
const definitions = [], getName = (callee) => {
|
|
5243
|
+
if (!callee) return null;
|
|
5244
|
+
if (callee.type === "Identifier") return callee.name;
|
|
5245
|
+
if (callee.type === "CallExpression") return getName(callee.callee);
|
|
5246
|
+
if (callee.type === "TaggedTemplateExpression") return getName(callee.tag);
|
|
5247
|
+
if (callee.type === "MemberExpression")
|
|
5248
|
+
// call as `__vite_ssr__.test.skip()`
|
|
5249
|
+
return callee.object?.type === "Identifier" && [
|
|
5250
|
+
"it",
|
|
5251
|
+
"test",
|
|
5252
|
+
"describe",
|
|
5253
|
+
"suite"
|
|
5254
|
+
].includes(callee.object.name) ? callee.object?.name : callee.object?.name?.startsWith("__vite_ssr_") || callee.object?.object?.name?.startsWith("__vite_ssr_") && callee.object?.property?.name === "Vitest" ? getName(callee.property) : getName(callee.object?.property);
|
|
5255
|
+
// unwrap (0, ...)
|
|
5256
|
+
if (callee.type === "SequenceExpression" && callee.expressions.length === 2) {
|
|
5257
|
+
const [e0, e1] = callee.expressions;
|
|
5258
|
+
if (e0.type === "Literal" && e0.value === 0) return getName(e1);
|
|
5259
|
+
}
|
|
5260
|
+
return null;
|
|
5261
|
+
};
|
|
5262
|
+
return ancestor(ast, { CallExpression(node) {
|
|
5263
|
+
const { callee } = node, name = getName(callee);
|
|
5264
|
+
if (!name) return;
|
|
5265
|
+
if (![
|
|
5266
|
+
"it",
|
|
5267
|
+
"test",
|
|
5268
|
+
"describe",
|
|
5269
|
+
"suite"
|
|
5270
|
+
].includes(name)) {
|
|
5271
|
+
verbose?.(`Skipping ${name} (unknown call)`);
|
|
5272
|
+
return;
|
|
5273
|
+
}
|
|
5274
|
+
const property = callee?.property?.name;
|
|
5275
|
+
let mode = !property || property === name ? "run" : property;
|
|
5276
|
+
// they will be picked up in the next iteration
|
|
5277
|
+
if ([
|
|
5278
|
+
"each",
|
|
5279
|
+
"for",
|
|
5280
|
+
"skipIf",
|
|
5281
|
+
"runIf"
|
|
5282
|
+
].includes(mode)) return;
|
|
5283
|
+
let start;
|
|
5284
|
+
const end = node.end;
|
|
5285
|
+
// .each or (0, __vite_ssr_exports_0__.test)()
|
|
5286
|
+
if (callee.type === "CallExpression" || callee.type === "SequenceExpression" || callee.type === "TaggedTemplateExpression") start = callee.end;
|
|
5287
|
+
else start = node.start;
|
|
5288
|
+
const messageNode = node.arguments?.[0];
|
|
5289
|
+
if (messageNode == null) {
|
|
5290
|
+
verbose?.(`Skipping node at ${node.start} because it doesn't have a name`);
|
|
5291
|
+
return;
|
|
5292
|
+
}
|
|
5293
|
+
let message;
|
|
5294
|
+
if (messageNode?.type === "Literal" || messageNode?.type === "TemplateLiteral") message = code.slice(messageNode.start + 1, messageNode.end - 1);
|
|
5295
|
+
else message = code.slice(messageNode.start, messageNode.end);
|
|
5296
|
+
if (message.startsWith("0,")) message = message.slice(2);
|
|
5297
|
+
// cannot statically analyze, so we always skip it
|
|
5298
|
+
if (message = message.replace(/__vite_ssr_import_\d+__\./g, "").replace(/__vi_import_\d+__\./g, ""), mode === "skipIf" || mode === "runIf") mode = "skip";
|
|
5299
|
+
const parentCalleeName = typeof callee?.callee === "object" && callee?.callee.type === "MemberExpression" && callee?.callee.property?.name;
|
|
5300
|
+
let isDynamicEach = parentCalleeName === "each" || parentCalleeName === "for";
|
|
5301
|
+
if (!isDynamicEach && callee.type === "TaggedTemplateExpression") {
|
|
5302
|
+
const property = callee.tag?.property?.name;
|
|
5303
|
+
isDynamicEach = property === "each" || property === "for";
|
|
5304
|
+
}
|
|
5305
|
+
debug?.("Found", name, message, `(${mode})`), definitions.push({
|
|
5306
|
+
start,
|
|
5307
|
+
end,
|
|
5308
|
+
name: message,
|
|
5309
|
+
type: name === "it" || name === "test" ? "test" : "suite",
|
|
5310
|
+
mode,
|
|
5311
|
+
task: null,
|
|
5312
|
+
dynamic: isDynamicEach
|
|
5313
|
+
});
|
|
5314
|
+
} }), {
|
|
5315
|
+
ast,
|
|
5316
|
+
definitions
|
|
5317
|
+
};
|
|
5318
|
+
}
|
|
5319
|
+
function createFailedFileTask(project, filepath, error) {
|
|
5320
|
+
const testFilepath = relative(project.config.root, filepath), file = {
|
|
5321
|
+
filepath,
|
|
5322
|
+
type: "suite",
|
|
5323
|
+
id: /* @__PURE__ */ generateHash$1(`${testFilepath}${project.config.name || ""}`),
|
|
5324
|
+
name: testFilepath,
|
|
5325
|
+
mode: "run",
|
|
5326
|
+
tasks: [],
|
|
5327
|
+
start: 0,
|
|
5328
|
+
end: 0,
|
|
5329
|
+
projectName: project.name,
|
|
5330
|
+
meta: {},
|
|
5331
|
+
pool: project.browser ? "browser" : project.config.pool,
|
|
5332
|
+
file: null,
|
|
5333
|
+
result: {
|
|
5334
|
+
state: "fail",
|
|
5335
|
+
errors: serializeError(project, error)
|
|
5336
|
+
}
|
|
5337
|
+
};
|
|
5338
|
+
return file.file = file, file;
|
|
5339
|
+
}
|
|
5340
|
+
function serializeError(ctx, error) {
|
|
5341
|
+
if ("errors" in error && "pluginCode" in error) {
|
|
5342
|
+
const errors = error.errors.map((e) => {
|
|
5343
|
+
return {
|
|
5344
|
+
name: error.name,
|
|
5345
|
+
message: e.text,
|
|
5346
|
+
stack: e.location ? `${error.name}: ${e.text}\n at ${relative(ctx.config.root, e.location.file)}:${e.location.line}:${e.location.column}` : ""
|
|
5347
|
+
};
|
|
5348
|
+
});
|
|
5349
|
+
return errors;
|
|
5350
|
+
}
|
|
5351
|
+
return [{
|
|
5352
|
+
name: error.name,
|
|
5353
|
+
stack: error.stack,
|
|
5354
|
+
message: error.message
|
|
5355
|
+
}];
|
|
5356
|
+
}
|
|
5357
|
+
function createFileTask(testFilepath, code, requestMap, options) {
|
|
5358
|
+
const { definitions, ast } = astParseFile(testFilepath, code), file = {
|
|
5359
|
+
filepath: options.filepath,
|
|
5360
|
+
type: "suite",
|
|
5361
|
+
id: /* @__PURE__ */ generateHash$1(`${testFilepath}${options.name || ""}`),
|
|
5362
|
+
name: testFilepath,
|
|
5363
|
+
mode: "run",
|
|
5364
|
+
tasks: [],
|
|
5365
|
+
start: ast.start,
|
|
5366
|
+
end: ast.end,
|
|
5367
|
+
projectName: options.name,
|
|
5368
|
+
meta: {},
|
|
5369
|
+
pool: "browser",
|
|
5370
|
+
file: null
|
|
5371
|
+
};
|
|
5372
|
+
file.file = file;
|
|
5373
|
+
const indexMap = createIndexMap(code), map = requestMap && new TraceMap(requestMap);
|
|
5374
|
+
let lastSuite = file;
|
|
5375
|
+
const updateLatestSuite = (index) => {
|
|
5376
|
+
while (lastSuite.suite && lastSuite.end < index) lastSuite = lastSuite.suite;
|
|
5377
|
+
return lastSuite;
|
|
5378
|
+
};
|
|
5379
|
+
definitions.sort((a, b) => a.start - b.start).forEach((definition) => {
|
|
5380
|
+
const latestSuite = updateLatestSuite(definition.start);
|
|
5381
|
+
let mode = definition.mode;
|
|
5382
|
+
if (latestSuite.mode !== "run")
|
|
5383
|
+
// inherit suite mode, if it's set
|
|
5384
|
+
mode = latestSuite.mode;
|
|
5385
|
+
const processedLocation = indexMap.get(definition.start);
|
|
5386
|
+
let location;
|
|
5387
|
+
if (map && processedLocation) {
|
|
5388
|
+
const originalLocation = originalPositionFor(map, {
|
|
5389
|
+
line: processedLocation.line,
|
|
5390
|
+
column: processedLocation.column
|
|
5391
|
+
});
|
|
5392
|
+
if (originalLocation.column != null) verbose?.(`Found location for`, definition.type, definition.name, `${processedLocation.line}:${processedLocation.column}`, "->", `${originalLocation.line}:${originalLocation.column}`), location = originalLocation;
|
|
5393
|
+
else debug?.("Cannot find original location for", definition.type, definition.name, `${processedLocation.column}:${processedLocation.line}`);
|
|
5394
|
+
} else debug?.("Cannot find original location for", definition.type, definition.name, `${definition.start}`);
|
|
5395
|
+
if (definition.type === "suite") {
|
|
5396
|
+
const task = {
|
|
5397
|
+
type: definition.type,
|
|
5398
|
+
id: "",
|
|
5399
|
+
suite: latestSuite,
|
|
5400
|
+
file,
|
|
5401
|
+
tasks: [],
|
|
5402
|
+
mode,
|
|
5403
|
+
name: definition.name,
|
|
5404
|
+
end: definition.end,
|
|
5405
|
+
start: definition.start,
|
|
5406
|
+
location,
|
|
5407
|
+
dynamic: definition.dynamic,
|
|
5408
|
+
meta: {}
|
|
5409
|
+
};
|
|
5410
|
+
definition.task = task, latestSuite.tasks.push(task), lastSuite = task;
|
|
5411
|
+
return;
|
|
5412
|
+
}
|
|
5413
|
+
const task = {
|
|
5414
|
+
type: definition.type,
|
|
5415
|
+
id: "",
|
|
5416
|
+
suite: latestSuite,
|
|
5417
|
+
file,
|
|
5418
|
+
mode,
|
|
5419
|
+
context: {},
|
|
5420
|
+
name: definition.name,
|
|
5421
|
+
end: definition.end,
|
|
5422
|
+
start: definition.start,
|
|
5423
|
+
location,
|
|
5424
|
+
dynamic: definition.dynamic,
|
|
5425
|
+
meta: {},
|
|
5426
|
+
timeout: 0,
|
|
5427
|
+
annotations: []
|
|
5428
|
+
};
|
|
5429
|
+
definition.task = task, latestSuite.tasks.push(task);
|
|
5430
|
+
}), calculateSuiteHash(file);
|
|
5431
|
+
const hasOnly = someTasksAreOnly(file);
|
|
5432
|
+
if (interpretTaskModes(file, options.testNamePattern, void 0, hasOnly, false, options.allowOnly), markDynamicTests(file.tasks), !file.tasks.length) file.result = {
|
|
5433
|
+
state: "fail",
|
|
5434
|
+
errors: [{
|
|
5435
|
+
name: "Error",
|
|
5436
|
+
message: `No test suite found in file ${options.filepath}`
|
|
5437
|
+
}]
|
|
5438
|
+
};
|
|
5439
|
+
return file;
|
|
5440
|
+
}
|
|
5441
|
+
async function astCollectTests(project, filepath) {
|
|
5442
|
+
const request = await transformSSR(project, filepath), testFilepath = relative(project.config.root, filepath);
|
|
5443
|
+
return request ? createFileTask(testFilepath, request.code, request.map, {
|
|
5444
|
+
name: project.config.name,
|
|
5445
|
+
filepath,
|
|
5446
|
+
allowOnly: project.config.allowOnly,
|
|
5447
|
+
testNamePattern: project.config.testNamePattern,
|
|
5448
|
+
pool: project.browser ? "browser" : project.config.pool
|
|
5449
|
+
}) : (debug?.("Cannot parse", testFilepath, "(vite didn't return anything)"), createFailedFileTask(project, filepath, /* @__PURE__ */ new Error(`Failed to parse ${testFilepath}. Vite didn't return anything.`)));
|
|
5450
|
+
}
|
|
5451
|
+
async function transformSSR(project, filepath) {
|
|
5452
|
+
const request = await project.vite.transformRequest(filepath, { ssr: false });
|
|
5453
|
+
return request ? await project.vite.ssrTransform(request.code, request.map, filepath) : null;
|
|
5454
|
+
}
|
|
5455
|
+
function createIndexMap(source) {
|
|
5456
|
+
const map = /* @__PURE__ */ new Map();
|
|
5457
|
+
let index = 0, line = 1, column = 1;
|
|
5458
|
+
for (const char of source) if (map.set(index++, {
|
|
5459
|
+
line,
|
|
5460
|
+
column
|
|
5461
|
+
}), char === "\n" || char === "\r\n") line++, column = 0;
|
|
5462
|
+
else column++;
|
|
5463
|
+
return map;
|
|
5464
|
+
}
|
|
5465
|
+
function markDynamicTests(tasks) {
|
|
5466
|
+
for (const task of tasks) {
|
|
5467
|
+
if (task.dynamic) task.id += "-dynamic";
|
|
5468
|
+
if ("tasks" in task) markDynamicTests(task.tasks);
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
function escapeRegex(str) {
|
|
5472
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5473
|
+
}
|
|
5474
|
+
const kReplacers = new Map([
|
|
5475
|
+
["%i", "\\d+?"],
|
|
5476
|
+
["%#", "\\d+?"],
|
|
5477
|
+
["%d", "[\\d.eE+-]+?"],
|
|
5478
|
+
["%f", "[\\d.eE+-]+?"],
|
|
5479
|
+
["%s", ".+?"],
|
|
5480
|
+
["%j", ".+?"],
|
|
5481
|
+
["%o", ".+?"],
|
|
5482
|
+
["%%", "%"]
|
|
5483
|
+
]);
|
|
5484
|
+
function escapeTestName(label, dynamic) {
|
|
5485
|
+
if (!dynamic) return escapeRegex(label);
|
|
5486
|
+
// Replace object access patterns ($value, $obj.a) with %s first
|
|
5487
|
+
let pattern = label.replace(/\$[a-z_.]+/gi, "%s");
|
|
5488
|
+
return pattern = escapeRegex(pattern), pattern = pattern.replace(/%[i#dfsjo%]/g, (m) => kReplacers.get(m) || m), pattern;
|
|
5489
|
+
}
|
|
5490
|
+
|
|
5239
5491
|
class BrowserSessions {
|
|
5240
5492
|
sessions = /* @__PURE__ */ new Map();
|
|
5241
5493
|
sessionIds = /* @__PURE__ */ new Set();
|
|
@@ -5269,7 +5521,7 @@ class FilesStatsCache {
|
|
|
5269
5521
|
}
|
|
5270
5522
|
async populateStats(root, specs) {
|
|
5271
5523
|
const promises = specs.map((spec) => {
|
|
5272
|
-
const key = `${spec
|
|
5524
|
+
const key = `${spec.project.name}:${relative(root, spec.moduleId)}`;
|
|
5273
5525
|
return this.updateStats(spec.moduleId, key);
|
|
5274
5526
|
});
|
|
5275
5527
|
await Promise.all(promises);
|
|
@@ -5521,10 +5773,10 @@ class Logger {
|
|
|
5521
5773
|
const color = this.ctx.config.watch ? "blue" : "cyan", mode = this.ctx.config.watch ? "DEV" : "RUN";
|
|
5522
5774
|
if (this.log(withLabel(color, mode, `v${this.ctx.version} `) + c.gray(this.ctx.config.root)), this.ctx.config.sequence.sequencer === RandomSequencer) this.log(PAD + c.gray(`Running tests with seed "${this.ctx.config.sequence.seed}"`));
|
|
5523
5775
|
if (this.ctx.config.ui) {
|
|
5524
|
-
const host = this.ctx.config.api?.host || "localhost", port = this.ctx.
|
|
5776
|
+
const host = this.ctx.config.api?.host || "localhost", port = this.ctx.vite.config.server.port, base = this.ctx.config.uiBase;
|
|
5525
5777
|
this.log(PAD + c.dim(c.green(`UI started at http://${host}:${c.bold(port)}${base}`)));
|
|
5526
5778
|
} else if (this.ctx.config.api?.port) {
|
|
5527
|
-
const resolvedUrls = this.ctx.
|
|
5779
|
+
const resolvedUrls = this.ctx.vite.resolvedUrls, fallbackUrl = `http://${this.ctx.config.api.host || "localhost"}:${this.ctx.config.api.port}`, origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] ?? fallbackUrl;
|
|
5528
5780
|
this.log(PAD + c.dim(c.green(`API started at ${new URL("/", origin)}`)));
|
|
5529
5781
|
}
|
|
5530
5782
|
if (this.ctx.coverageProvider) this.log(PAD + c.dim("Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name));
|
|
@@ -5711,7 +5963,8 @@ function serializeConfig(config, coreConfig, viteConfig) {
|
|
|
5711
5963
|
viewport: browser.viewport,
|
|
5712
5964
|
screenshotFailures: browser.screenshotFailures,
|
|
5713
5965
|
locators: { testIdAttribute: browser.locators.testIdAttribute },
|
|
5714
|
-
providerOptions: browser.provider === "playwright" ? { actionTimeout: browser.providerOptions?.context?.actionTimeout } : {}
|
|
5966
|
+
providerOptions: browser.provider === "playwright" ? { actionTimeout: browser.providerOptions?.context?.actionTimeout } : {},
|
|
5967
|
+
trackUnhandledErrors: browser.trackUnhandledErrors ?? true
|
|
5715
5968
|
};
|
|
5716
5969
|
})(config.browser),
|
|
5717
5970
|
standalone: config.standalone,
|
|
@@ -6587,7 +6840,7 @@ function VitestProjectResolver(ctx) {
|
|
|
6587
6840
|
if (id === "vitest" || id.startsWith("@vitest/") || id.startsWith("vitest/")) {
|
|
6588
6841
|
// always redirect the request to the root vitest plugin since
|
|
6589
6842
|
// it will be the one used to run Vitest
|
|
6590
|
-
const resolved = await ctx.
|
|
6843
|
+
const resolved = await ctx.vite.pluginContainer.resolveId(id, void 0, {
|
|
6591
6844
|
skip: new Set([plugin]),
|
|
6592
6845
|
ssr
|
|
6593
6846
|
});
|
|
@@ -6822,18 +7075,6 @@ function matchExternalizePattern(id, moduleDirectories, patterns) {
|
|
|
6822
7075
|
}
|
|
6823
7076
|
|
|
6824
7077
|
class TestSpecification {
|
|
6825
|
-
/**
|
|
6826
|
-
* @deprecated use `project` instead
|
|
6827
|
-
*/
|
|
6828
|
-
0;
|
|
6829
|
-
/**
|
|
6830
|
-
* @deprecated use `moduleId` instead
|
|
6831
|
-
*/
|
|
6832
|
-
1;
|
|
6833
|
-
/**
|
|
6834
|
-
* @deprecated use `pool` instead
|
|
6835
|
-
*/
|
|
6836
|
-
2;
|
|
6837
7078
|
/**
|
|
6838
7079
|
* The task ID associated with the test module.
|
|
6839
7080
|
*/
|
|
@@ -6856,7 +7097,6 @@ class TestSpecification {
|
|
|
6856
7097
|
*/
|
|
6857
7098
|
testLines;
|
|
6858
7099
|
constructor(project, moduleId, pool, testLines) {
|
|
6859
|
-
this[0] = project, this[1] = moduleId, this[2] = { pool };
|
|
6860
7100
|
const name = project.config.name, hashName = pool !== "typescript" ? name : name ? `${name}:__typecheck__` : "__typecheck__";
|
|
6861
7101
|
this.taskId = generateFileHash(relative(project.config.root, moduleId), hashName), this.project = project, this.moduleId = moduleId, this.pool = pool, this.testLines = testLines;
|
|
6862
7102
|
}
|
|
@@ -6880,13 +7120,6 @@ class TestSpecification {
|
|
|
6880
7120
|
}
|
|
6881
7121
|
];
|
|
6882
7122
|
}
|
|
6883
|
-
/**
|
|
6884
|
-
* for backwards compatibility
|
|
6885
|
-
* @deprecated
|
|
6886
|
-
*/
|
|
6887
|
-
*[Symbol.iterator]() {
|
|
6888
|
-
yield this.project, yield this.moduleId, yield this.pool;
|
|
6889
|
-
}
|
|
6890
7123
|
}
|
|
6891
7124
|
|
|
6892
7125
|
async function createViteServer(inlineConfig) {
|
|
@@ -6914,8 +7147,6 @@ class TestProject {
|
|
|
6914
7147
|
* Browser instance if the browser is enabled. This is initialized when the tests run for the first time.
|
|
6915
7148
|
*/
|
|
6916
7149
|
browser;
|
|
6917
|
-
/** @deprecated use `vitest` instead */
|
|
6918
|
-
ctx;
|
|
6919
7150
|
/**
|
|
6920
7151
|
* Temporary directory for the project. This is unique for each project. Vitest stores transformed content here.
|
|
6921
7152
|
*/
|
|
@@ -6925,14 +7156,14 @@ class TestProject {
|
|
|
6925
7156
|
/** @internal */ _vite;
|
|
6926
7157
|
/** @internal */ _hash;
|
|
6927
7158
|
/** @internal */ _resolver;
|
|
7159
|
+
/** @inetrnal */ testFilesList = null;
|
|
6928
7160
|
runner;
|
|
6929
7161
|
closingPromise;
|
|
6930
|
-
testFilesList = null;
|
|
6931
7162
|
typecheckFilesList = null;
|
|
6932
7163
|
_globalSetups;
|
|
6933
7164
|
_provided = {};
|
|
6934
|
-
constructor(
|
|
6935
|
-
this.
|
|
7165
|
+
constructor(vitest, options) {
|
|
7166
|
+
this.options = options, this.vitest = vitest, this.globalConfig = vitest.config;
|
|
6936
7167
|
}
|
|
6937
7168
|
/**
|
|
6938
7169
|
* The unique hash of this project. This value is consistent between the reruns.
|
|
@@ -7024,28 +7255,12 @@ class TestProject {
|
|
|
7024
7255
|
get serializedConfig() {
|
|
7025
7256
|
return this._serializeOverriddenConfig();
|
|
7026
7257
|
}
|
|
7027
|
-
/** @deprecated use `vite` instead */
|
|
7028
|
-
get server() {
|
|
7029
|
-
return this._vite;
|
|
7030
|
-
}
|
|
7031
7258
|
/**
|
|
7032
7259
|
* Check if this is the root project. The root project is the one that has the root config.
|
|
7033
7260
|
*/
|
|
7034
7261
|
isRootProject() {
|
|
7035
7262
|
return this.vitest.getRootProject() === this;
|
|
7036
7263
|
}
|
|
7037
|
-
/** @deprecated use `isRootProject` instead */
|
|
7038
|
-
isCore() {
|
|
7039
|
-
return this.isRootProject();
|
|
7040
|
-
}
|
|
7041
|
-
/** @deprecated use `createSpecification` instead */
|
|
7042
|
-
createSpec(moduleId, pool) {
|
|
7043
|
-
return new TestSpecification(this, moduleId, pool);
|
|
7044
|
-
}
|
|
7045
|
-
/** @deprecated */
|
|
7046
|
-
initializeGlobalSetup() {
|
|
7047
|
-
return this._initializeGlobalSetup();
|
|
7048
|
-
}
|
|
7049
7264
|
/** @internal */
|
|
7050
7265
|
async _initializeGlobalSetup() {
|
|
7051
7266
|
if (!this._globalSetups) {
|
|
@@ -7061,37 +7276,10 @@ class TestProject {
|
|
|
7061
7276
|
onTestsRerun(cb) {
|
|
7062
7277
|
this.vitest.onTestsRerun(cb);
|
|
7063
7278
|
}
|
|
7064
|
-
/** @deprecated */
|
|
7065
|
-
teardownGlobalSetup() {
|
|
7066
|
-
return this._teardownGlobalSetup();
|
|
7067
|
-
}
|
|
7068
7279
|
/** @internal */
|
|
7069
7280
|
async _teardownGlobalSetup() {
|
|
7070
7281
|
if (this._globalSetups) for (const globalSetupFile of [...this._globalSetups].reverse()) await globalSetupFile.teardown?.();
|
|
7071
7282
|
}
|
|
7072
|
-
/** @deprecated use `vitest.logger` instead */
|
|
7073
|
-
get logger() {
|
|
7074
|
-
return this.vitest.logger;
|
|
7075
|
-
}
|
|
7076
|
-
// it's possible that file path was imported with different queries (?raw, ?url, etc)
|
|
7077
|
-
/** @deprecated use `.vite` or `.browser.vite` directly */
|
|
7078
|
-
getModulesByFilepath(file) {
|
|
7079
|
-
const set = this.server.moduleGraph.getModulesByFile(file) || this.browser?.vite.moduleGraph.getModulesByFile(file);
|
|
7080
|
-
return set || /* @__PURE__ */ new Set();
|
|
7081
|
-
}
|
|
7082
|
-
/** @deprecated use `.vite` or `.browser.vite` directly */
|
|
7083
|
-
getModuleById(id) {
|
|
7084
|
-
return this.server.moduleGraph.getModuleById(id) || this.browser?.vite.moduleGraph.getModuleById(id);
|
|
7085
|
-
}
|
|
7086
|
-
/** @deprecated use `.vite` or `.browser.vite` directly */
|
|
7087
|
-
getSourceMapModuleById(id) {
|
|
7088
|
-
const mod = this.server.moduleGraph.getModuleById(id);
|
|
7089
|
-
return mod?.ssrTransformResult?.map || mod?.transformResult?.map;
|
|
7090
|
-
}
|
|
7091
|
-
/** @deprecated use `vitest.reporters` instead */
|
|
7092
|
-
get reporters() {
|
|
7093
|
-
return this.ctx.reporters;
|
|
7094
|
-
}
|
|
7095
7283
|
/**
|
|
7096
7284
|
* Get all files in the project that match the globs in the config and the filters.
|
|
7097
7285
|
* @param filters String filters to match the test files.
|
|
@@ -7143,10 +7331,6 @@ class TestProject {
|
|
|
7143
7331
|
_isCachedTypecheckFile(testPath) {
|
|
7144
7332
|
return !!this.typecheckFilesList && this.typecheckFilesList.includes(testPath);
|
|
7145
7333
|
}
|
|
7146
|
-
/** @deprecated use `serializedConfig` instead */
|
|
7147
|
-
getSerializableConfig() {
|
|
7148
|
-
return this._serializeOverriddenConfig();
|
|
7149
|
-
}
|
|
7150
7334
|
/** @internal */
|
|
7151
7335
|
async globFiles(include, exclude, cwd) {
|
|
7152
7336
|
const globOptions = {
|
|
@@ -7174,10 +7358,6 @@ class TestProject {
|
|
|
7174
7358
|
}
|
|
7175
7359
|
return false;
|
|
7176
7360
|
}
|
|
7177
|
-
/** @deprecated use `matchesTestGlob` instead */
|
|
7178
|
-
async isTargetFile(id, source) {
|
|
7179
|
-
return this.matchesTestGlob(id, source ? () => source : void 0);
|
|
7180
|
-
}
|
|
7181
7361
|
isInSourceTestCode(code) {
|
|
7182
7362
|
return code.includes("import.meta.vitest");
|
|
7183
7363
|
}
|
|
@@ -7242,14 +7422,6 @@ class TestProject {
|
|
|
7242
7422
|
import(moduleId) {
|
|
7243
7423
|
return this.runner.import(moduleId);
|
|
7244
7424
|
}
|
|
7245
|
-
/** @deprecated use `name` instead */
|
|
7246
|
-
getName() {
|
|
7247
|
-
return this.config.name || "";
|
|
7248
|
-
}
|
|
7249
|
-
/** @deprecated internal */
|
|
7250
|
-
setServer(options, server) {
|
|
7251
|
-
return this._configureServer(options, server);
|
|
7252
|
-
}
|
|
7253
7425
|
_setHash() {
|
|
7254
7426
|
this._hash = generateHash(this._config.root + this._config.name);
|
|
7255
7427
|
}
|
|
@@ -7277,10 +7449,6 @@ class TestProject {
|
|
|
7277
7449
|
await rm(this.tmpDir, { recursive: true });
|
|
7278
7450
|
} catch {}
|
|
7279
7451
|
}
|
|
7280
|
-
/** @deprecated */
|
|
7281
|
-
initBrowserProvider() {
|
|
7282
|
-
return this._initBrowserProvider();
|
|
7283
|
-
}
|
|
7284
7452
|
/** @internal */
|
|
7285
7453
|
_initBrowserProvider = deduped(async () => {
|
|
7286
7454
|
if (!(!this.isBrowserEnabled() || this.browser?.provider)) {
|
|
@@ -7298,12 +7466,12 @@ class TestProject {
|
|
|
7298
7466
|
}
|
|
7299
7467
|
/** @internal */
|
|
7300
7468
|
static _createBasicProject(vitest) {
|
|
7301
|
-
const project = new TestProject(vitest
|
|
7302
|
-
return project.runner = vitest.runner, project._vite = vitest.
|
|
7469
|
+
const project = new TestProject(vitest);
|
|
7470
|
+
return project.runner = vitest.runner, project._vite = vitest.vite, project._config = vitest.config, project._resolver = vitest._resolver, project._setHash(), project._provideObject(vitest.config.provide), project;
|
|
7303
7471
|
}
|
|
7304
7472
|
/** @internal */
|
|
7305
7473
|
static _cloneBrowserProject(parent, config) {
|
|
7306
|
-
const clone = new TestProject(parent.
|
|
7474
|
+
const clone = new TestProject(parent.vitest);
|
|
7307
7475
|
return clone.runner = parent.runner, clone._vite = parent._vite, clone._resolver = parent._resolver, clone._config = config, clone._setHash(), clone._parent = parent, clone._provideObject(config.provide), clone;
|
|
7308
7476
|
}
|
|
7309
7477
|
}
|
|
@@ -7317,7 +7485,7 @@ function deduped(cb) {
|
|
|
7317
7485
|
});
|
|
7318
7486
|
}
|
|
7319
7487
|
async function initializeProject(workspacePath, ctx, options) {
|
|
7320
|
-
const project = new TestProject(
|
|
7488
|
+
const project = new TestProject(ctx, options), { configFile,...restOptions } = options, config = {
|
|
7321
7489
|
...restOptions,
|
|
7322
7490
|
configFile,
|
|
7323
7491
|
configLoader: ctx.vite.config.inlineConfig.configLoader,
|
|
@@ -8073,6 +8241,9 @@ function getSuiteState(task) {
|
|
|
8073
8241
|
if (state === "pass") return "passed";
|
|
8074
8242
|
throw new Error(`Unknown suite state: ${state}`);
|
|
8075
8243
|
}
|
|
8244
|
+
function experimental_getRunnerTask(entity) {
|
|
8245
|
+
return entity.task;
|
|
8246
|
+
}
|
|
8076
8247
|
|
|
8077
8248
|
function isAggregateError(err) {
|
|
8078
8249
|
return typeof AggregateError !== "undefined" && err instanceof AggregateError ? true : err instanceof Error && "errors" in err;
|
|
@@ -8159,7 +8330,7 @@ class StateManager {
|
|
|
8159
8330
|
}
|
|
8160
8331
|
clearFiles(project, paths = []) {
|
|
8161
8332
|
paths.forEach((path) => {
|
|
8162
|
-
const files = this.filesMap.get(path), fileTask = createFileTask(path, project.config.root, project.config.name);
|
|
8333
|
+
const files = this.filesMap.get(path), fileTask = createFileTask$1(path, project.config.root, project.config.name);
|
|
8163
8334
|
if (fileTask.local = true, TestModule.register(fileTask, project), this.idMap.set(fileTask.id, fileTask), !files) {
|
|
8164
8335
|
this.filesMap.set(path, [fileTask]);
|
|
8165
8336
|
return;
|
|
@@ -8203,7 +8374,7 @@ class StateManager {
|
|
|
8203
8374
|
return Array.from(this.idMap.values()).filter((t) => t.result?.state === "fail").length;
|
|
8204
8375
|
}
|
|
8205
8376
|
cancelFiles(files, project) {
|
|
8206
|
-
this.collectFiles(project, files.map((filepath) => createFileTask(filepath, project.config.root, project.config.name)));
|
|
8377
|
+
this.collectFiles(project, files.map((filepath) => createFileTask$1(filepath, project.config.root, project.config.name)));
|
|
8207
8378
|
}
|
|
8208
8379
|
}
|
|
8209
8380
|
|
|
@@ -8686,9 +8857,9 @@ class TestRun {
|
|
|
8686
8857
|
return assert$1(task && entity, `Entity must be found for task ${task?.name || testId}`), assert$1(entity.type === "test", `Annotation can only be added to a test, instead got ${entity.type}`), await this.resolveTestAttachment(entity, annotation), entity.task.annotations.push(annotation), await this.vitest.report("onTestCaseAnnotate", entity, annotation), annotation;
|
|
8687
8858
|
}
|
|
8688
8859
|
async updated(update, events) {
|
|
8689
|
-
this.vitest.state.updateTasks(update);
|
|
8860
|
+
this.syncUpdateStacks(update), this.vitest.state.updateTasks(update);
|
|
8690
8861
|
for (const [id, event, data] of events) await this.reportEvent(id, event, data).catch((error) => {
|
|
8691
|
-
this.vitest.state.catchError(serializeError(error), "Unhandled Reporter Error");
|
|
8862
|
+
this.vitest.state.catchError(serializeError$1(error), "Unhandled Reporter Error");
|
|
8692
8863
|
});
|
|
8693
8864
|
// TODO: what is the order or reports here?
|
|
8694
8865
|
// "onTaskUpdate" in parallel with others or before all or after all?
|
|
@@ -8705,6 +8876,17 @@ class TestRun {
|
|
|
8705
8876
|
hasFailed(modules) {
|
|
8706
8877
|
return modules.length ? modules.some((m) => !m.ok()) : !this.vitest.config.passWithNoTests;
|
|
8707
8878
|
}
|
|
8879
|
+
syncUpdateStacks(update) {
|
|
8880
|
+
update.forEach(([taskId, result]) => {
|
|
8881
|
+
const task = this.vitest.state.idMap.get(taskId), isBrowser = task && task.file.pool === "browser";
|
|
8882
|
+
result?.errors?.forEach((error) => {
|
|
8883
|
+
if (isPrimitive(error)) return;
|
|
8884
|
+
const project = this.vitest.getProjectByName(task.file.projectName || "");
|
|
8885
|
+
if (isBrowser) error.stacks = project.browser?.parseErrorStacktrace(error, { frameFilter: project.config.onStackTrace }) || [];
|
|
8886
|
+
else error.stacks = parseErrorStacktrace(error, { frameFilter: project.config.onStackTrace });
|
|
8887
|
+
});
|
|
8888
|
+
});
|
|
8889
|
+
}
|
|
8708
8890
|
async reportEvent(id, event, data) {
|
|
8709
8891
|
const task = this.vitest.state.idMap.get(id), entity = task && this.vitest.state.getReportedEntity(task);
|
|
8710
8892
|
if (assert$1(task && entity, `Entity must be found for task ${task?.name || id}`), event === "suite-prepare" && entity.type === "suite") return await this.vitest.report("onTestSuiteReady", entity);
|
|
@@ -8786,8 +8968,8 @@ class VitestWatcher {
|
|
|
8786
8968
|
registerWatcher() {
|
|
8787
8969
|
const watcher = this.vitest.vite.watcher;
|
|
8788
8970
|
if (this.vitest.config.forceRerunTriggers.length) watcher.add(this.vitest.config.forceRerunTriggers);
|
|
8789
|
-
return watcher.on("change", this.
|
|
8790
|
-
watcher.off("change", this.
|
|
8971
|
+
return watcher.on("change", this.onFileChange), watcher.on("unlink", this.onFileDelete), watcher.on("add", this.onFileCreate), this.unregisterWatcher = () => {
|
|
8972
|
+
watcher.off("change", this.onFileChange), watcher.off("unlink", this.onFileDelete), watcher.off("add", this.onFileCreate), this.unregisterWatcher = noop;
|
|
8791
8973
|
}, this;
|
|
8792
8974
|
}
|
|
8793
8975
|
scheduleRerun(file) {
|
|
@@ -8805,7 +8987,7 @@ class VitestWatcher {
|
|
|
8805
8987
|
}
|
|
8806
8988
|
}), triggered;
|
|
8807
8989
|
}
|
|
8808
|
-
|
|
8990
|
+
onFileChange = (id) => {
|
|
8809
8991
|
id = slash(id), this.vitest.logger.clearHighlightCache(id), this.vitest.invalidateFile(id);
|
|
8810
8992
|
const testFiles = this.getTestFilesFromWatcherTrigger(id);
|
|
8811
8993
|
if (testFiles) this.scheduleRerun(id);
|
|
@@ -8814,10 +8996,10 @@ class VitestWatcher {
|
|
|
8814
8996
|
if (needsRerun) this.scheduleRerun(id);
|
|
8815
8997
|
}
|
|
8816
8998
|
};
|
|
8817
|
-
|
|
8999
|
+
onFileDelete = (id) => {
|
|
8818
9000
|
if (id = slash(id), this.vitest.logger.clearHighlightCache(id), this.invalidates.add(id), this.vitest.state.filesMap.has(id)) this.vitest.projects.forEach((project) => project._removeCachedTestFile(id)), this.vitest.state.filesMap.delete(id), this.vitest.cache.results.removeFromCache(id), this.vitest.cache.stats.removeStats(id), this.changedTests.delete(id), this.vitest.report("onTestRemoved", id);
|
|
8819
9001
|
};
|
|
8820
|
-
|
|
9002
|
+
onFileCreate = (id) => {
|
|
8821
9003
|
id = slash(id), this.vitest.invalidateFile(id);
|
|
8822
9004
|
const testFiles = this.getTestFilesFromWatcherTrigger(id);
|
|
8823
9005
|
if (testFiles) {
|
|
@@ -8910,8 +9092,15 @@ class Vitest {
|
|
|
8910
9092
|
* If projects were filtered with `--project` flag, they won't appear here.
|
|
8911
9093
|
*/
|
|
8912
9094
|
projects = [];
|
|
9095
|
+
/**
|
|
9096
|
+
* A watcher handler. This is not the file system watcher. The handler only
|
|
9097
|
+
* exposes methods to handle changed files.
|
|
9098
|
+
*
|
|
9099
|
+
* If you have your own watcher, you can use these methods to replicate
|
|
9100
|
+
* Vitest behaviour.
|
|
9101
|
+
*/
|
|
9102
|
+
watcher;
|
|
8913
9103
|
/** @internal */ configOverride = {};
|
|
8914
|
-
/** @internal */ coverageProvider;
|
|
8915
9104
|
/** @internal */ filenamePattern;
|
|
8916
9105
|
/** @internal */ runningPromise;
|
|
8917
9106
|
/** @internal */ closingPromise;
|
|
@@ -8926,15 +9115,15 @@ class Vitest {
|
|
|
8926
9115
|
isFirstRun = true;
|
|
8927
9116
|
restartsCount = 0;
|
|
8928
9117
|
specifications;
|
|
8929
|
-
watcher;
|
|
8930
9118
|
pool;
|
|
8931
9119
|
_config;
|
|
8932
9120
|
_vite;
|
|
8933
9121
|
_state;
|
|
8934
9122
|
_cache;
|
|
8935
9123
|
_snapshot;
|
|
9124
|
+
_coverageProvider;
|
|
8936
9125
|
constructor(mode, cliOptions, options = {}) {
|
|
8937
|
-
this.mode = mode, this._cliOptions = cliOptions, this.logger = new Logger(this, options.stdout, options.stderr), this.packageInstaller = options.packageInstaller || new VitestPackageInstaller(), this.specifications = new VitestSpecifications(this), this.watcher = new VitestWatcher(this).onWatcherRerun((file) => this.scheduleRerun(
|
|
9126
|
+
this.mode = mode, this._cliOptions = cliOptions, this.logger = new Logger(this, options.stdout, options.stderr), this.packageInstaller = options.packageInstaller || new VitestPackageInstaller(), this.specifications = new VitestSpecifications(this), this.watcher = new VitestWatcher(this).onWatcherRerun((file) => this.scheduleRerun(file));
|
|
8938
9127
|
}
|
|
8939
9128
|
_onRestartListeners = [];
|
|
8940
9129
|
_onClose = [];
|
|
@@ -8942,24 +9131,12 @@ class Vitest {
|
|
|
8942
9131
|
_onCancelListeners = [];
|
|
8943
9132
|
_onUserTestsRerun = [];
|
|
8944
9133
|
_onFilterWatchedSpecification = [];
|
|
8945
|
-
/** @deprecated will be removed in 4.0, use `onFilterWatchedSpecification` instead */
|
|
8946
|
-
get invalidates() {
|
|
8947
|
-
return this.watcher.invalidates;
|
|
8948
|
-
}
|
|
8949
|
-
/** @deprecated will be removed in 4.0, use `onFilterWatchedSpecification` instead */
|
|
8950
|
-
get changedTests() {
|
|
8951
|
-
return this.watcher.changedTests;
|
|
8952
|
-
}
|
|
8953
9134
|
/**
|
|
8954
9135
|
* The global config.
|
|
8955
9136
|
*/
|
|
8956
9137
|
get config() {
|
|
8957
9138
|
return assert(this._config, "config"), this._config;
|
|
8958
9139
|
}
|
|
8959
|
-
/** @deprecated use `vitest.vite` instead */
|
|
8960
|
-
get server() {
|
|
8961
|
-
return this._vite;
|
|
8962
|
-
}
|
|
8963
9140
|
/**
|
|
8964
9141
|
* Global Vite's dev server instance.
|
|
8965
9142
|
*/
|
|
@@ -8985,13 +9162,9 @@ class Vitest {
|
|
|
8985
9162
|
get cache() {
|
|
8986
9163
|
return assert(this._cache, "cache"), this._cache;
|
|
8987
9164
|
}
|
|
8988
|
-
/** @deprecated internal */
|
|
8989
|
-
setServer(options, server) {
|
|
8990
|
-
return this._setServer(options, server);
|
|
8991
|
-
}
|
|
8992
9165
|
/** @internal */
|
|
8993
9166
|
async _setServer(options, server) {
|
|
8994
|
-
this.watcher.unregisterWatcher(), clearTimeout(this._rerunTimer), this.restartsCount += 1, this.pool?.close?.(), this.pool = void 0, this.closingPromise = void 0, this.projects = [], this.
|
|
9167
|
+
this.watcher.unregisterWatcher(), clearTimeout(this._rerunTimer), this.restartsCount += 1, this.pool?.close?.(), this.pool = void 0, this.closingPromise = void 0, this.projects = [], this.runningPromise = void 0, this.coreWorkspaceProject = void 0, this.specifications.clearCache(), this._coverageProvider = void 0, this._onUserTestsRerun = [], this._vite = server;
|
|
8995
9168
|
const resolved = resolveConfig(this, options, server.config);
|
|
8996
9169
|
if (this._config = resolved, this._state = new StateManager({ onUnhandledError: resolved.onUnhandledError }), this._cache = new VitestCache(this.version), this._snapshot = new SnapshotManager({ ...resolved.snapshotOptions }), this._testRun = new TestRun(this), this.config.watch) this.watcher.registerWatcher();
|
|
8997
9170
|
this._resolver = new VitestResolver(server.config.cacheDir, resolved);
|
|
@@ -9032,6 +9205,26 @@ class Vitest {
|
|
|
9032
9205
|
if (this.config.testNamePattern) this.configOverride.testNamePattern = this.config.testNamePattern;
|
|
9033
9206
|
this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray(resolved.benchmark?.reporters), this.runner) : await createReporters(resolved.reporters, this), await Promise.all(this._onSetServer.map((fn) => fn()));
|
|
9034
9207
|
}
|
|
9208
|
+
/** @internal */
|
|
9209
|
+
get coverageProvider() {
|
|
9210
|
+
return this.configOverride.coverage?.enabled === false ? null : this._coverageProvider;
|
|
9211
|
+
}
|
|
9212
|
+
async enableCoverage() {
|
|
9213
|
+
this.configOverride.coverage = {}, this.configOverride.coverage.enabled = true, await this.createCoverageProvider(), await this.coverageProvider?.onEnabled?.();
|
|
9214
|
+
}
|
|
9215
|
+
disableCoverage() {
|
|
9216
|
+
this.configOverride.coverage ??= {}, this.configOverride.coverage.enabled = false;
|
|
9217
|
+
}
|
|
9218
|
+
_coverageOverrideCache = /* @__PURE__ */ new WeakMap();
|
|
9219
|
+
/** @internal */
|
|
9220
|
+
get _coverageOptions() {
|
|
9221
|
+
if (!this.configOverride.coverage) return this.config.coverage;
|
|
9222
|
+
if (!this._coverageOverrideCache.has(this.configOverride.coverage)) {
|
|
9223
|
+
const coverage = deepClone(this.config.coverage), options = deepMerge(coverage, this.configOverride.coverage);
|
|
9224
|
+
this._coverageOverrideCache.set(this.configOverride.coverage, options);
|
|
9225
|
+
}
|
|
9226
|
+
return this._coverageOverrideCache.get(this.configOverride.coverage);
|
|
9227
|
+
}
|
|
9035
9228
|
/**
|
|
9036
9229
|
* Inject new test projects into the workspace.
|
|
9037
9230
|
* @param config Glob, config path or a custom config options.
|
|
@@ -9057,10 +9250,6 @@ class Vitest {
|
|
|
9057
9250
|
_ensureRootProject() {
|
|
9058
9251
|
return this.coreWorkspaceProject ||= TestProject._createBasicProject(this), this.coreWorkspaceProject;
|
|
9059
9252
|
}
|
|
9060
|
-
/** @deprecated use `getRootProject` instead */
|
|
9061
|
-
getCoreWorkspaceProject() {
|
|
9062
|
-
return this.getRootProject();
|
|
9063
|
-
}
|
|
9064
9253
|
/**
|
|
9065
9254
|
* Return project that has the root (or "global") config.
|
|
9066
9255
|
*/
|
|
@@ -9068,13 +9257,6 @@ class Vitest {
|
|
|
9068
9257
|
if (!this.coreWorkspaceProject) throw new Error(`Root project is not initialized. This means that the Vite server was not established yet and the the workspace config is not resolved.`);
|
|
9069
9258
|
return this.coreWorkspaceProject;
|
|
9070
9259
|
}
|
|
9071
|
-
/**
|
|
9072
|
-
* @deprecated use Reported Task API instead
|
|
9073
|
-
*/
|
|
9074
|
-
getProjectByTaskId(taskId) {
|
|
9075
|
-
const task = this.state.idMap.get(taskId), projectName = task.projectName || task?.file?.projectName || "";
|
|
9076
|
-
return this.getProjectByName(projectName);
|
|
9077
|
-
}
|
|
9078
9260
|
getProjectByName(name) {
|
|
9079
9261
|
const project = this.projects.find((p) => p.name === name) || this.coreWorkspaceProject || this.projects[0];
|
|
9080
9262
|
if (!project) throw new Error(`Project "${name}" was not found.`);
|
|
@@ -9087,6 +9269,15 @@ class Vitest {
|
|
|
9087
9269
|
import(moduleId) {
|
|
9088
9270
|
return this.runner.import(moduleId);
|
|
9089
9271
|
}
|
|
9272
|
+
/**
|
|
9273
|
+
* Creates a coverage provider if `coverage` is enabled in the config.
|
|
9274
|
+
*/
|
|
9275
|
+
async createCoverageProvider() {
|
|
9276
|
+
if (this._coverageProvider) return this._coverageProvider;
|
|
9277
|
+
const coverageProvider = await this.initCoverageProvider();
|
|
9278
|
+
if (coverageProvider) await coverageProvider.clean(this._coverageOptions.clean);
|
|
9279
|
+
return coverageProvider || null;
|
|
9280
|
+
}
|
|
9090
9281
|
async resolveProjects(cliOptions) {
|
|
9091
9282
|
const names = /* @__PURE__ */ new Set();
|
|
9092
9283
|
if (this.config.projects) return resolveProjects(this, cliOptions, void 0, this.config.projects, names);
|
|
@@ -9104,10 +9295,10 @@ class Vitest {
|
|
|
9104
9295
|
return this.specifications.globTestSpecifications(filters);
|
|
9105
9296
|
}
|
|
9106
9297
|
async initCoverageProvider() {
|
|
9107
|
-
if (this.
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9298
|
+
if (this._coverageProvider != null) return;
|
|
9299
|
+
const coverageConfig = this.configOverride.coverage ? this.getRootProject().serializedConfig.coverage : this.config.coverage;
|
|
9300
|
+
if (this._coverageProvider = await getCoverageProvider(coverageConfig, this.runner), this._coverageProvider) await this._coverageProvider.initialize(this), this.config.coverage = this._coverageProvider.resolveOptions();
|
|
9301
|
+
return this._coverageProvider;
|
|
9111
9302
|
}
|
|
9112
9303
|
/**
|
|
9113
9304
|
* Merge reports from multiple runs located in the specified directory (value from `--merge-reports` if not specified).
|
|
@@ -9151,10 +9342,6 @@ class Vitest {
|
|
|
9151
9342
|
unhandledErrors: []
|
|
9152
9343
|
};
|
|
9153
9344
|
}
|
|
9154
|
-
/** @deprecated use `getRelevantTestSpecifications` instead */
|
|
9155
|
-
listFiles(filters) {
|
|
9156
|
-
return this.getRelevantTestSpecifications(filters);
|
|
9157
|
-
}
|
|
9158
9345
|
/**
|
|
9159
9346
|
* Returns the list of test files that match the config and filters.
|
|
9160
9347
|
* @param filters String filters to match the test files
|
|
@@ -9172,7 +9359,7 @@ class Vitest {
|
|
|
9172
9359
|
*/
|
|
9173
9360
|
async start(filters) {
|
|
9174
9361
|
try {
|
|
9175
|
-
await this.initCoverageProvider(), await this.coverageProvider?.clean(this.
|
|
9362
|
+
await this.initCoverageProvider(), await this.coverageProvider?.clean(this._coverageOptions.clean);
|
|
9176
9363
|
} finally {
|
|
9177
9364
|
await this.report("onInit", this);
|
|
9178
9365
|
}
|
|
@@ -9198,21 +9385,18 @@ class Vitest {
|
|
|
9198
9385
|
*/
|
|
9199
9386
|
async init() {
|
|
9200
9387
|
try {
|
|
9201
|
-
await this.initCoverageProvider(), await this.coverageProvider?.clean(this.
|
|
9388
|
+
await this.initCoverageProvider(), await this.coverageProvider?.clean(this._coverageOptions.clean);
|
|
9202
9389
|
} finally {
|
|
9203
9390
|
await this.report("onInit", this);
|
|
9204
9391
|
}
|
|
9205
9392
|
if (await this.globTestSpecifications(), this.config.watch) await this.report("onWatcherStart");
|
|
9206
9393
|
}
|
|
9207
9394
|
/**
|
|
9208
|
-
*
|
|
9395
|
+
* If there is a test run happening, returns a promise that will
|
|
9396
|
+
* resolve when the test run is finished.
|
|
9209
9397
|
*/
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
}
|
|
9213
|
-
/** @deprecated */
|
|
9214
|
-
getFileWorkspaceSpecs(file) {
|
|
9215
|
-
return this.getModuleSpecifications(file);
|
|
9398
|
+
async waitForTestRunEnd() {
|
|
9399
|
+
this.runningPromise && await this.runningPromise;
|
|
9216
9400
|
}
|
|
9217
9401
|
/**
|
|
9218
9402
|
* Get test specifications associated with the given module. If module is not a test file, an empty array is returned.
|
|
@@ -9227,7 +9411,9 @@ class Vitest {
|
|
|
9227
9411
|
* Vitest automatically caches test specifications for each file. This method clears the cache for the given file or the whole cache altogether.
|
|
9228
9412
|
*/
|
|
9229
9413
|
clearSpecificationsCache(moduleId) {
|
|
9230
|
-
this.specifications.clearCache(moduleId)
|
|
9414
|
+
if (this.specifications.clearCache(moduleId), !moduleId) this.projects.forEach((project) => {
|
|
9415
|
+
project.testFilesList = null;
|
|
9416
|
+
});
|
|
9231
9417
|
}
|
|
9232
9418
|
/**
|
|
9233
9419
|
* Run tests for the given test specifications. This does not trigger `onWatcher*` events.
|
|
@@ -9243,7 +9429,6 @@ class Vitest {
|
|
|
9243
9429
|
* @param allTestsRun Indicates whether all tests were run. This only matters for coverage.
|
|
9244
9430
|
*/
|
|
9245
9431
|
async rerunTestSpecifications(specifications, allTestsRun = false) {
|
|
9246
|
-
this.configOverride.testNamePattern = void 0;
|
|
9247
9432
|
const files = specifications.map((spec) => spec.moduleId);
|
|
9248
9433
|
await Promise.all([this.report("onWatcherRerun", files, "rerun test"), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
|
|
9249
9434
|
const result = await this.runTestSpecifications(specifications, allTestsRun);
|
|
@@ -9254,7 +9439,7 @@ class Vitest {
|
|
|
9254
9439
|
try {
|
|
9255
9440
|
if (!this.pool) this.pool = createPool(this);
|
|
9256
9441
|
const invalidates = Array.from(this.watcher.invalidates);
|
|
9257
|
-
if (this.watcher.invalidates.clear(), this.snapshot.clear(), this.state.clearErrors(), !this.isFirstRun && this.
|
|
9442
|
+
if (this.watcher.invalidates.clear(), this.snapshot.clear(), this.state.clearErrors(), !this.isFirstRun && this._coverageOptions.cleanOnRerun) await this.coverageProvider?.clean();
|
|
9258
9443
|
await this.initializeGlobalSetup(specs);
|
|
9259
9444
|
try {
|
|
9260
9445
|
await this.pool.runTests(specs, invalidates);
|
|
@@ -9278,6 +9463,18 @@ class Vitest {
|
|
|
9278
9463
|
this.runningPromise = void 0, this.isFirstRun = false, this.config.changed = false, this.config.related = void 0;
|
|
9279
9464
|
}), await this.runningPromise;
|
|
9280
9465
|
}
|
|
9466
|
+
async experimental_parseSpecifications(specifications, options) {
|
|
9467
|
+
if (this.mode !== "test") throw new Error(`The \`experimental_parseSpecifications\` does not support "${this.mode}" mode.`);
|
|
9468
|
+
const concurrency = options?.concurrency ?? (typeof nodeos__default.availableParallelism === "function" ? nodeos__default.availableParallelism() : nodeos__default.cpus().length), limit = limitConcurrency(concurrency), promises = specifications.map((specification) => limit(() => this.experimental_parseSpecification(specification)));
|
|
9469
|
+
return Promise.all(promises);
|
|
9470
|
+
}
|
|
9471
|
+
async experimental_parseSpecification(specification) {
|
|
9472
|
+
if (this.mode !== "test") throw new Error(`The \`experimental_parseSpecification\` does not support "${this.mode}" mode.`);
|
|
9473
|
+
const file = await astCollectTests(specification.project, specification.moduleId).catch((error) => {
|
|
9474
|
+
return createFailedFileTask(specification.project, specification.moduleId, error);
|
|
9475
|
+
});
|
|
9476
|
+
return this.state.collectFiles(specification.project, [file]), this.state.getReportedEntity(file);
|
|
9477
|
+
}
|
|
9281
9478
|
/**
|
|
9282
9479
|
* Collect tests in specified modules. Vitest will run the files to collect tests.
|
|
9283
9480
|
* @param specifications A list of specifications to run.
|
|
@@ -9416,7 +9613,6 @@ class Vitest {
|
|
|
9416
9613
|
this.configOverride.testNamePattern = void 0;
|
|
9417
9614
|
}
|
|
9418
9615
|
_rerunTimer;
|
|
9419
|
-
// we can't use a single `triggerId` yet because vscode extension relies on this
|
|
9420
9616
|
async scheduleRerun(triggerId) {
|
|
9421
9617
|
const currentCount = this.restartsCount;
|
|
9422
9618
|
clearTimeout(this._rerunTimer), await this.runningPromise, clearTimeout(this._rerunTimer), this.restartsCount === currentCount && (this._rerunTimer = setTimeout(async () => {
|
|
@@ -9434,7 +9630,7 @@ class Vitest {
|
|
|
9434
9630
|
if (files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file)), files.length === 0) return;
|
|
9435
9631
|
}
|
|
9436
9632
|
this.watcher.changedTests.clear();
|
|
9437
|
-
const
|
|
9633
|
+
const triggerLabel = relative(this.config.root, triggerId), specifications = files.flatMap((file) => this.getModuleSpecifications(file)).filter((specification) => {
|
|
9438
9634
|
return this._onFilterWatchedSpecification.length === 0 ? true : this._onFilterWatchedSpecification.every((fn) => fn(specification));
|
|
9439
9635
|
});
|
|
9440
9636
|
await Promise.all([this.report("onWatcherRerun", files, triggerLabel), ...this._onUserTestsRerun.map((fn) => fn(specifications))]), await this.runFiles(specifications, false), await this.report("onWatcherStart", this.state.getFiles(files));
|
|
@@ -9452,17 +9648,13 @@ class Vitest {
|
|
|
9452
9648
|
});
|
|
9453
9649
|
});
|
|
9454
9650
|
}
|
|
9455
|
-
/** @deprecated use `invalidateFile` */
|
|
9456
|
-
updateLastChanged(filepath) {
|
|
9457
|
-
this.invalidateFile(filepath);
|
|
9458
|
-
}
|
|
9459
9651
|
/** @internal */
|
|
9460
9652
|
_checkUnhandledErrors(errors) {
|
|
9461
9653
|
if (errors.length && !this.config.dangerouslyIgnoreUnhandledErrors) process.exitCode = 1;
|
|
9462
9654
|
}
|
|
9463
9655
|
async reportCoverage(coverage, allTestsRun) {
|
|
9464
9656
|
if (this.state.getCountOfFailedTests() > 0) {
|
|
9465
|
-
if (await this.coverageProvider?.onTestFailure?.(), !this.
|
|
9657
|
+
if (await this.coverageProvider?.onTestFailure?.(), !this._coverageOptions.reportOnFailure) return;
|
|
9466
9658
|
}
|
|
9467
9659
|
if (this.coverageProvider) {
|
|
9468
9660
|
await this.coverageProvider.reportCoverage(coverage, { allTestsRun });
|
|
@@ -9526,25 +9718,6 @@ class Vitest {
|
|
|
9526
9718
|
return Array.from(new Set(specifications.map((spec) => spec.moduleId)));
|
|
9527
9719
|
}
|
|
9528
9720
|
/**
|
|
9529
|
-
* @deprecated use `globTestSpecifications` instead
|
|
9530
|
-
*/
|
|
9531
|
-
async globTestSpecs(filters = []) {
|
|
9532
|
-
return this.globTestSpecifications(filters);
|
|
9533
|
-
}
|
|
9534
|
-
/**
|
|
9535
|
-
* @deprecated use `globTestSpecifications` instead
|
|
9536
|
-
*/
|
|
9537
|
-
async globTestFiles(filters = []) {
|
|
9538
|
-
return this.globTestSpecifications(filters);
|
|
9539
|
-
}
|
|
9540
|
-
/** @deprecated filter by `this.projects` yourself */
|
|
9541
|
-
getModuleProjects(filepath) {
|
|
9542
|
-
return this.projects.filter((project) => {
|
|
9543
|
-
return project.getModulesByFilepath(filepath).size;
|
|
9544
|
-
// TODO: reevaluate || project.browser?.moduleGraph.getModulesByFile(id)?.size
|
|
9545
|
-
});
|
|
9546
|
-
}
|
|
9547
|
-
/**
|
|
9548
9721
|
* Should the server be kept running after the tests are done.
|
|
9549
9722
|
*/
|
|
9550
9723
|
shouldKeepServer() {
|
|
@@ -9961,8 +10134,8 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
9961
10134
|
async function inputFilePattern() {
|
|
9962
10135
|
off();
|
|
9963
10136
|
const watchFilter = new WatchFilter("Input filename pattern", stdin, stdout), filter = await watchFilter.filter(async (str) => {
|
|
9964
|
-
const
|
|
9965
|
-
return
|
|
10137
|
+
const specifications = await ctx.globTestSpecifications([str]);
|
|
10138
|
+
return specifications.map((specification) => relative(ctx.config.root, specification.moduleId)).filter((file, index, all) => all.indexOf(file) === index);
|
|
9966
10139
|
});
|
|
9967
10140
|
if (on(), typeof filter === "undefined") return;
|
|
9968
10141
|
latestFilename = filter?.trim() || "";
|
|
@@ -9992,8 +10165,8 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
9992
10165
|
*/
|
|
9993
10166
|
async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, vitestOptions) {
|
|
9994
10167
|
const root = resolve(options.root || process.cwd()), ctx = await prepareVitest(mode, options, viteOverrides, vitestOptions, cliFilters);
|
|
9995
|
-
if (mode === "test" && ctx.
|
|
9996
|
-
const provider = ctx.
|
|
10168
|
+
if (mode === "test" && ctx._coverageOptions.enabled) {
|
|
10169
|
+
const provider = ctx._coverageOptions.provider || "v8", requiredPackages = CoverageProviderMap[provider];
|
|
9997
10170
|
if (requiredPackages) {
|
|
9998
10171
|
if (!await ctx.packageInstaller.ensureInstalled(requiredPackages, root, ctx.version)) return process.exitCode = 1, ctx;
|
|
9999
10172
|
}
|
|
@@ -10114,4 +10287,4 @@ var cliApi = /*#__PURE__*/Object.freeze({
|
|
|
10114
10287
|
startVitest: startVitest
|
|
10115
10288
|
});
|
|
10116
10289
|
|
|
10117
|
-
export { FilesNotFoundError as F, GitNotFoundError as G, Vitest as V, VitestPlugin as a, VitestPackageInstaller as b, createVitest as c,
|
|
10290
|
+
export { FilesNotFoundError as F, GitNotFoundError as G, Vitest as V, VitestPlugin as a, VitestPackageInstaller as b, createVitest as c, experimental_getRunnerTask as d, escapeTestName as e, registerConsoleShortcuts as f, createViteLogger as g, createDebugger as h, isValidApiRequest as i, cliApi as j, resolveFsAllow as r, startVitest as s };
|