vitest 4.0.0-beta.5 → 4.0.0-beta.6
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/LICENSE.md +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +2 -2
- package/dist/chunks/{base.DMfOuRWD.js → base.BXI97p6t.js} +7 -16
- package/dist/chunks/{benchmark.CtuRzf-i.js → benchmark.UW6Ezvxy.js} +4 -9
- package/dist/chunks/{cac.CKnbxhn2.js → cac.WE-urWw5.js} +37 -113
- package/dist/chunks/{cli-api.COn58yrl.js → cli-api.CZz3evYC.js} +505 -1211
- package/dist/chunks/{console.Duv2dVIC.js → console.B0quX7yH.js} +32 -68
- package/dist/chunks/{coverage.B6cReEn1.js → coverage.BPRS6xgn.js} +210 -579
- package/dist/chunks/{creator.DUVZ6rfm.js → creator.KEg6n5IC.js} +28 -74
- package/dist/chunks/{date.Bq6ZW5rf.js → date.-jtEtIeV.js} +6 -17
- package/dist/chunks/{git.BVQ8w_Sw.js → git.BFNcloKD.js} +1 -2
- package/dist/chunks/{globals.CJQ63oO0.js → globals.lgsmH00r.js} +5 -5
- package/dist/chunks/{index.DgN0Zk9a.js → index.7w0eqmYM.js} +14 -24
- package/dist/chunks/{index.QZr3S3vQ.js → index.AR8aAkCC.js} +2 -2
- package/dist/chunks/{index.BRtIe7r8.js → index.BG0gqZH-.js} +39 -102
- package/dist/chunks/{index.oWRWx-nj.js → index.CsFXYRkW.js} +17 -36
- package/dist/chunks/{index.DQhAfQQU.js → index.VNI-1z5c.js} +270 -606
- package/dist/chunks/{inspector.C914Efll.js → inspector.CvQD-Nie.js} +10 -25
- package/dist/chunks/{moduleRunner.d.mmOmOGrW.d.ts → moduleRunner.d.8kKUsuDg.d.ts} +1 -1
- package/dist/chunks/{node.4JV5OXkt.js → node.BOqcT2jW.js} +1 -1
- package/dist/chunks/{plugin.d.CvOlgjxK.d.ts → plugin.d.DuiQJfUL.d.ts} +1 -1
- package/dist/chunks/{reporters.d.CYE9sT5z.d.ts → reporters.d.CqR9-CDJ.d.ts} +16 -33
- package/dist/chunks/{resolver.D5bG4zy5.js → resolver.Bx6lE0iq.js} +21 -64
- package/dist/chunks/{rpc.DGoW_Vl-.js → rpc.RpPylpp0.js} +7 -21
- package/dist/chunks/{runBaseTests.B3KcKqlF.js → runBaseTests.D6sfuWBM.js} +25 -54
- package/dist/chunks/{setup-common.lgPs-bYv.js → setup-common.hLGRxhC8.js} +9 -22
- package/dist/chunks/{startModuleRunner.C8FtT_BY.js → startModuleRunner.C8TW8zTN.js} +83 -205
- package/dist/chunks/{typechecker.BgoW4nTA.js → typechecker.Cd1wvxUM.js} +96 -208
- package/dist/chunks/{utils.CcGm2cd1.js → utils.C2YI6McM.js} +4 -13
- package/dist/chunks/{utils.B9FY3b73.js → utils.C7__0Iv5.js} +5 -14
- package/dist/chunks/{vi.DGAfBY4R.js → vi.BfdOiD4j.js} +110 -267
- package/dist/chunks/{vm.BKfKvaKl.js → vm.BHBje7cC.js} +73 -177
- package/dist/cli.js +3 -3
- package/dist/config.d.ts +4 -4
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.js +2 -2
- package/dist/environments.js +1 -1
- package/dist/index.js +5 -5
- package/dist/module-evaluator.d.ts +1 -1
- package/dist/module-evaluator.js +33 -84
- package/dist/module-runner.js +2 -2
- package/dist/node.d.ts +3 -3
- package/dist/node.js +13 -19
- package/dist/reporters.d.ts +2 -2
- package/dist/reporters.js +3 -3
- package/dist/runners.js +23 -51
- package/dist/snapshot.js +2 -2
- package/dist/suite.js +2 -2
- package/dist/worker.js +18 -34
- package/dist/workers/forks.js +4 -4
- package/dist/workers/runVmTests.js +19 -37
- package/dist/workers/threads.js +4 -4
- package/dist/workers/vmForks.js +7 -7
- package/dist/workers/vmThreads.js +7 -7
- package/dist/workers.js +11 -11
- package/package.json +11 -11
|
@@ -9,9 +9,9 @@ import { 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
10
|
import { generateFileHash, limitConcurrency, createFileTask, hasFailed, getTasks, getTests } from '@vitest/runner/utils';
|
|
11
11
|
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
12
|
-
import { v as version$1 } from './cac.
|
|
12
|
+
import { v as version$1 } from './cac.WE-urWw5.js';
|
|
13
13
|
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.
|
|
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.VNI-1z5c.js';
|
|
15
15
|
import require$$0$3 from 'events';
|
|
16
16
|
import require$$1$1 from 'https';
|
|
17
17
|
import require$$2 from 'http';
|
|
@@ -26,8 +26,8 @@ import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
|
|
|
26
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.BPRS6xgn.js';
|
|
30
|
+
import { c as convertTasksToEvents } from './typechecker.Cd1wvxUM.js';
|
|
31
31
|
import { VitestModuleEvaluator } from '#module-evaluator';
|
|
32
32
|
import { ModuleRunner } from 'vite/module-runner';
|
|
33
33
|
import { Console } from 'node:console';
|
|
@@ -42,9 +42,9 @@ import { glob, isDynamicPattern } from 'tinyglobby';
|
|
|
42
42
|
import MagicString from 'magic-string';
|
|
43
43
|
import { hoistMocksPlugin, automockPlugin } from '@vitest/mocker/node';
|
|
44
44
|
import { c as configDefaults } from './defaults.CXFFjsi8.js';
|
|
45
|
-
import { f as findNearestPackageData } from './resolver.
|
|
45
|
+
import { f as findNearestPackageData } from './resolver.Bx6lE0iq.js';
|
|
46
46
|
import * as esModuleLexer from 'es-module-lexer';
|
|
47
|
-
import { a as BenchmarkReportsMap } from './index.
|
|
47
|
+
import { a as BenchmarkReportsMap } from './index.7w0eqmYM.js';
|
|
48
48
|
import assert$1 from 'node:assert';
|
|
49
49
|
import { serializeError } from '@vitest/utils/error';
|
|
50
50
|
import readline from 'node:readline';
|
|
@@ -5017,26 +5017,18 @@ var websocketServerExports = requireWebsocketServer();
|
|
|
5017
5017
|
var WebSocketServer = /*@__PURE__*/getDefaultExportFromCjs(websocketServerExports);
|
|
5018
5018
|
|
|
5019
5019
|
async function getModuleGraph(ctx, projectName, id, browser = false) {
|
|
5020
|
-
const graph = {};
|
|
5021
|
-
const externalized = /* @__PURE__ */ new Set();
|
|
5022
|
-
const inlined = /* @__PURE__ */ new Set();
|
|
5023
|
-
const project = ctx.getProjectByName(projectName);
|
|
5020
|
+
const graph = {}, externalized = /* @__PURE__ */ new Set(), inlined = /* @__PURE__ */ new Set(), project = ctx.getProjectByName(projectName);
|
|
5024
5021
|
async function get(mod, seen = /* @__PURE__ */ new Map()) {
|
|
5025
|
-
if (!mod || !mod.id) return;
|
|
5026
|
-
if (mod.id === "\0@vitest/browser/context") return;
|
|
5022
|
+
if (!mod || !mod.id || mod.id === "\0@vitest/browser/context") return;
|
|
5027
5023
|
if (seen.has(mod)) return seen.get(mod);
|
|
5028
5024
|
let id = clearId(mod.id);
|
|
5029
5025
|
seen.set(mod, id);
|
|
5030
5026
|
// TODO: how to know if it was rewritten(?) - what is rewritten?
|
|
5031
5027
|
const rewrote = browser ? mod.file?.includes(project.browser.vite.config.cacheDir) ? mod.id : false : false;
|
|
5032
|
-
if (rewrote)
|
|
5033
|
-
|
|
5034
|
-
externalized.add(id);
|
|
5035
|
-
seen.set(mod, id);
|
|
5036
|
-
} else inlined.add(id);
|
|
5028
|
+
if (rewrote) id = rewrote, externalized.add(id), seen.set(mod, id);
|
|
5029
|
+
else inlined.add(id);
|
|
5037
5030
|
const mods = Array.from(mod.importedModules).filter((i) => i.id && !i.id.includes("/vitest/dist/"));
|
|
5038
|
-
graph[id] = (await Promise.all(mods.map((m) => get(m, seen)))).filter(Boolean);
|
|
5039
|
-
return id;
|
|
5031
|
+
return graph[id] = (await Promise.all(mods.map((m) => get(m, seen)))).filter(Boolean), id;
|
|
5040
5032
|
}
|
|
5041
5033
|
if (browser && project.browser) await get(project.browser.vite.moduleGraph.getModuleById(id));
|
|
5042
5034
|
else await get(project.vite.moduleGraph.getModuleById(id));
|
|
@@ -5088,21 +5080,19 @@ catch {}
|
|
|
5088
5080
|
}
|
|
5089
5081
|
|
|
5090
5082
|
function setup(ctx, _server) {
|
|
5091
|
-
const wss = new WebSocketServer({ noServer: true });
|
|
5092
|
-
const clients = /* @__PURE__ */ new Map();
|
|
5093
|
-
const server = _server || ctx.server;
|
|
5083
|
+
const wss = new WebSocketServer({ noServer: true }), clients = /* @__PURE__ */ new Map(), server = _server || ctx.server;
|
|
5094
5084
|
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
5095
5085
|
if (!request.url) return;
|
|
5096
5086
|
const { pathname } = new URL(request.url, "http://localhost");
|
|
5097
|
-
if (pathname
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5087
|
+
if (pathname === API_PATH) {
|
|
5088
|
+
if (!isValidApiRequest(ctx.config, request)) {
|
|
5089
|
+
socket.destroy();
|
|
5090
|
+
return;
|
|
5091
|
+
}
|
|
5092
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
5093
|
+
wss.emit("connection", ws, request), setupClient(ws);
|
|
5094
|
+
});
|
|
5101
5095
|
}
|
|
5102
|
-
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
5103
|
-
wss.emit("connection", ws, request);
|
|
5104
|
-
setupClient(ws);
|
|
5105
|
-
});
|
|
5106
5096
|
});
|
|
5107
5097
|
function setupClient(ws) {
|
|
5108
5098
|
const rpc = createBirpc({
|
|
@@ -5116,8 +5106,7 @@ function setup(ctx, _server) {
|
|
|
5116
5106
|
return ctx.state.getPaths();
|
|
5117
5107
|
},
|
|
5118
5108
|
async readTestFile(id) {
|
|
5119
|
-
|
|
5120
|
-
return promises.readFile(id, "utf-8");
|
|
5109
|
+
return !ctx.state.filesMap.has(id) || !existsSync(id) ? null : promises.readFile(id, "utf-8");
|
|
5121
5110
|
},
|
|
5122
5111
|
async saveTestFile(id, content) {
|
|
5123
5112
|
if (!ctx.state.filesMap.has(id) || !existsSync(id)) throw new Error(`Test file "${id}" was not registered, so it cannot be updated using the API.`);
|
|
@@ -5139,8 +5128,7 @@ function setup(ctx, _server) {
|
|
|
5139
5128
|
}));
|
|
5140
5129
|
},
|
|
5141
5130
|
async getTransformResult(projectName, id, browser = false) {
|
|
5142
|
-
const project = ctx.getProjectByName(projectName);
|
|
5143
|
-
const result = browser ? await project.browser.vite.transformRequest(id) : await project.vite.transformRequest(id);
|
|
5131
|
+
const project = ctx.getProjectByName(projectName), result = browser ? await project.browser.vite.transformRequest(id) : await project.vite.transformRequest(id);
|
|
5144
5132
|
if (result) {
|
|
5145
5133
|
try {
|
|
5146
5134
|
result.source = result.source || await promises.readFile(id, "utf-8");
|
|
@@ -5183,56 +5171,49 @@ function setup(ctx, _server) {
|
|
|
5183
5171
|
deserialize: parse,
|
|
5184
5172
|
timeout: -1
|
|
5185
5173
|
});
|
|
5186
|
-
clients.set(ws, rpc)
|
|
5187
|
-
|
|
5188
|
-
clients.delete(ws);
|
|
5189
|
-
rpc.$close(/* @__PURE__ */ new Error("[vitest-api]: Pending methods while closing rpc"));
|
|
5174
|
+
clients.set(ws, rpc), ws.on("close", () => {
|
|
5175
|
+
clients.delete(ws), rpc.$close(/* @__PURE__ */ new Error("[vitest-api]: Pending methods while closing rpc"));
|
|
5190
5176
|
});
|
|
5191
5177
|
}
|
|
5192
5178
|
ctx.reporters.push(new WebSocketReporter(ctx, wss, clients));
|
|
5193
5179
|
}
|
|
5194
5180
|
class WebSocketReporter {
|
|
5195
5181
|
constructor(ctx, wss, clients) {
|
|
5196
|
-
this.ctx = ctx;
|
|
5197
|
-
this.wss = wss;
|
|
5198
|
-
this.clients = clients;
|
|
5182
|
+
this.ctx = ctx, this.wss = wss, this.clients = clients;
|
|
5199
5183
|
}
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
client.onCollected?.(files)?.catch?.(noop);
|
|
5184
|
+
onTestModuleCollected(testModule) {
|
|
5185
|
+
this.clients.size !== 0 && this.clients.forEach((client) => {
|
|
5186
|
+
client.onCollected?.([testModule.task])?.catch?.(noop);
|
|
5204
5187
|
});
|
|
5205
5188
|
}
|
|
5206
|
-
|
|
5189
|
+
onTestRunStart(specifications) {
|
|
5207
5190
|
if (this.clients.size === 0) return;
|
|
5191
|
+
const serializedSpecs = specifications.map((spec) => spec.toJSON());
|
|
5208
5192
|
this.clients.forEach((client) => {
|
|
5209
|
-
client.onSpecsCollected?.(
|
|
5193
|
+
client.onSpecsCollected?.(serializedSpecs)?.catch?.(noop);
|
|
5210
5194
|
});
|
|
5211
5195
|
}
|
|
5212
5196
|
async onTestCaseAnnotate(testCase, annotation) {
|
|
5213
|
-
|
|
5214
|
-
this.clients.forEach((client) => {
|
|
5197
|
+
this.clients.size !== 0 && this.clients.forEach((client) => {
|
|
5215
5198
|
client.onTestAnnotate?.(testCase.id, annotation)?.catch?.(noop);
|
|
5216
5199
|
});
|
|
5217
5200
|
}
|
|
5218
5201
|
async onTaskUpdate(packs, events) {
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
const task = this.ctx.state.idMap.get(taskId);
|
|
5222
|
-
const isBrowser = task && task.file.pool === "browser";
|
|
5202
|
+
this.clients.size !== 0 && (packs.forEach(([taskId, result]) => {
|
|
5203
|
+
const task = this.ctx.state.idMap.get(taskId), isBrowser = task && task.file.pool === "browser";
|
|
5223
5204
|
result?.errors?.forEach((error) => {
|
|
5224
|
-
if (isPrimitive(error))
|
|
5225
|
-
if (isBrowser) {
|
|
5205
|
+
if (!isPrimitive(error)) if (isBrowser) {
|
|
5226
5206
|
const project = this.ctx.getProjectByName(task.file.projectName || "");
|
|
5227
5207
|
error.stacks = project.browser?.parseErrorStacktrace(error);
|
|
5228
5208
|
} else error.stacks = parseErrorStacktrace(error);
|
|
5229
5209
|
});
|
|
5230
|
-
})
|
|
5231
|
-
this.clients.forEach((client) => {
|
|
5210
|
+
}), this.clients.forEach((client) => {
|
|
5232
5211
|
client.onTaskUpdate?.(packs, events)?.catch?.(noop);
|
|
5233
|
-
});
|
|
5212
|
+
}));
|
|
5234
5213
|
}
|
|
5235
|
-
|
|
5214
|
+
onTestRunEnd(testModules, unhandledErrors) {
|
|
5215
|
+
if (!this.clients.size) return;
|
|
5216
|
+
const files = testModules.map((testModule) => testModule.task), errors = [...unhandledErrors];
|
|
5236
5217
|
this.clients.forEach((client) => {
|
|
5237
5218
|
client.onFinished?.(files, errors)?.catch?.(noop);
|
|
5238
5219
|
});
|
|
@@ -5266,23 +5247,18 @@ class BrowserSessions {
|
|
|
5266
5247
|
}
|
|
5267
5248
|
createSession(sessionId, project, pool) {
|
|
5268
5249
|
// this promise only waits for the WS connection with the orhcestrator to be established
|
|
5269
|
-
const defer = createDefer()
|
|
5270
|
-
const timeout = setTimeout(() => {
|
|
5250
|
+
const defer = createDefer(), timeout = setTimeout(() => {
|
|
5271
5251
|
defer.reject(/* @__PURE__ */ new Error(`Failed to connect to the browser session "${sessionId}" [${project.name}] within the timeout.`));
|
|
5272
5252
|
}, project.vitest.config.browser.connectTimeout ?? 6e4).unref();
|
|
5273
|
-
this.sessions.set(sessionId, {
|
|
5253
|
+
return this.sessions.set(sessionId, {
|
|
5274
5254
|
project,
|
|
5275
5255
|
connected: () => {
|
|
5276
|
-
defer.resolve();
|
|
5277
|
-
clearTimeout(timeout);
|
|
5256
|
+
defer.resolve(), clearTimeout(timeout);
|
|
5278
5257
|
},
|
|
5279
5258
|
fail: (error) => {
|
|
5280
|
-
defer.resolve();
|
|
5281
|
-
clearTimeout(timeout);
|
|
5282
|
-
pool.reject(error);
|
|
5259
|
+
defer.resolve(), clearTimeout(timeout), pool.reject(error);
|
|
5283
5260
|
}
|
|
5284
|
-
});
|
|
5285
|
-
return defer;
|
|
5261
|
+
}), defer;
|
|
5286
5262
|
}
|
|
5287
5263
|
}
|
|
5288
5264
|
|
|
@@ -5323,37 +5299,25 @@ class ResultsCache {
|
|
|
5323
5299
|
return this.cachePath;
|
|
5324
5300
|
}
|
|
5325
5301
|
setConfig(root, config) {
|
|
5326
|
-
this.root = root;
|
|
5327
|
-
if (config) this.cachePath = resolve(config.dir, "results.json");
|
|
5302
|
+
if (this.root = root, config) this.cachePath = resolve(config.dir, "results.json");
|
|
5328
5303
|
}
|
|
5329
5304
|
getResults(key) {
|
|
5330
5305
|
return this.cache.get(key);
|
|
5331
5306
|
}
|
|
5332
5307
|
async readFromCache() {
|
|
5333
|
-
if (!this.cachePath) return;
|
|
5334
|
-
|
|
5335
|
-
const resultsCache = await fs.promises.readFile(this.cachePath, "utf8");
|
|
5336
|
-
const { results, version } = JSON.parse(resultsCache || "[]");
|
|
5337
|
-
const [major, minor] = version.split(".");
|
|
5308
|
+
if (!this.cachePath || !fs.existsSync(this.cachePath)) return;
|
|
5309
|
+
const resultsCache = await fs.promises.readFile(this.cachePath, "utf8"), { results, version } = JSON.parse(resultsCache || "[]"), [major, minor] = version.split(".");
|
|
5338
5310
|
// handling changed in 0.30.0
|
|
5339
|
-
if (major > 0 || Number(minor) >= 30) {
|
|
5340
|
-
|
|
5341
|
-
this.
|
|
5342
|
-
|
|
5343
|
-
const [projectName, relativePath] = spec.split(":");
|
|
5344
|
-
const keyMap = this.workspacesKeyMap.get(relativePath) || [];
|
|
5345
|
-
keyMap.push(projectName);
|
|
5346
|
-
this.workspacesKeyMap.set(relativePath, keyMap);
|
|
5347
|
-
});
|
|
5348
|
-
}
|
|
5311
|
+
if (major > 0 || Number(minor) >= 30) this.cache = new Map(results), this.version = version, results.forEach(([spec]) => {
|
|
5312
|
+
const [projectName, relativePath] = spec.split(":"), keyMap = this.workspacesKeyMap.get(relativePath) || [];
|
|
5313
|
+
keyMap.push(projectName), this.workspacesKeyMap.set(relativePath, keyMap);
|
|
5314
|
+
});
|
|
5349
5315
|
}
|
|
5350
5316
|
updateResults(files) {
|
|
5351
5317
|
files.forEach((file) => {
|
|
5352
5318
|
const result = file.result;
|
|
5353
5319
|
if (!result) return;
|
|
5354
|
-
const duration = result.duration || 0;
|
|
5355
|
-
// store as relative, so cache would be the same in CI and locally
|
|
5356
|
-
const relativePath = relative(this.root, file.filepath);
|
|
5320
|
+
const duration = result.duration || 0, relativePath = relative(this.root, file.filepath);
|
|
5357
5321
|
this.cache.set(`${file.projectName || ""}:${relativePath}`, {
|
|
5358
5322
|
duration: duration >= 0 ? duration : 0,
|
|
5359
5323
|
failed: result.state === "fail"
|
|
@@ -5367,8 +5331,7 @@ class ResultsCache {
|
|
|
5367
5331
|
}
|
|
5368
5332
|
async writeToCache() {
|
|
5369
5333
|
if (!this.cachePath) return;
|
|
5370
|
-
const results = Array.from(this.cache.entries());
|
|
5371
|
-
const cacheDirname = dirname(this.cachePath);
|
|
5334
|
+
const results = Array.from(this.cache.entries()), cacheDirname = dirname(this.cachePath);
|
|
5372
5335
|
if (!fs.existsSync(cacheDirname)) await fs.promises.mkdir(cacheDirname, { recursive: true });
|
|
5373
5336
|
const cache = JSON.stringify({
|
|
5374
5337
|
version: this.version,
|
|
@@ -5412,9 +5375,7 @@ class ServerModuleRunner extends ModuleRunner {
|
|
|
5412
5375
|
return { error };
|
|
5413
5376
|
}
|
|
5414
5377
|
} }
|
|
5415
|
-
}, new VitestModuleEvaluator());
|
|
5416
|
-
this.environment = environment;
|
|
5417
|
-
this.config = config;
|
|
5378
|
+
}, new VitestModuleEvaluator()), this.environment = environment, this.config = config;
|
|
5418
5379
|
}
|
|
5419
5380
|
async import(rawId) {
|
|
5420
5381
|
const resolved = await this.environment.pluginContainer.resolveId(rawId, this.config.root);
|
|
@@ -5481,43 +5442,26 @@ function highlightCode(id, source, colors) {
|
|
|
5481
5442
|
});
|
|
5482
5443
|
}
|
|
5483
5444
|
|
|
5484
|
-
const PAD = " ";
|
|
5485
|
-
const ESC$1 = "\x1B[";
|
|
5486
|
-
const ERASE_DOWN = `${ESC$1}J`;
|
|
5487
|
-
const ERASE_SCROLLBACK = `${ESC$1}3J`;
|
|
5488
|
-
const CURSOR_TO_START = `${ESC$1}1;1H`;
|
|
5489
|
-
const HIDE_CURSOR = `${ESC$1}?25l`;
|
|
5490
|
-
const SHOW_CURSOR = `${ESC$1}?25h`;
|
|
5491
|
-
const CLEAR_SCREEN = "\x1Bc";
|
|
5445
|
+
const PAD = " ", ESC$1 = "\x1B[", ERASE_DOWN = `${ESC$1}J`, ERASE_SCROLLBACK = `${ESC$1}3J`, CURSOR_TO_START = `${ESC$1}1;1H`, HIDE_CURSOR = `${ESC$1}?25l`, SHOW_CURSOR = `${ESC$1}?25h`, CLEAR_SCREEN = "\x1Bc";
|
|
5492
5446
|
class Logger {
|
|
5493
5447
|
_clearScreenPending;
|
|
5494
5448
|
_highlights = /* @__PURE__ */ new Map();
|
|
5495
5449
|
cleanupListeners = [];
|
|
5496
5450
|
console;
|
|
5497
5451
|
constructor(ctx, outputStream = process.stdout, errorStream = process.stderr) {
|
|
5498
|
-
this.ctx = ctx
|
|
5499
|
-
this.outputStream = outputStream;
|
|
5500
|
-
this.errorStream = errorStream;
|
|
5501
|
-
this.console = new Console({
|
|
5452
|
+
if (this.ctx = ctx, this.outputStream = outputStream, this.errorStream = errorStream, this.console = new Console({
|
|
5502
5453
|
stdout: outputStream,
|
|
5503
5454
|
stderr: errorStream
|
|
5504
|
-
});
|
|
5505
|
-
this._highlights.clear();
|
|
5506
|
-
this.addCleanupListeners();
|
|
5507
|
-
this.registerUnhandledRejection();
|
|
5508
|
-
if (this.outputStream.isTTY) this.outputStream.write(HIDE_CURSOR);
|
|
5455
|
+
}), this._highlights.clear(), this.addCleanupListeners(), this.registerUnhandledRejection(), this.outputStream.isTTY) this.outputStream.write(HIDE_CURSOR);
|
|
5509
5456
|
}
|
|
5510
5457
|
log(...args) {
|
|
5511
|
-
this._clearScreen();
|
|
5512
|
-
this.console.log(...args);
|
|
5458
|
+
this._clearScreen(), this.console.log(...args);
|
|
5513
5459
|
}
|
|
5514
5460
|
error(...args) {
|
|
5515
|
-
this._clearScreen();
|
|
5516
|
-
this.console.error(...args);
|
|
5461
|
+
this._clearScreen(), this.console.error(...args);
|
|
5517
5462
|
}
|
|
5518
5463
|
warn(...args) {
|
|
5519
|
-
this._clearScreen();
|
|
5520
|
-
this.console.warn(...args);
|
|
5464
|
+
this._clearScreen(), this.console.warn(...args);
|
|
5521
5465
|
}
|
|
5522
5466
|
clearFullScreen(message = "") {
|
|
5523
5467
|
if (!this.ctx.config.clearScreen) {
|
|
@@ -5532,14 +5476,12 @@ class Logger {
|
|
|
5532
5476
|
this.console.log(message);
|
|
5533
5477
|
return;
|
|
5534
5478
|
}
|
|
5535
|
-
this._clearScreenPending = message;
|
|
5536
|
-
if (force) this._clearScreen();
|
|
5479
|
+
if (this._clearScreenPending = message, force) this._clearScreen();
|
|
5537
5480
|
}
|
|
5538
5481
|
_clearScreen() {
|
|
5539
5482
|
if (this._clearScreenPending == null) return;
|
|
5540
5483
|
const log = this._clearScreenPending;
|
|
5541
|
-
this._clearScreenPending = void 0;
|
|
5542
|
-
this.console.log(`${CURSOR_TO_START}${ERASE_DOWN}${log}`);
|
|
5484
|
+
this._clearScreenPending = void 0, this.console.log(`${CURSOR_TO_START}${ERASE_DOWN}${log}`);
|
|
5543
5485
|
}
|
|
5544
5486
|
printError(err, options = {}) {
|
|
5545
5487
|
printError(err, this.ctx, this, options);
|
|
@@ -5554,8 +5496,7 @@ class Logger {
|
|
|
5554
5496
|
highlight(filename, source) {
|
|
5555
5497
|
if (this._highlights.has(filename)) return this._highlights.get(filename);
|
|
5556
5498
|
const code = highlightCode(filename, source);
|
|
5557
|
-
this._highlights.set(filename, code);
|
|
5558
|
-
return code;
|
|
5499
|
+
return this._highlights.set(filename, code), code;
|
|
5559
5500
|
}
|
|
5560
5501
|
printNoTestFound(filters) {
|
|
5561
5502
|
const config = this.ctx.config;
|
|
@@ -5568,34 +5509,22 @@ class Logger {
|
|
|
5568
5509
|
const projectsFilter = toArray(config.project);
|
|
5569
5510
|
if (projectsFilter.length) this.console.error(c.dim("projects: ") + c.yellow(projectsFilter.join(comma)));
|
|
5570
5511
|
this.ctx.projects.forEach((project) => {
|
|
5571
|
-
const config = project.config;
|
|
5572
|
-
const printConfig = !project.isRootProject() && project.name;
|
|
5512
|
+
const config = project.config, printConfig = !project.isRootProject() && project.name;
|
|
5573
5513
|
if (printConfig) this.console.error(`\n${formatProjectName(project)}\n`);
|
|
5574
5514
|
if (config.include) this.console.error(c.dim("include: ") + c.yellow(config.include.join(comma)));
|
|
5575
5515
|
if (config.exclude) this.console.error(c.dim("exclude: ") + c.yellow(config.exclude.join(comma)));
|
|
5576
|
-
if (config.typecheck.enabled)
|
|
5577
|
-
|
|
5578
|
-
this.console.error(c.dim("typecheck exclude: ") + c.yellow(config.typecheck.exclude.join(comma)));
|
|
5579
|
-
}
|
|
5580
|
-
});
|
|
5581
|
-
this.console.error();
|
|
5516
|
+
if (config.typecheck.enabled) this.console.error(c.dim("typecheck include: ") + c.yellow(config.typecheck.include.join(comma))), this.console.error(c.dim("typecheck exclude: ") + c.yellow(config.typecheck.exclude.join(comma)));
|
|
5517
|
+
}), this.console.error();
|
|
5582
5518
|
}
|
|
5583
5519
|
printBanner() {
|
|
5584
5520
|
this.log();
|
|
5585
|
-
const color = this.ctx.config.watch ? "blue" : "cyan";
|
|
5586
|
-
|
|
5587
|
-
this.log(withLabel(color, mode, `v${this.ctx.version} `) + c.gray(this.ctx.config.root));
|
|
5588
|
-
if (this.ctx.config.sequence.sequencer === RandomSequencer) this.log(PAD + c.gray(`Running tests with seed "${this.ctx.config.sequence.seed}"`));
|
|
5521
|
+
const color = this.ctx.config.watch ? "blue" : "cyan", mode = this.ctx.config.watch ? "DEV" : "RUN";
|
|
5522
|
+
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}"`));
|
|
5589
5523
|
if (this.ctx.config.ui) {
|
|
5590
|
-
const host = this.ctx.config.api?.host || "localhost";
|
|
5591
|
-
const port = this.ctx.server.config.server.port;
|
|
5592
|
-
const base = this.ctx.config.uiBase;
|
|
5524
|
+
const host = this.ctx.config.api?.host || "localhost", port = this.ctx.server.config.server.port, base = this.ctx.config.uiBase;
|
|
5593
5525
|
this.log(PAD + c.dim(c.green(`UI started at http://${host}:${c.bold(port)}${base}`)));
|
|
5594
5526
|
} else if (this.ctx.config.api?.port) {
|
|
5595
|
-
const resolvedUrls = this.ctx.server.resolvedUrls;
|
|
5596
|
-
// workaround for https://github.com/vitejs/vite/issues/15438, it was fixed in vite 5.1
|
|
5597
|
-
const fallbackUrl = `http://${this.ctx.config.api.host || "localhost"}:${this.ctx.config.api.port}`;
|
|
5598
|
-
const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] ?? fallbackUrl;
|
|
5527
|
+
const resolvedUrls = this.ctx.server.resolvedUrls, fallbackUrl = `http://${this.ctx.config.api.host || "localhost"}:${this.ctx.config.api.port}`, origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] ?? fallbackUrl;
|
|
5599
5528
|
this.log(PAD + c.dim(c.green(`API started at ${new URL("/", origin)}`)));
|
|
5600
5529
|
}
|
|
5601
5530
|
if (this.ctx.coverageProvider) this.log(PAD + c.dim("Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name));
|
|
@@ -5604,35 +5533,26 @@ class Logger {
|
|
|
5604
5533
|
}
|
|
5605
5534
|
printBrowserBanner(project) {
|
|
5606
5535
|
if (!project.browser) return;
|
|
5607
|
-
const resolvedUrls = project.browser.vite.resolvedUrls;
|
|
5608
|
-
const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0];
|
|
5536
|
+
const resolvedUrls = project.browser.vite.resolvedUrls, origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0];
|
|
5609
5537
|
if (!origin) return;
|
|
5610
|
-
const output = project.isRootProject() ? "" : formatProjectName(project)
|
|
5611
|
-
const provider = project.browser.provider.name;
|
|
5612
|
-
const providerString = provider === "preview" ? "" : ` by ${c.reset(c.bold(provider))}`;
|
|
5538
|
+
const output = project.isRootProject() ? "" : formatProjectName(project), provider = project.browser.provider.name, providerString = provider === "preview" ? "" : ` by ${c.reset(c.bold(provider))}`;
|
|
5613
5539
|
this.log(c.dim(`${output}Browser runner started${providerString} ${c.dim("at")} ${c.blue(new URL("/__vitest_test__/", origin))}\n`));
|
|
5614
5540
|
}
|
|
5615
5541
|
printUnhandledErrors(errors) {
|
|
5616
5542
|
const errorMessage = c.red(c.bold(`\nVitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
|
|
5617
5543
|
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`));
|
|
5618
|
-
this.error(errorBanner("Unhandled Errors"))
|
|
5619
|
-
this.error(errorMessage);
|
|
5620
|
-
errors.forEach((err) => {
|
|
5544
|
+
this.error(errorBanner("Unhandled Errors")), this.error(errorMessage), errors.forEach((err) => {
|
|
5621
5545
|
this.printError(err, {
|
|
5622
5546
|
fullStack: true,
|
|
5623
5547
|
type: err.type || "Unhandled Error"
|
|
5624
5548
|
});
|
|
5625
|
-
});
|
|
5626
|
-
this.error(c.red(divider()));
|
|
5549
|
+
}), this.error(c.red(divider()));
|
|
5627
5550
|
}
|
|
5628
5551
|
printSourceTypeErrors(errors) {
|
|
5629
5552
|
const errorMessage = c.red(c.bold(`\nVitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related to your test files.`));
|
|
5630
|
-
this.log(errorBanner("Source Errors"))
|
|
5631
|
-
this.log(errorMessage);
|
|
5632
|
-
errors.forEach((err) => {
|
|
5553
|
+
this.log(errorBanner("Source Errors")), this.log(errorMessage), errors.forEach((err) => {
|
|
5633
5554
|
this.printError(err, { fullStack: true });
|
|
5634
|
-
});
|
|
5635
|
-
this.log(c.red(divider()));
|
|
5555
|
+
}), this.log(c.red(divider()));
|
|
5636
5556
|
}
|
|
5637
5557
|
getColumns() {
|
|
5638
5558
|
return "columns" in this.outputStream ? this.outputStream.columns : 80;
|
|
@@ -5642,38 +5562,25 @@ This might cause false positive tests. Resolve unhandled errors to make sure you
|
|
|
5642
5562
|
}
|
|
5643
5563
|
addCleanupListeners() {
|
|
5644
5564
|
const cleanup = () => {
|
|
5645
|
-
this.cleanupListeners.forEach((fn) => fn());
|
|
5646
|
-
|
|
5647
|
-
};
|
|
5648
|
-
const onExit = (signal, exitCode) => {
|
|
5649
|
-
cleanup();
|
|
5565
|
+
if (this.cleanupListeners.forEach((fn) => fn()), this.outputStream.isTTY) this.outputStream.write(SHOW_CURSOR);
|
|
5566
|
+
}, onExit = (signal, exitCode) => {
|
|
5650
5567
|
// Interrupted signals don't set exit code automatically.
|
|
5651
5568
|
// Use same exit code as node: https://nodejs.org/api/process.html#signal-events
|
|
5652
|
-
if (process.exitCode === void 0) process.exitCode = exitCode !== void 0 ? 128 + exitCode : Number(signal);
|
|
5569
|
+
if (cleanup(), process.exitCode === void 0) process.exitCode = exitCode !== void 0 ? 128 + exitCode : Number(signal);
|
|
5653
5570
|
process.exit();
|
|
5654
5571
|
};
|
|
5655
|
-
process.once("SIGINT", onExit)
|
|
5656
|
-
|
|
5657
|
-
process.once("exit", onExit);
|
|
5658
|
-
this.ctx.onClose(() => {
|
|
5659
|
-
process.off("SIGINT", onExit);
|
|
5660
|
-
process.off("SIGTERM", onExit);
|
|
5661
|
-
process.off("exit", onExit);
|
|
5662
|
-
cleanup();
|
|
5572
|
+
process.once("SIGINT", onExit), process.once("SIGTERM", onExit), process.once("exit", onExit), this.ctx.onClose(() => {
|
|
5573
|
+
process.off("SIGINT", onExit), process.off("SIGTERM", onExit), process.off("exit", onExit), cleanup();
|
|
5663
5574
|
});
|
|
5664
5575
|
}
|
|
5665
5576
|
registerUnhandledRejection() {
|
|
5666
5577
|
const onUnhandledRejection = (err) => {
|
|
5667
|
-
process.exitCode = 1
|
|
5668
|
-
this.printError(err, {
|
|
5578
|
+
process.exitCode = 1, this.printError(err, {
|
|
5669
5579
|
fullStack: true,
|
|
5670
5580
|
type: "Unhandled Rejection"
|
|
5671
|
-
});
|
|
5672
|
-
this.error("\n\n");
|
|
5673
|
-
process.exit();
|
|
5581
|
+
}), this.error("\n\n"), process.exit();
|
|
5674
5582
|
};
|
|
5675
|
-
process.on("unhandledRejection", onUnhandledRejection)
|
|
5676
|
-
this.ctx.onClose(() => {
|
|
5583
|
+
process.on("unhandledRejection", onUnhandledRejection), this.ctx.onClose(() => {
|
|
5677
5584
|
process.off("unhandledRejection", onUnhandledRejection);
|
|
5678
5585
|
});
|
|
5679
5586
|
}
|
|
@@ -5689,36 +5596,26 @@ class VitestPackageInstaller {
|
|
|
5689
5596
|
if (process.versions.pnp) {
|
|
5690
5597
|
const targetRequire = createRequire(__dirname);
|
|
5691
5598
|
try {
|
|
5692
|
-
targetRequire.resolve(dependency, { paths: [root, __dirname] });
|
|
5693
|
-
return true;
|
|
5599
|
+
return targetRequire.resolve(dependency, { paths: [root, __dirname] }), true;
|
|
5694
5600
|
} catch {}
|
|
5695
5601
|
}
|
|
5696
5602
|
if (/* @__PURE__ */ isPackageExists(dependency, { paths: [root, __dirname] })) return true;
|
|
5697
|
-
process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'\n\n`));
|
|
5698
|
-
|
|
5699
|
-
const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; });
|
|
5700
|
-
const { install } = await prompts.default({
|
|
5603
|
+
if (process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'\n\n`)), !isTTY) return false;
|
|
5604
|
+
const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; }), { install } = await prompts.default({
|
|
5701
5605
|
type: "confirm",
|
|
5702
5606
|
name: "install",
|
|
5703
5607
|
message: c.reset(`Do you want to install ${c.green(dependency)}?`)
|
|
5704
5608
|
});
|
|
5705
5609
|
if (install) {
|
|
5706
5610
|
const packageName = version ? `${dependency}@${version}` : dependency;
|
|
5707
|
-
await (await import('./index.D3XRDfWc.js')).installPackage(packageName, { dev: true });
|
|
5708
|
-
// TODO: somehow it fails to load the package after installation, remove this when it's fixed
|
|
5709
|
-
process.stderr.write(c.yellow(`\nPackage ${packageName} installed, re-run the command to start.\n`));
|
|
5710
|
-
process.exit();
|
|
5711
|
-
return true;
|
|
5611
|
+
return await (await import('./index.D3XRDfWc.js')).installPackage(packageName, { dev: true }), process.stderr.write(c.yellow(`\nPackage ${packageName} installed, re-run the command to start.\n`)), process.exit(), true;
|
|
5712
5612
|
}
|
|
5713
5613
|
return false;
|
|
5714
5614
|
}
|
|
5715
5615
|
}
|
|
5716
5616
|
|
|
5717
5617
|
function serializeConfig(config, coreConfig, viteConfig) {
|
|
5718
|
-
const optimizer = config.deps?.optimizer || {};
|
|
5719
|
-
const poolOptions = config.poolOptions;
|
|
5720
|
-
// Resolve from server.config to avoid comparing against default value
|
|
5721
|
-
const isolate = viteConfig?.test?.isolate;
|
|
5618
|
+
const optimizer = config.deps?.optimizer || {}, poolOptions = config.poolOptions, isolate = viteConfig?.test?.isolate;
|
|
5722
5619
|
return {
|
|
5723
5620
|
environmentOptions: config.environmentOptions,
|
|
5724
5621
|
mode: config.mode,
|
|
@@ -5752,8 +5649,7 @@ function serializeConfig(config, coreConfig, viteConfig) {
|
|
|
5752
5649
|
snapshotEnvironment: config.snapshotEnvironment,
|
|
5753
5650
|
passWithNoTests: config.passWithNoTests,
|
|
5754
5651
|
coverage: ((coverage) => {
|
|
5755
|
-
const htmlReporter = coverage.reporter.find(([reporterName]) => reporterName === "html");
|
|
5756
|
-
const subdir = htmlReporter && htmlReporter[1]?.subdir;
|
|
5652
|
+
const htmlReporter = coverage.reporter.find(([reporterName]) => reporterName === "html"), subdir = htmlReporter && htmlReporter[1]?.subdir;
|
|
5757
5653
|
return {
|
|
5758
5654
|
reportsDirectory: coverage.reportsDirectory,
|
|
5759
5655
|
provider: coverage.provider,
|
|
@@ -5778,8 +5674,7 @@ function serializeConfig(config, coreConfig, viteConfig) {
|
|
|
5778
5674
|
deps: {
|
|
5779
5675
|
web: config.deps.web || {},
|
|
5780
5676
|
optimizer: Object.entries(optimizer).reduce((acc, [name, option]) => {
|
|
5781
|
-
acc[name] = { enabled: option?.enabled ?? false };
|
|
5782
|
-
return acc;
|
|
5677
|
+
return acc[name] = { enabled: option?.enabled ?? false }, acc;
|
|
5783
5678
|
}, {}),
|
|
5784
5679
|
interopDefault: config.deps.interopDefault,
|
|
5785
5680
|
moduleDirectories: config.deps.moduleDirectories
|
|
@@ -5840,12 +5735,12 @@ async function loadGlobalSetupFile(file, runner) {
|
|
|
5840
5735
|
file,
|
|
5841
5736
|
setup: m.default
|
|
5842
5737
|
};
|
|
5843
|
-
|
|
5738
|
+
if (m.setup || m.teardown) return {
|
|
5844
5739
|
file,
|
|
5845
5740
|
setup: m.setup,
|
|
5846
5741
|
teardown: m.teardown
|
|
5847
5742
|
};
|
|
5848
|
-
|
|
5743
|
+
throw new Error(`invalid globalSetup file ${file}. Must export setup, teardown or have a default export`);
|
|
5849
5744
|
}
|
|
5850
5745
|
|
|
5851
5746
|
function CoverageTransform(ctx) {
|
|
@@ -6350,12 +6245,10 @@ function MetaEnvReplacerPlugin() {
|
|
|
6350
6245
|
transform(code, id) {
|
|
6351
6246
|
if (!/\bimport\.meta\.env\b/.test(code)) return null;
|
|
6352
6247
|
let s = null;
|
|
6353
|
-
const cleanCode = stripLiteral(code);
|
|
6354
|
-
const envs = cleanCode.matchAll(/\bimport\.meta\.env\b/g);
|
|
6248
|
+
const cleanCode = stripLiteral(code), envs = cleanCode.matchAll(/\bimport\.meta\.env\b/g);
|
|
6355
6249
|
for (const env of envs) {
|
|
6356
6250
|
s ||= new MagicString(code);
|
|
6357
|
-
const startIndex = env.index;
|
|
6358
|
-
const endIndex = startIndex + env[0].length;
|
|
6251
|
+
const startIndex = env.index, endIndex = startIndex + env[0].length;
|
|
6359
6252
|
s.overwrite(startIndex, endIndex, `Object.assign(/* istanbul ignore next */ globalThis.__vitest_worker__?.metaEnv ?? import.meta.env)`);
|
|
6360
6253
|
}
|
|
6361
6254
|
if (s) return {
|
|
@@ -6373,9 +6266,7 @@ function MocksPlugins(options = {}) {
|
|
|
6373
6266
|
const normalizedDistDir = normalize(distDir);
|
|
6374
6267
|
return [hoistMocksPlugin({
|
|
6375
6268
|
filter(id) {
|
|
6376
|
-
|
|
6377
|
-
if (options.filter) return options.filter(id);
|
|
6378
|
-
return true;
|
|
6269
|
+
return id.includes(normalizedDistDir) ? false : options.filter ? options.filter(id) : true;
|
|
6379
6270
|
},
|
|
6380
6271
|
codeFrameGenerator(node, id, code) {
|
|
6381
6272
|
return generateCodeFrame(code, 4, node.start + 1);
|
|
@@ -6401,34 +6292,23 @@ const LogLevels = {
|
|
|
6401
6292
|
info: 3
|
|
6402
6293
|
};
|
|
6403
6294
|
function clearScreen(logger) {
|
|
6404
|
-
const repeatCount = process.stdout.rows - 2;
|
|
6405
|
-
const blank = repeatCount > 0 ? "\n".repeat(repeatCount) : "";
|
|
6295
|
+
const repeatCount = process.stdout.rows - 2, blank = repeatCount > 0 ? "\n".repeat(repeatCount) : "";
|
|
6406
6296
|
logger.clearScreen(blank);
|
|
6407
6297
|
}
|
|
6408
|
-
let lastType;
|
|
6409
|
-
let lastMsg;
|
|
6410
|
-
let sameCount = 0;
|
|
6411
|
-
// Only initialize the timeFormatter when the timestamp option is used, and
|
|
6412
|
-
// reuse it across all loggers
|
|
6413
|
-
let timeFormatter;
|
|
6298
|
+
let lastType, lastMsg, sameCount = 0, timeFormatter;
|
|
6414
6299
|
function getTimeFormatter() {
|
|
6415
|
-
timeFormatter ??= new Intl.DateTimeFormat(void 0, {
|
|
6300
|
+
return timeFormatter ??= new Intl.DateTimeFormat(void 0, {
|
|
6416
6301
|
hour: "numeric",
|
|
6417
6302
|
minute: "numeric",
|
|
6418
6303
|
second: "numeric"
|
|
6419
|
-
});
|
|
6420
|
-
return timeFormatter;
|
|
6304
|
+
}), timeFormatter;
|
|
6421
6305
|
}
|
|
6422
6306
|
// This is copy-pasted and needs to be synced from time to time. Ideally, Vite's `createLogger` should accept a custom `console`
|
|
6423
6307
|
// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/logger.ts?rgh-link-date=2024-10-16T23%3A29%3A19Z
|
|
6424
6308
|
// When Vitest supports only Vite 6 and above, we can use Vite's `createLogger({ console })`
|
|
6425
6309
|
// https://github.com/vitejs/vite/pull/18379
|
|
6426
6310
|
function createViteLogger(console, level = "info", options = {}) {
|
|
6427
|
-
const loggedErrors = /* @__PURE__ */ new WeakSet();
|
|
6428
|
-
const { prefix = "[vite]", allowClearScreen = true } = options;
|
|
6429
|
-
const thresh = LogLevels[level];
|
|
6430
|
-
const canClearScreen = allowClearScreen && process.stdout.isTTY && !process.env.CI;
|
|
6431
|
-
const clear = canClearScreen ? clearScreen : () => {};
|
|
6311
|
+
const loggedErrors = /* @__PURE__ */ new WeakSet(), { prefix = "[vite]", allowClearScreen = true } = options, thresh = LogLevels[level], canClearScreen = allowClearScreen && process.stdout.isTTY && !process.env.CI, clear = canClearScreen ? clearScreen : () => {};
|
|
6432
6312
|
function format(type, msg, options = {}) {
|
|
6433
6313
|
if (options.timestamp) {
|
|
6434
6314
|
let tag = "";
|
|
@@ -6443,39 +6323,27 @@ function createViteLogger(console, level = "info", options = {}) {
|
|
|
6443
6323
|
if (thresh >= LogLevels[type]) {
|
|
6444
6324
|
const method = type === "info" ? "log" : type;
|
|
6445
6325
|
if (options.error) loggedErrors.add(options.error);
|
|
6446
|
-
if (canClearScreen) if (type === lastType && msg === lastMsg) {
|
|
6447
|
-
|
|
6448
|
-
clear(console);
|
|
6449
|
-
console[method](format(type, msg, options), c.yellow(`(x${sameCount + 1})`));
|
|
6450
|
-
} else {
|
|
6451
|
-
sameCount = 0;
|
|
6452
|
-
lastMsg = msg;
|
|
6453
|
-
lastType = type;
|
|
6454
|
-
if (options.clear) clear(console);
|
|
6326
|
+
if (canClearScreen) if (type === lastType && msg === lastMsg) sameCount++, clear(console), console[method](format(type, msg, options), c.yellow(`(x${sameCount + 1})`));
|
|
6327
|
+
else {
|
|
6328
|
+
if (sameCount = 0, lastMsg = msg, lastType = type, options.clear) clear(console);
|
|
6455
6329
|
console[method](format(type, msg, options));
|
|
6456
6330
|
}
|
|
6457
6331
|
else console[method](format(type, msg, options));
|
|
6458
6332
|
}
|
|
6459
6333
|
}
|
|
6460
|
-
const warnedMessages = /* @__PURE__ */ new Set()
|
|
6461
|
-
const logger = {
|
|
6334
|
+
const warnedMessages = /* @__PURE__ */ new Set(), logger = {
|
|
6462
6335
|
hasWarned: false,
|
|
6463
6336
|
info(msg, opts) {
|
|
6464
6337
|
output("info", msg, opts);
|
|
6465
6338
|
},
|
|
6466
6339
|
warn(msg, opts) {
|
|
6467
|
-
logger.hasWarned = true;
|
|
6468
|
-
output("warn", msg, opts);
|
|
6340
|
+
logger.hasWarned = true, output("warn", msg, opts);
|
|
6469
6341
|
},
|
|
6470
6342
|
warnOnce(msg, opts) {
|
|
6471
|
-
|
|
6472
|
-
logger.hasWarned = true;
|
|
6473
|
-
output("warn", msg, opts);
|
|
6474
|
-
warnedMessages.add(msg);
|
|
6343
|
+
warnedMessages.has(msg) || (logger.hasWarned = true, output("warn", msg, opts), warnedMessages.add(msg));
|
|
6475
6344
|
},
|
|
6476
6345
|
error(msg, opts) {
|
|
6477
|
-
logger.hasWarned = true;
|
|
6478
|
-
output("error", msg, opts);
|
|
6346
|
+
logger.hasWarned = true, output("error", msg, opts);
|
|
6479
6347
|
},
|
|
6480
6348
|
clearScreen(type) {
|
|
6481
6349
|
if (thresh >= LogLevels[type]) clear(console);
|
|
@@ -6491,16 +6359,12 @@ function silenceImportViteIgnoreWarning(logger) {
|
|
|
6491
6359
|
return {
|
|
6492
6360
|
...logger,
|
|
6493
6361
|
warn(msg, options) {
|
|
6494
|
-
|
|
6495
|
-
logger.warn(msg, options);
|
|
6362
|
+
msg.includes("The above dynamic import cannot be analyzed by Vite") || logger.warn(msg, options);
|
|
6496
6363
|
}
|
|
6497
6364
|
};
|
|
6498
6365
|
}
|
|
6499
6366
|
|
|
6500
|
-
const cssLangs = "\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss)(?:$|\\?)"
|
|
6501
|
-
const cssLangRE = new RegExp(cssLangs);
|
|
6502
|
-
const cssModuleRE = /* @__PURE__ */ new RegExp(`\\.module${cssLangs}`);
|
|
6503
|
-
const cssInlineRE = /[?&]inline(?:&|$)/;
|
|
6367
|
+
const cssLangs = "\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss)(?:$|\\?)", cssLangRE = new RegExp(cssLangs), cssModuleRE = /* @__PURE__ */ new RegExp(`\\.module${cssLangs}`), cssInlineRE = /[?&]inline(?:&|$)/;
|
|
6504
6368
|
function isCSS(id) {
|
|
6505
6369
|
return cssLangRE.test(id);
|
|
6506
6370
|
}
|
|
@@ -6520,45 +6384,37 @@ function getCSSModuleProxyReturn(strategy, filename) {
|
|
|
6520
6384
|
function CSSEnablerPlugin(ctx) {
|
|
6521
6385
|
const shouldProcessCSS = (id) => {
|
|
6522
6386
|
const { css } = ctx.config;
|
|
6523
|
-
|
|
6524
|
-
if (toArray(css.exclude).some((re) => re.test(id))) return false;
|
|
6525
|
-
if (toArray(css.include).some((re) => re.test(id))) return true;
|
|
6526
|
-
return false;
|
|
6387
|
+
return typeof css === "boolean" ? css : toArray(css.exclude).some((re) => re.test(id)) ? false : !!toArray(css.include).some((re) => re.test(id));
|
|
6527
6388
|
};
|
|
6528
6389
|
return [{
|
|
6529
6390
|
name: "vitest:css-disable",
|
|
6530
6391
|
enforce: "pre",
|
|
6531
6392
|
transform(code, id) {
|
|
6532
|
-
if (
|
|
6533
|
-
// css plugin inside Vite won't do anything if the code is empty
|
|
6534
|
-
// but it will put __vite__updateStyle anyway
|
|
6535
|
-
if (!shouldProcessCSS(id)) return { code: "" };
|
|
6393
|
+
if (isCSS(id) && !shouldProcessCSS(id)) return { code: "" };
|
|
6536
6394
|
}
|
|
6537
6395
|
}, {
|
|
6538
6396
|
name: "vitest:css-empty-post",
|
|
6539
6397
|
enforce: "post",
|
|
6540
6398
|
transform(_, id) {
|
|
6541
|
-
if (!isCSS(id) || shouldProcessCSS(id))
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
const proxyReturn = getCSSModuleProxyReturn(scopeStrategy, relative(ctx.config.root, id));
|
|
6548
|
-
const code = `export default new Proxy(Object.create(null), {
|
|
6399
|
+
if (!(!isCSS(id) || shouldProcessCSS(id))) {
|
|
6400
|
+
if (isCSSModule(id) && !isInline(id)) {
|
|
6401
|
+
// return proxy for css modules, so that imported module has names:
|
|
6402
|
+
// styles.foo returns a "foo" instead of "undefined"
|
|
6403
|
+
// we don't use code content to generate hash for "scoped", because it's empty
|
|
6404
|
+
const scopeStrategy = typeof ctx.config.css !== "boolean" && ctx.config.css.modules?.classNameStrategy || "stable", proxyReturn = getCSSModuleProxyReturn(scopeStrategy, relative(ctx.config.root, id)), code = `export default new Proxy(Object.create(null), {
|
|
6549
6405
|
get(_, style) {
|
|
6550
6406
|
return ${proxyReturn};
|
|
6551
6407
|
},
|
|
6552
6408
|
})`;
|
|
6553
|
-
|
|
6409
|
+
return { code };
|
|
6410
|
+
}
|
|
6411
|
+
return { code: "export default \"\"" };
|
|
6554
6412
|
}
|
|
6555
|
-
return { code: "export default \"\"" };
|
|
6556
6413
|
}
|
|
6557
6414
|
}];
|
|
6558
6415
|
}
|
|
6559
6416
|
|
|
6560
|
-
const metaUrlLength = 15;
|
|
6561
|
-
const locationString = "self.location".padEnd(metaUrlLength, " ");
|
|
6417
|
+
const metaUrlLength = 15, locationString = "self.location".padEnd(metaUrlLength, " ");
|
|
6562
6418
|
// Vite transforms new URL('./path', import.meta.url) to new URL('/path.js', import.meta.url)
|
|
6563
6419
|
// This makes "href" equal to "http://localhost:3000/path.js" in the browser, but if we keep it like this,
|
|
6564
6420
|
// then in tests the URL will become "file:///path.js".
|
|
@@ -6569,14 +6425,11 @@ function NormalizeURLPlugin() {
|
|
|
6569
6425
|
enforce: "post",
|
|
6570
6426
|
transform(code) {
|
|
6571
6427
|
if (this.environment.name !== "client" || !code.includes("new URL") || !code.includes("import.meta.url")) return;
|
|
6572
|
-
const cleanString = stripLiteral(code);
|
|
6573
|
-
|
|
6574
|
-
let updatedCode = code;
|
|
6575
|
-
let match;
|
|
6428
|
+
const cleanString = stripLiteral(code), assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*(?:'[^']+'|"[^"]+"|`[^`]+`)\s*,\s*(?:'' \+ )?import\.meta\.url\s*(?:,\s*)?\)/g;
|
|
6429
|
+
let updatedCode = code, match;
|
|
6576
6430
|
// eslint-disable-next-line no-cond-assign
|
|
6577
6431
|
while (match = assetImportMetaUrlRE.exec(cleanString)) {
|
|
6578
|
-
const { 0: exp, index } = match;
|
|
6579
|
-
const metaUrlIndex = index + exp.indexOf("import.meta.url");
|
|
6432
|
+
const { 0: exp, index } = match, metaUrlIndex = index + exp.indexOf("import.meta.url");
|
|
6580
6433
|
updatedCode = updatedCode.slice(0, metaUrlIndex) + locationString + updatedCode.slice(metaUrlIndex + metaUrlLength);
|
|
6581
6434
|
}
|
|
6582
6435
|
return {
|
|
@@ -6593,10 +6446,7 @@ function VitestOptimizer() {
|
|
|
6593
6446
|
config: {
|
|
6594
6447
|
order: "post",
|
|
6595
6448
|
handler(viteConfig) {
|
|
6596
|
-
const testConfig = viteConfig.test || {};
|
|
6597
|
-
const root = resolve(viteConfig.root || process.cwd());
|
|
6598
|
-
const name = viteConfig.test?.name;
|
|
6599
|
-
const label = typeof name === "string" ? name : name?.label || "";
|
|
6449
|
+
const testConfig = viteConfig.test || {}, root = resolve(viteConfig.root || process.cwd()), name = viteConfig.test?.name, label = typeof name === "string" ? name : name?.label || "";
|
|
6600
6450
|
viteConfig.cacheDir = VitestCache.resolveCacheDir(resolve(root || process.cwd()), testConfig.cache != null && testConfig.cache !== false ? testConfig.cache.dir : viteConfig.cacheDir, label);
|
|
6601
6451
|
}
|
|
6602
6452
|
}
|
|
@@ -6606,21 +6456,17 @@ function VitestOptimizer() {
|
|
|
6606
6456
|
function resolveOptimizerConfig(_testOptions, viteOptions) {
|
|
6607
6457
|
const testOptions = _testOptions || {};
|
|
6608
6458
|
let optimizeDeps;
|
|
6609
|
-
if (testOptions.enabled !== true) {
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
} else {
|
|
6616
|
-
const currentInclude = testOptions.include || viteOptions?.include || [];
|
|
6617
|
-
const exclude = [
|
|
6459
|
+
if (testOptions.enabled !== true) testOptions.enabled ??= false, optimizeDeps = {
|
|
6460
|
+
disabled: true,
|
|
6461
|
+
entries: []
|
|
6462
|
+
};
|
|
6463
|
+
else {
|
|
6464
|
+
const currentInclude = testOptions.include || viteOptions?.include || [], exclude = [
|
|
6618
6465
|
"vitest",
|
|
6619
6466
|
"react",
|
|
6620
6467
|
"vue",
|
|
6621
6468
|
...testOptions.exclude || viteOptions?.exclude || []
|
|
6622
|
-
];
|
|
6623
|
-
const runtime = currentInclude.filter((n) => n.endsWith("jsx-dev-runtime") || n.endsWith("jsx-runtime"));
|
|
6469
|
+
], runtime = currentInclude.filter((n) => n.endsWith("jsx-dev-runtime") || n.endsWith("jsx-runtime"));
|
|
6624
6470
|
exclude.push(...runtime);
|
|
6625
6471
|
const include = (testOptions.include || viteOptions?.include || []).filter((n) => !exclude.includes(n));
|
|
6626
6472
|
optimizeDeps = {
|
|
@@ -6635,21 +6481,12 @@ function resolveOptimizerConfig(_testOptions, viteOptions) {
|
|
|
6635
6481
|
}
|
|
6636
6482
|
// `optimizeDeps.disabled` is deprecated since v5.1.0-beta.1
|
|
6637
6483
|
// https://github.com/vitejs/vite/pull/15184
|
|
6638
|
-
if (optimizeDeps.disabled)
|
|
6639
|
-
|
|
6640
|
-
optimizeDeps.include = [];
|
|
6641
|
-
}
|
|
6642
|
-
delete optimizeDeps.disabled;
|
|
6643
|
-
return optimizeDeps;
|
|
6484
|
+
if (optimizeDeps.disabled) optimizeDeps.noDiscovery = true, optimizeDeps.include = [];
|
|
6485
|
+
return delete optimizeDeps.disabled, optimizeDeps;
|
|
6644
6486
|
}
|
|
6645
6487
|
function deleteDefineConfig(viteConfig) {
|
|
6646
6488
|
const defines = {};
|
|
6647
|
-
if (viteConfig.define)
|
|
6648
|
-
delete viteConfig.define["import.meta.vitest"];
|
|
6649
|
-
delete viteConfig.define["process.env"];
|
|
6650
|
-
delete viteConfig.define.process;
|
|
6651
|
-
delete viteConfig.define.global;
|
|
6652
|
-
}
|
|
6489
|
+
if (viteConfig.define) delete viteConfig.define["import.meta.vitest"], delete viteConfig.define["process.env"], delete viteConfig.define.process, delete viteConfig.define.global;
|
|
6653
6490
|
for (const key in viteConfig.define) {
|
|
6654
6491
|
const val = viteConfig.define[key];
|
|
6655
6492
|
let replacement;
|
|
@@ -6662,26 +6499,20 @@ function deleteDefineConfig(viteConfig) {
|
|
|
6662
6499
|
}
|
|
6663
6500
|
if (key.startsWith("import.meta.env.")) {
|
|
6664
6501
|
const envKey = key.slice(16);
|
|
6665
|
-
process.env[envKey] = replacement;
|
|
6666
|
-
delete viteConfig.define[key];
|
|
6502
|
+
process.env[envKey] = replacement, delete viteConfig.define[key];
|
|
6667
6503
|
} else if (key.startsWith("process.env.")) {
|
|
6668
6504
|
const envKey = key.slice(12);
|
|
6669
|
-
process.env[envKey] = replacement;
|
|
6670
|
-
|
|
6671
|
-
} else if (!key.includes(".")) {
|
|
6672
|
-
defines[key] = replacement;
|
|
6673
|
-
delete viteConfig.define[key];
|
|
6674
|
-
}
|
|
6505
|
+
process.env[envKey] = replacement, delete viteConfig.define[key];
|
|
6506
|
+
} else if (!key.includes(".")) defines[key] = replacement, delete viteConfig.define[key];
|
|
6675
6507
|
}
|
|
6676
6508
|
return defines;
|
|
6677
6509
|
}
|
|
6678
6510
|
function resolveFsAllow(projectRoot, rootConfigFile) {
|
|
6679
|
-
|
|
6680
|
-
return [
|
|
6511
|
+
return rootConfigFile ? [
|
|
6681
6512
|
dirname(rootConfigFile),
|
|
6682
6513
|
searchForWorkspaceRoot(projectRoot),
|
|
6683
6514
|
rootDir
|
|
6684
|
-
];
|
|
6515
|
+
] : [searchForWorkspaceRoot(projectRoot), rootDir];
|
|
6685
6516
|
}
|
|
6686
6517
|
function getDefaultResolveOptions() {
|
|
6687
6518
|
return {
|
|
@@ -6708,78 +6539,44 @@ function ModuleRunnerTransform() {
|
|
|
6708
6539
|
const testConfig = config.test || {};
|
|
6709
6540
|
config.environments ??= {};
|
|
6710
6541
|
const names = new Set(Object.keys(config.environments));
|
|
6711
|
-
names.add("client");
|
|
6712
|
-
names.add("ssr");
|
|
6542
|
+
names.add("client"), names.add("ssr");
|
|
6713
6543
|
const pool = config.test?.pool;
|
|
6714
6544
|
if (pool === "vmForks" || pool === "vmThreads") names.add("__vitest_vm__");
|
|
6715
|
-
const external = [];
|
|
6716
|
-
const noExternal = [];
|
|
6545
|
+
const external = [], noExternal = [];
|
|
6717
6546
|
let noExternalAll;
|
|
6718
6547
|
for (const name of names) {
|
|
6719
6548
|
config.environments[name] ??= {};
|
|
6720
6549
|
const environment = config.environments[name];
|
|
6721
|
-
environment.dev ??= {};
|
|
6722
6550
|
// vm tests run using the native import mechanism
|
|
6723
|
-
if (name === "__vitest_vm__")
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
environment.dev.preTransformRequests = false;
|
|
6728
|
-
environment.keepProcessEnv = true;
|
|
6729
|
-
const resolveExternal = name === "client" ? config.resolve?.external : [];
|
|
6730
|
-
const resolveNoExternal = name === "client" ? config.resolve?.noExternal : [];
|
|
6731
|
-
const topLevelResolveOptions = {};
|
|
6551
|
+
if (environment.dev ??= {}, name === "__vitest_vm__") environment.dev.moduleRunnerTransform = false, environment.consumer = "client";
|
|
6552
|
+
else environment.dev.moduleRunnerTransform = true;
|
|
6553
|
+
environment.dev.preTransformRequests = false, environment.keepProcessEnv = true;
|
|
6554
|
+
const resolveExternal = name === "client" ? config.resolve?.external : [], resolveNoExternal = name === "client" ? config.resolve?.noExternal : [], topLevelResolveOptions = {};
|
|
6732
6555
|
if (resolveExternal != null) topLevelResolveOptions.external = resolveExternal;
|
|
6733
6556
|
if (resolveNoExternal != null) topLevelResolveOptions.noExternal = resolveNoExternal;
|
|
6734
|
-
const currentResolveOptions = mergeConfig(topLevelResolveOptions, environment.resolve || {});
|
|
6735
|
-
const envNoExternal = resolveViteResolveOptions("noExternal", currentResolveOptions);
|
|
6557
|
+
const currentResolveOptions = mergeConfig(topLevelResolveOptions, environment.resolve || {}), envNoExternal = resolveViteResolveOptions("noExternal", currentResolveOptions);
|
|
6736
6558
|
if (envNoExternal === true) noExternalAll = true;
|
|
6737
6559
|
else noExternal.push(...envNoExternal);
|
|
6738
6560
|
const envExternal = resolveViteResolveOptions("external", currentResolveOptions);
|
|
6739
6561
|
if (envExternal !== true) external.push(...envExternal);
|
|
6740
|
-
|
|
6741
|
-
environment.
|
|
6742
|
-
environment.resolve.external = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)];
|
|
6743
|
-
// by setting `noExternal` to `true`, we make sure that
|
|
6744
|
-
// Vite will never use its own externalization mechanism
|
|
6745
|
-
// to externalize modules and always resolve static imports
|
|
6746
|
-
// in both SSR and Client environments
|
|
6747
|
-
environment.resolve.noExternal = true;
|
|
6748
|
-
if (name === "__vitest_vm__" || name === "__vitest__") continue;
|
|
6749
|
-
const currentOptimizeDeps = environment.optimizeDeps || (name === "client" ? config.optimizeDeps : name === "ssr" ? config.ssr?.optimizeDeps : void 0);
|
|
6750
|
-
const optimizeDeps = resolveOptimizerConfig(testConfig.deps?.optimizer?.[name], currentOptimizeDeps);
|
|
6562
|
+
if (environment.resolve ??= {}, environment.resolve.external = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)], environment.resolve.noExternal = true, name === "__vitest_vm__" || name === "__vitest__") continue;
|
|
6563
|
+
const currentOptimizeDeps = environment.optimizeDeps || (name === "client" ? config.optimizeDeps : name === "ssr" ? config.ssr?.optimizeDeps : void 0), optimizeDeps = resolveOptimizerConfig(testConfig.deps?.optimizer?.[name], currentOptimizeDeps);
|
|
6751
6564
|
// Vite respects the root level optimize deps, so we override it instead
|
|
6752
|
-
if (name === "client")
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
} else if (name === "ssr") {
|
|
6756
|
-
config.ssr ??= {};
|
|
6757
|
-
config.ssr.optimizeDeps = optimizeDeps;
|
|
6758
|
-
environment.optimizeDeps = void 0;
|
|
6759
|
-
} else environment.optimizeDeps = optimizeDeps;
|
|
6565
|
+
if (name === "client") config.optimizeDeps = optimizeDeps, environment.optimizeDeps = void 0;
|
|
6566
|
+
else if (name === "ssr") config.ssr ??= {}, config.ssr.optimizeDeps = optimizeDeps, environment.optimizeDeps = void 0;
|
|
6567
|
+
else environment.optimizeDeps = optimizeDeps;
|
|
6760
6568
|
}
|
|
6761
|
-
testConfig.server ??= {}
|
|
6762
|
-
testConfig.server.deps ??= {};
|
|
6763
|
-
if (testConfig.server.deps.inline !== true) {
|
|
6569
|
+
if (testConfig.server ??= {}, testConfig.server.deps ??= {}, testConfig.server.deps.inline !== true) {
|
|
6764
6570
|
if (noExternalAll) testConfig.server.deps.inline = true;
|
|
6765
|
-
else if (noExternal.length)
|
|
6766
|
-
testConfig.server.deps.inline ??= [];
|
|
6767
|
-
testConfig.server.deps.inline.push(...noExternal);
|
|
6768
|
-
}
|
|
6769
|
-
}
|
|
6770
|
-
if (external.length) {
|
|
6771
|
-
testConfig.server.deps.external ??= [];
|
|
6772
|
-
testConfig.server.deps.external.push(...external);
|
|
6571
|
+
else if (noExternal.length) testConfig.server.deps.inline ??= [], testConfig.server.deps.inline.push(...noExternal);
|
|
6773
6572
|
}
|
|
6573
|
+
if (external.length) testConfig.server.deps.external ??= [], testConfig.server.deps.external.push(...external);
|
|
6774
6574
|
}
|
|
6775
6575
|
}
|
|
6776
6576
|
};
|
|
6777
6577
|
}
|
|
6778
6578
|
function resolveViteResolveOptions(key, options) {
|
|
6779
|
-
|
|
6780
|
-
else if (typeof options[key] === "string" || options[key] instanceof RegExp) return [options[key]];
|
|
6781
|
-
else if (typeof options[key] === "boolean") return true;
|
|
6782
|
-
return [];
|
|
6579
|
+
return Array.isArray(options[key]) ? options[key] : typeof options[key] === "string" || options[key] instanceof RegExp ? [options[key]] : typeof options[key] === "boolean" ? true : [];
|
|
6783
6580
|
}
|
|
6784
6581
|
|
|
6785
6582
|
function VitestProjectResolver(ctx) {
|
|
@@ -6826,23 +6623,16 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6826
6623
|
};
|
|
6827
6624
|
if (!name) if (typeof options.workspacePath === "string") {
|
|
6828
6625
|
// if there is a package.json, read the name from it
|
|
6829
|
-
const dir = options.workspacePath.endsWith("/") ? options.workspacePath.slice(0, -1) : dirname(options.workspacePath);
|
|
6830
|
-
const pkgJsonPath = resolve(dir, "package.json");
|
|
6626
|
+
const dir = options.workspacePath.endsWith("/") ? options.workspacePath.slice(0, -1) : dirname(options.workspacePath), pkgJsonPath = resolve(dir, "package.json");
|
|
6831
6627
|
if (existsSync(pkgJsonPath)) name = JSON.parse(readFileSync(pkgJsonPath, "utf-8")).name;
|
|
6832
6628
|
if (typeof name !== "string" || !name) name = basename(dir);
|
|
6833
6629
|
} else name = options.workspacePath.toString();
|
|
6834
|
-
const isUserBrowserEnabled = viteConfig.test?.browser?.enabled;
|
|
6835
|
-
const isBrowserEnabled = isUserBrowserEnabled ?? (viteConfig.test?.browser && project.vitest._cliOptions.browser?.enabled);
|
|
6836
|
-
// keep project names to potentially filter it out
|
|
6837
|
-
const workspaceNames = [name];
|
|
6838
|
-
const browser = viteConfig.test.browser || {};
|
|
6630
|
+
const isUserBrowserEnabled = viteConfig.test?.browser?.enabled, isBrowserEnabled = isUserBrowserEnabled ?? (viteConfig.test?.browser && project.vitest._cliOptions.browser?.enabled), workspaceNames = [name], browser = viteConfig.test.browser || {};
|
|
6839
6631
|
if (isBrowserEnabled && browser.name && !browser.instances?.length)
|
|
6840
6632
|
// vitest injects `instances` in this case later on
|
|
6841
6633
|
workspaceNames.push(name ? `${name} (${browser.name})` : browser.name);
|
|
6842
6634
|
viteConfig.test?.browser?.instances?.forEach((instance) => {
|
|
6843
|
-
|
|
6844
|
-
instance.name ??= name ? `${name} (${instance.browser})` : instance.browser;
|
|
6845
|
-
if (isBrowserEnabled) workspaceNames.push(instance.name);
|
|
6635
|
+
if (instance.name ??= name ? `${name} (${instance.browser})` : instance.browser, isBrowserEnabled) workspaceNames.push(instance.name);
|
|
6846
6636
|
});
|
|
6847
6637
|
const filters = project.vitest.config.project;
|
|
6848
6638
|
// if there is `--project=...` filter, check if any of the potential projects match
|
|
@@ -6870,22 +6660,14 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6870
6660
|
this.meta.watchMode = false;
|
|
6871
6661
|
},
|
|
6872
6662
|
config(viteConfig) {
|
|
6873
|
-
const defines = deleteDefineConfig(viteConfig);
|
|
6874
|
-
|
|
6875
|
-
const root = testConfig.root || viteConfig.root || options.root;
|
|
6876
|
-
const resolveOptions = getDefaultResolveOptions();
|
|
6877
|
-
const config = {
|
|
6663
|
+
const defines = deleteDefineConfig(viteConfig), testConfig = viteConfig.test || {}, root = testConfig.root || viteConfig.root || options.root, resolveOptions = getDefaultResolveOptions();
|
|
6664
|
+
let config = {
|
|
6878
6665
|
root,
|
|
6879
6666
|
define: { "process.env.NODE_ENV": "process.env.NODE_ENV" },
|
|
6880
6667
|
resolve: {
|
|
6881
6668
|
...resolveOptions,
|
|
6882
6669
|
alias: testConfig.alias
|
|
6883
6670
|
},
|
|
6884
|
-
esbuild: viteConfig.esbuild === false ? false : {
|
|
6885
|
-
target: viteConfig.esbuild?.target || "node18",
|
|
6886
|
-
sourcemap: "external",
|
|
6887
|
-
legalComments: "inline"
|
|
6888
|
-
},
|
|
6889
6671
|
server: {
|
|
6890
6672
|
watch: null,
|
|
6891
6673
|
open: false,
|
|
@@ -6898,19 +6680,27 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6898
6680
|
environments: { ssr: { resolve: resolveOptions } },
|
|
6899
6681
|
test: {}
|
|
6900
6682
|
};
|
|
6683
|
+
if ("rolldownVersion" in vite) config = {
|
|
6684
|
+
...config,
|
|
6685
|
+
oxc: viteConfig.oxc === false ? false : { target: viteConfig.oxc?.target || "node18" }
|
|
6686
|
+
};
|
|
6687
|
+
else config = {
|
|
6688
|
+
...config,
|
|
6689
|
+
esbuild: viteConfig.esbuild === false ? false : {
|
|
6690
|
+
target: viteConfig.esbuild?.target || "node18",
|
|
6691
|
+
sourcemap: "external",
|
|
6692
|
+
legalComments: "inline"
|
|
6693
|
+
}
|
|
6694
|
+
};
|
|
6901
6695
|
config.test.defines = defines;
|
|
6902
6696
|
const classNameStrategy = typeof testConfig.css !== "boolean" && testConfig.css?.modules?.classNameStrategy || "stable";
|
|
6903
6697
|
if (classNameStrategy !== "scoped") {
|
|
6904
|
-
config.css ??= {}
|
|
6905
|
-
config.css.modules ??= {};
|
|
6906
|
-
if (config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
|
|
6698
|
+
if (config.css ??= {}, config.css.modules ??= {}, config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
|
|
6907
6699
|
const root = project.config.root;
|
|
6908
6700
|
return generateScopedClassName(classNameStrategy, name, relative(root, filename));
|
|
6909
6701
|
};
|
|
6910
6702
|
}
|
|
6911
|
-
config.customLogger = createViteLogger(project.vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false });
|
|
6912
|
-
config.customLogger = silenceImportViteIgnoreWarning(config.customLogger);
|
|
6913
|
-
return config;
|
|
6703
|
+
return config.customLogger = createViteLogger(project.vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false }), config.customLogger = silenceImportViteIgnoreWarning(config.customLogger), config;
|
|
6914
6704
|
}
|
|
6915
6705
|
},
|
|
6916
6706
|
{
|
|
@@ -6918,8 +6708,7 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6918
6708
|
enforce: "post",
|
|
6919
6709
|
async configureServer(server) {
|
|
6920
6710
|
const options = deepMerge({}, configDefaults, server.config.test || {});
|
|
6921
|
-
await project._configureServer(options, server);
|
|
6922
|
-
await server.watcher.close();
|
|
6711
|
+
await project._configureServer(options, server), await server.watcher.close();
|
|
6923
6712
|
}
|
|
6924
6713
|
},
|
|
6925
6714
|
MetaEnvReplacerPlugin(),
|
|
@@ -6962,10 +6751,7 @@ const BUILTIN_EXTENSIONS = new Set([
|
|
|
6962
6751
|
".cjs",
|
|
6963
6752
|
".node",
|
|
6964
6753
|
".wasm"
|
|
6965
|
-
])
|
|
6966
|
-
const ESM_EXT_RE = /\.(es|esm|esm-browser|esm-bundler|es6|module)\.js$/;
|
|
6967
|
-
const ESM_FOLDER_RE = /\/(es|esm)\/(.*\.js)$/;
|
|
6968
|
-
const defaultInline = [
|
|
6754
|
+
]), ESM_EXT_RE = /\.(es|esm|esm-browser|esm-bundler|es6|module)\.js$/, ESM_FOLDER_RE = /\/(es|esm)\/(.*\.js)$/, defaultInline = [
|
|
6969
6755
|
/virtual:/,
|
|
6970
6756
|
/\.[mc]?ts$/,
|
|
6971
6757
|
/[?&](init|raw|url|inline)\b/,
|
|
@@ -6973,8 +6759,7 @@ const defaultInline = [
|
|
|
6973
6759
|
/^(?!.*node_modules).*\.mjs$/,
|
|
6974
6760
|
/^(?!.*node_modules).*\.cjs\.js$/,
|
|
6975
6761
|
/vite\w*\/dist\/client\/env.mjs/
|
|
6976
|
-
];
|
|
6977
|
-
const depsExternal = [/\/node_modules\/.*\.cjs\.js$/, /\/node_modules\/.*\.mjs$/];
|
|
6762
|
+
], depsExternal = [/\/node_modules\/.*\.cjs\.js$/, /\/node_modules\/.*\.mjs$/];
|
|
6978
6763
|
function guessCJSversion(id) {
|
|
6979
6764
|
if (id.match(ESM_EXT_RE)) {
|
|
6980
6765
|
for (const i of [
|
|
@@ -7004,8 +6789,7 @@ async function isValidNodeImport(id) {
|
|
|
7004
6789
|
if (/\.(?:\w+-)?esm?(?:-\w+)?\.js$|\/esm?\//.test(id)) return false;
|
|
7005
6790
|
try {
|
|
7006
6791
|
await esModuleLexer.init;
|
|
7007
|
-
const code = await promises.readFile(id, "utf8");
|
|
7008
|
-
const [, , , hasModuleSyntax] = esModuleLexer.parse(code);
|
|
6792
|
+
const code = await promises.readFile(id, "utf8"), [, , , hasModuleSyntax] = esModuleLexer.parse(code);
|
|
7009
6793
|
return !hasModuleSyntax;
|
|
7010
6794
|
} catch {
|
|
7011
6795
|
return false;
|
|
@@ -7016,25 +6800,17 @@ async function shouldExternalize(id, options, cache) {
|
|
|
7016
6800
|
return cache.get(id);
|
|
7017
6801
|
}
|
|
7018
6802
|
async function _shouldExternalize(id, options) {
|
|
7019
|
-
if (isBuiltin(id)) return id;
|
|
7020
6803
|
// data: should be processed by native import,
|
|
7021
6804
|
// since it is a feature of ESM.
|
|
7022
6805
|
// also externalize network imports since nodejs allows it when --experimental-network-imports
|
|
7023
|
-
if (id.startsWith("data:") || /^(?:https?:)?\/\//.test(id)) return id;
|
|
6806
|
+
if (isBuiltin(id) || id.startsWith("data:") || /^(?:https?:)?\/\//.test(id)) return id;
|
|
7024
6807
|
const moduleDirectories = options?.moduleDirectories || ["/node_modules/"];
|
|
7025
|
-
if (matchExternalizePattern(id, moduleDirectories, options?.inline)) return false;
|
|
7026
|
-
if (options?.inlineFiles && options?.inlineFiles.includes(id)) return false;
|
|
7027
|
-
if (matchExternalizePattern(id, moduleDirectories, options?.external)) return id;
|
|
6808
|
+
if (matchExternalizePattern(id, moduleDirectories, options?.inline) || options?.inlineFiles && options?.inlineFiles.includes(id)) return false;
|
|
7028
6809
|
// Unless the user explicitly opted to inline them, externalize Vite deps.
|
|
7029
6810
|
// They are too big to inline by default.
|
|
7030
|
-
if (options?.cacheDir && id.includes(options.cacheDir)) return id;
|
|
7031
|
-
const isLibraryModule = moduleDirectories.some((dir) => id.includes(dir));
|
|
7032
|
-
|
|
7033
|
-
id = guessCJS ? guessCJSversion(id) || id : id;
|
|
7034
|
-
if (matchExternalizePattern(id, moduleDirectories, defaultInline)) return false;
|
|
7035
|
-
if (matchExternalizePattern(id, moduleDirectories, depsExternal)) return id;
|
|
7036
|
-
if (isLibraryModule && await isValidNodeImport(id)) return id;
|
|
7037
|
-
return false;
|
|
6811
|
+
if (matchExternalizePattern(id, moduleDirectories, options?.external) || options?.cacheDir && id.includes(options.cacheDir)) return id;
|
|
6812
|
+
const isLibraryModule = moduleDirectories.some((dir) => id.includes(dir)), guessCJS = isLibraryModule && options?.fallbackCJS;
|
|
6813
|
+
return id = guessCJS ? guessCJSversion(id) || id : id, matchExternalizePattern(id, moduleDirectories, defaultInline) ? false : matchExternalizePattern(id, moduleDirectories, depsExternal) || isLibraryModule && await isValidNodeImport(id) ? id : false;
|
|
7038
6814
|
}
|
|
7039
6815
|
function matchExternalizePattern(id, moduleDirectories, patterns) {
|
|
7040
6816
|
if (patterns == null) return false;
|
|
@@ -7080,24 +6856,16 @@ class TestSpecification {
|
|
|
7080
6856
|
*/
|
|
7081
6857
|
testLines;
|
|
7082
6858
|
constructor(project, moduleId, pool, testLines) {
|
|
7083
|
-
this[0] = project;
|
|
7084
|
-
|
|
7085
|
-
this
|
|
7086
|
-
const name = project.config.name;
|
|
7087
|
-
const hashName = pool !== "typescript" ? name : name ? `${name}:__typecheck__` : "__typecheck__";
|
|
7088
|
-
this.taskId = generateFileHash(relative(project.config.root, moduleId), hashName);
|
|
7089
|
-
this.project = project;
|
|
7090
|
-
this.moduleId = moduleId;
|
|
7091
|
-
this.pool = pool;
|
|
7092
|
-
this.testLines = testLines;
|
|
6859
|
+
this[0] = project, this[1] = moduleId, this[2] = { pool };
|
|
6860
|
+
const name = project.config.name, hashName = pool !== "typescript" ? name : name ? `${name}:__typecheck__` : "__typecheck__";
|
|
6861
|
+
this.taskId = generateFileHash(relative(project.config.root, moduleId), hashName), this.project = project, this.moduleId = moduleId, this.pool = pool, this.testLines = testLines;
|
|
7093
6862
|
}
|
|
7094
6863
|
/**
|
|
7095
6864
|
* Test module associated with the specification.
|
|
7096
6865
|
*/
|
|
7097
6866
|
get testModule() {
|
|
7098
6867
|
const task = this.project.vitest.state.idMap.get(this.taskId);
|
|
7099
|
-
|
|
7100
|
-
return this.project.vitest.state.getReportedEntity(task);
|
|
6868
|
+
return task ? this.project.vitest.state.getReportedEntity(task) : void 0;
|
|
7101
6869
|
}
|
|
7102
6870
|
toJSON() {
|
|
7103
6871
|
return [
|
|
@@ -7117,9 +6885,7 @@ class TestSpecification {
|
|
|
7117
6885
|
* @deprecated
|
|
7118
6886
|
*/
|
|
7119
6887
|
*[Symbol.iterator]() {
|
|
7120
|
-
yield this.project;
|
|
7121
|
-
yield this.moduleId;
|
|
7122
|
-
yield this.pool;
|
|
6888
|
+
yield this.project, yield this.moduleId, yield this.pool;
|
|
7123
6889
|
}
|
|
7124
6890
|
}
|
|
7125
6891
|
|
|
@@ -7128,12 +6894,10 @@ async function createViteServer(inlineConfig) {
|
|
|
7128
6894
|
// But Vitest works correctly either way
|
|
7129
6895
|
const error = console.error;
|
|
7130
6896
|
console.error = (...args) => {
|
|
7131
|
-
|
|
7132
|
-
error(...args);
|
|
6897
|
+
typeof args[0] === "string" && args[0].includes("WebSocket server error:") || error(...args);
|
|
7133
6898
|
};
|
|
7134
6899
|
const server = await createServer(inlineConfig);
|
|
7135
|
-
console.error = error;
|
|
7136
|
-
return server;
|
|
6900
|
+
return console.error = error, server;
|
|
7137
6901
|
}
|
|
7138
6902
|
|
|
7139
6903
|
class TestProject {
|
|
@@ -7168,11 +6932,7 @@ class TestProject {
|
|
|
7168
6932
|
_globalSetups;
|
|
7169
6933
|
_provided = {};
|
|
7170
6934
|
constructor(path, vitest, options) {
|
|
7171
|
-
this.path = path;
|
|
7172
|
-
this.options = options;
|
|
7173
|
-
this.vitest = vitest;
|
|
7174
|
-
this.ctx = vitest;
|
|
7175
|
-
this.globalConfig = vitest.config;
|
|
6935
|
+
this.path = path, this.options = options, this.vitest = vitest, this.ctx = vitest, this.globalConfig = vitest.config;
|
|
7176
6936
|
}
|
|
7177
6937
|
/**
|
|
7178
6938
|
* The unique hash of this project. This value is consistent between the reruns.
|
|
@@ -7201,10 +6961,9 @@ class TestProject {
|
|
|
7201
6961
|
* Get the provided context. The project context is merged with the global context.
|
|
7202
6962
|
*/
|
|
7203
6963
|
getProvidedContext() {
|
|
7204
|
-
if (this.isRootProject()) return this._provided;
|
|
7205
6964
|
// globalSetup can run even if core workspace is not part of the test run
|
|
7206
6965
|
// so we need to inherit its provided context
|
|
7207
|
-
return {
|
|
6966
|
+
return this.isRootProject() ? this._provided : {
|
|
7208
6967
|
...this.vitest.getRootProject().getProvidedContext(),
|
|
7209
6968
|
...this._provided
|
|
7210
6969
|
};
|
|
@@ -7228,13 +6987,11 @@ class TestProject {
|
|
|
7228
6987
|
*/
|
|
7229
6988
|
get vite() {
|
|
7230
6989
|
if (!this._vite) throw new Error("The server was not set. It means that `project.vite` was called before the Vite server was established.");
|
|
7231
|
-
|
|
7232
|
-
Object.defineProperty(this, "vite", {
|
|
6990
|
+
return Object.defineProperty(this, "vite", {
|
|
7233
6991
|
configurable: true,
|
|
7234
6992
|
writable: true,
|
|
7235
6993
|
value: this._vite
|
|
7236
|
-
});
|
|
7237
|
-
return this._vite;
|
|
6994
|
+
}), this._vite;
|
|
7238
6995
|
}
|
|
7239
6996
|
/**
|
|
7240
6997
|
* Resolved project configuration.
|
|
@@ -7291,13 +7048,14 @@ class TestProject {
|
|
|
7291
7048
|
}
|
|
7292
7049
|
/** @internal */
|
|
7293
7050
|
async _initializeGlobalSetup() {
|
|
7294
|
-
if (this._globalSetups)
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7051
|
+
if (!this._globalSetups) {
|
|
7052
|
+
this._globalSetups = await loadGlobalSetupFiles(this.runner, this.config.globalSetup);
|
|
7053
|
+
for (const globalSetupFile of this._globalSetups) {
|
|
7054
|
+
const teardown = await globalSetupFile.setup?.(this);
|
|
7055
|
+
if (teardown == null || !!globalSetupFile.teardown) continue;
|
|
7056
|
+
if (typeof teardown !== "function") throw new TypeError(`invalid return value in globalSetup file ${globalSetupFile.file}. Must return a function`);
|
|
7057
|
+
globalSetupFile.teardown = teardown;
|
|
7058
|
+
}
|
|
7301
7059
|
}
|
|
7302
7060
|
}
|
|
7303
7061
|
onTestsRerun(cb) {
|
|
@@ -7309,8 +7067,7 @@ class TestProject {
|
|
|
7309
7067
|
}
|
|
7310
7068
|
/** @internal */
|
|
7311
7069
|
async _teardownGlobalSetup() {
|
|
7312
|
-
if (
|
|
7313
|
-
for (const globalSetupFile of [...this._globalSetups].reverse()) await globalSetupFile.teardown?.();
|
|
7070
|
+
if (this._globalSetups) for (const globalSetupFile of [...this._globalSetups].reverse()) await globalSetupFile.teardown?.();
|
|
7314
7071
|
}
|
|
7315
7072
|
/** @deprecated use `vitest.logger` instead */
|
|
7316
7073
|
get logger() {
|
|
@@ -7340,12 +7097,8 @@ class TestProject {
|
|
|
7340
7097
|
* @param filters String filters to match the test files.
|
|
7341
7098
|
*/
|
|
7342
7099
|
async globTestFiles(filters = []) {
|
|
7343
|
-
const dir = this.config.dir || this.config.root;
|
|
7344
|
-
|
|
7345
|
-
const typecheck = this.config.typecheck;
|
|
7346
|
-
const [testFiles, typecheckTestFiles] = await Promise.all([typecheck.enabled && typecheck.only ? [] : this.globAllTestFiles(include, exclude, includeSource, dir), typecheck.enabled ? this.typecheckFilesList || this.globFiles(typecheck.include, typecheck.exclude, dir) : []]);
|
|
7347
|
-
this.typecheckFilesList = typecheckTestFiles;
|
|
7348
|
-
return {
|
|
7100
|
+
const dir = this.config.dir || this.config.root, { include, exclude, includeSource } = this.config, typecheck = this.config.typecheck, [testFiles, typecheckTestFiles] = await Promise.all([typecheck.enabled && typecheck.only ? [] : this.globAllTestFiles(include, exclude, includeSource, dir), typecheck.enabled ? this.typecheckFilesList || this.globFiles(typecheck.include, typecheck.exclude, dir) : []]);
|
|
7101
|
+
return this.typecheckFilesList = typecheckTestFiles, {
|
|
7349
7102
|
testFiles: this.filterFiles(testFiles, filters, dir),
|
|
7350
7103
|
typecheckTestFiles: this.filterFiles(typecheckTestFiles, filters, dir)
|
|
7351
7104
|
};
|
|
@@ -7364,8 +7117,7 @@ class TestProject {
|
|
|
7364
7117
|
}
|
|
7365
7118
|
}));
|
|
7366
7119
|
}
|
|
7367
|
-
this.testFilesList = testFiles;
|
|
7368
|
-
return testFiles;
|
|
7120
|
+
return this.testFilesList = testFiles, testFiles;
|
|
7369
7121
|
}
|
|
7370
7122
|
isBrowserEnabled() {
|
|
7371
7123
|
return isBrowserEnabled(this.config);
|
|
@@ -7402,8 +7154,7 @@ class TestProject {
|
|
|
7402
7154
|
cwd,
|
|
7403
7155
|
ignore: exclude,
|
|
7404
7156
|
expandDirectories: false
|
|
7405
|
-
};
|
|
7406
|
-
const files = await glob(include, globOptions);
|
|
7157
|
+
}, files = await glob(include, globOptions);
|
|
7407
7158
|
// keep the slashes consistent with Vite
|
|
7408
7159
|
// we are not using the pathe here because it normalizes the drive letter on Windows
|
|
7409
7160
|
// and we want to keep it the same as working dir
|
|
@@ -7416,16 +7167,10 @@ class TestProject {
|
|
|
7416
7167
|
if (this._isCachedTestFile(moduleId)) return true;
|
|
7417
7168
|
const relativeId = relative(this.config.dir || this.config.root, moduleId);
|
|
7418
7169
|
if (pm.isMatch(relativeId, this.config.exclude)) return false;
|
|
7419
|
-
if (pm.isMatch(relativeId, this.config.include))
|
|
7420
|
-
this.markTestFile(moduleId);
|
|
7421
|
-
return true;
|
|
7422
|
-
}
|
|
7170
|
+
if (pm.isMatch(relativeId, this.config.include)) return this.markTestFile(moduleId), true;
|
|
7423
7171
|
if (this.config.includeSource?.length && pm.isMatch(relativeId, this.config.includeSource)) {
|
|
7424
7172
|
const code = source?.() || readFileSync(moduleId, "utf-8");
|
|
7425
|
-
if (this.isInSourceTestCode(code))
|
|
7426
|
-
this.markTestFile(moduleId);
|
|
7427
|
-
return true;
|
|
7428
|
-
}
|
|
7173
|
+
if (this.isInSourceTestCode(code)) return this.markTestFile(moduleId), true;
|
|
7429
7174
|
}
|
|
7430
7175
|
return false;
|
|
7431
7176
|
}
|
|
@@ -7438,7 +7183,7 @@ class TestProject {
|
|
|
7438
7183
|
}
|
|
7439
7184
|
filterFiles(testFiles, filters, dir) {
|
|
7440
7185
|
if (filters.length && process.platform === "win32") filters = filters.map((f) => slash(f));
|
|
7441
|
-
|
|
7186
|
+
return filters.length ? testFiles.filter((t) => {
|
|
7442
7187
|
const testFile = relative(dir, t).toLocaleLowerCase();
|
|
7443
7188
|
return filters.some((f) => {
|
|
7444
7189
|
// if filter is a full file path, we should include it if it's in the same folder
|
|
@@ -7446,8 +7191,7 @@ class TestProject {
|
|
|
7446
7191
|
const relativePath = f.endsWith("/") ? join(relative(dir, f), "/") : relative(dir, f);
|
|
7447
7192
|
return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase());
|
|
7448
7193
|
});
|
|
7449
|
-
});
|
|
7450
|
-
return testFiles;
|
|
7194
|
+
}) : testFiles;
|
|
7451
7195
|
}
|
|
7452
7196
|
_parentBrowser;
|
|
7453
7197
|
/** @internal */
|
|
@@ -7466,21 +7210,15 @@ class TestProject {
|
|
|
7466
7210
|
}
|
|
7467
7211
|
},
|
|
7468
7212
|
...MocksPlugins({ filter(id) {
|
|
7469
|
-
|
|
7470
|
-
return true;
|
|
7213
|
+
return !(id.includes(distRoot) || id.includes(cacheDir));
|
|
7471
7214
|
} }),
|
|
7472
7215
|
MetaEnvReplacerPlugin()
|
|
7473
7216
|
], [CoverageTransform(this.vitest)]);
|
|
7474
|
-
this._parentBrowser = browser;
|
|
7475
|
-
if (this.config.browser.ui) setup(this.vitest, browser.vite);
|
|
7217
|
+
if (this._parentBrowser = browser, this.config.browser.ui) setup(this.vitest, browser.vite);
|
|
7476
7218
|
});
|
|
7477
7219
|
/** @internal */
|
|
7478
7220
|
_initBrowserServer = deduped(async () => {
|
|
7479
|
-
await this._parent?._initParentBrowser();
|
|
7480
|
-
if (!this.browser && this._parent?._parentBrowser) {
|
|
7481
|
-
this.browser = this._parent._parentBrowser.spawn(this);
|
|
7482
|
-
await this.vitest.report("onBrowserInit", this);
|
|
7483
|
-
}
|
|
7221
|
+
if (await this._parent?._initParentBrowser(), !this.browser && this._parent?._parentBrowser) this.browser = this._parent._parentBrowser.spawn(this), await this.vitest.report("onBrowserInit", this);
|
|
7484
7222
|
});
|
|
7485
7223
|
/**
|
|
7486
7224
|
* Closes the project and all associated resources. This can only be called once; the closing promise is cached until the server restarts.
|
|
@@ -7493,8 +7231,7 @@ class TestProject {
|
|
|
7493
7231
|
this.browser?.close(),
|
|
7494
7232
|
this.clearTmpDir()
|
|
7495
7233
|
].filter(Boolean)).then(() => {
|
|
7496
|
-
this._provided = {};
|
|
7497
|
-
this._vite = void 0;
|
|
7234
|
+
this._provided = {}, this._vite = void 0;
|
|
7498
7235
|
});
|
|
7499
7236
|
return this.closingPromise;
|
|
7500
7237
|
}
|
|
@@ -7518,27 +7255,22 @@ class TestProject {
|
|
|
7518
7255
|
}
|
|
7519
7256
|
/** @internal */
|
|
7520
7257
|
async _configureServer(options, server) {
|
|
7521
|
-
this._config = resolveConfig(this.vitest, {
|
|
7258
|
+
for (const _providedKey in this._config = resolveConfig(this.vitest, {
|
|
7522
7259
|
...options,
|
|
7523
7260
|
coverage: this.vitest.config.coverage
|
|
7524
|
-
}, server.config)
|
|
7525
|
-
this._setHash();
|
|
7526
|
-
for (const _providedKey in this.config.provide) {
|
|
7261
|
+
}, server.config), this._setHash(), this.config.provide) {
|
|
7527
7262
|
const providedKey = _providedKey;
|
|
7528
7263
|
// type is very strict here, so we cast it to any
|
|
7529
7264
|
this.provide(providedKey, this.config.provide[providedKey]);
|
|
7530
7265
|
}
|
|
7531
|
-
this.closingPromise = void 0;
|
|
7532
|
-
this._resolver = new VitestResolver(server.config.cacheDir, this._config);
|
|
7533
|
-
this._vite = server;
|
|
7266
|
+
this.closingPromise = void 0, this._resolver = new VitestResolver(server.config.cacheDir, this._config), this._vite = server;
|
|
7534
7267
|
const environment = server.environments.__vitest__;
|
|
7535
7268
|
this.runner = new ServerModuleRunner(environment, this._resolver, this._config);
|
|
7536
7269
|
}
|
|
7537
7270
|
_serializeOverriddenConfig() {
|
|
7538
7271
|
// TODO: serialize the config _once_ or when needed
|
|
7539
7272
|
const config = serializeConfig(this.config, this.vitest.config, this.vite.config);
|
|
7540
|
-
|
|
7541
|
-
return deepMerge(config, this.vitest.configOverride);
|
|
7273
|
+
return this.vitest.configOverride ? deepMerge(config, this.vitest.configOverride) : config;
|
|
7542
7274
|
}
|
|
7543
7275
|
async clearTmpDir() {
|
|
7544
7276
|
try {
|
|
@@ -7551,9 +7283,10 @@ class TestProject {
|
|
|
7551
7283
|
}
|
|
7552
7284
|
/** @internal */
|
|
7553
7285
|
_initBrowserProvider = deduped(async () => {
|
|
7554
|
-
if (!this.isBrowserEnabled() || this.browser?.provider)
|
|
7555
|
-
|
|
7556
|
-
|
|
7286
|
+
if (!(!this.isBrowserEnabled() || this.browser?.provider)) {
|
|
7287
|
+
if (!this.browser) await this._initBrowserServer();
|
|
7288
|
+
await this.browser?.initBrowserProvider(this);
|
|
7289
|
+
}
|
|
7557
7290
|
});
|
|
7558
7291
|
/** @internal */
|
|
7559
7292
|
_provideObject(context) {
|
|
@@ -7566,40 +7299,25 @@ class TestProject {
|
|
|
7566
7299
|
/** @internal */
|
|
7567
7300
|
static _createBasicProject(vitest) {
|
|
7568
7301
|
const project = new TestProject(vitest.config.name || vitest.config.root, vitest);
|
|
7569
|
-
project.runner = vitest.runner;
|
|
7570
|
-
project._vite = vitest.server;
|
|
7571
|
-
project._config = vitest.config;
|
|
7572
|
-
project._resolver = vitest._resolver;
|
|
7573
|
-
project._setHash();
|
|
7574
|
-
project._provideObject(vitest.config.provide);
|
|
7575
|
-
return project;
|
|
7302
|
+
return project.runner = vitest.runner, project._vite = vitest.server, project._config = vitest.config, project._resolver = vitest._resolver, project._setHash(), project._provideObject(vitest.config.provide), project;
|
|
7576
7303
|
}
|
|
7577
7304
|
/** @internal */
|
|
7578
7305
|
static _cloneBrowserProject(parent, config) {
|
|
7579
7306
|
const clone = new TestProject(parent.path, parent.vitest);
|
|
7580
|
-
clone.runner = parent.runner;
|
|
7581
|
-
clone._vite = parent._vite;
|
|
7582
|
-
clone._resolver = parent._resolver;
|
|
7583
|
-
clone._config = config;
|
|
7584
|
-
clone._setHash();
|
|
7585
|
-
clone._parent = parent;
|
|
7586
|
-
clone._provideObject(config.provide);
|
|
7587
|
-
return clone;
|
|
7307
|
+
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;
|
|
7588
7308
|
}
|
|
7589
7309
|
}
|
|
7590
7310
|
function deduped(cb) {
|
|
7591
7311
|
let _promise;
|
|
7592
|
-
return (...args) => {
|
|
7312
|
+
return ((...args) => {
|
|
7593
7313
|
if (!_promise) _promise = cb(...args).finally(() => {
|
|
7594
7314
|
_promise = void 0;
|
|
7595
7315
|
});
|
|
7596
7316
|
return _promise;
|
|
7597
|
-
};
|
|
7317
|
+
});
|
|
7598
7318
|
}
|
|
7599
7319
|
async function initializeProject(workspacePath, ctx, options) {
|
|
7600
|
-
const project = new TestProject(workspacePath, ctx, options)
|
|
7601
|
-
const { configFile,...restOptions } = options;
|
|
7602
|
-
const config = {
|
|
7320
|
+
const project = new TestProject(workspacePath, ctx, options), { configFile,...restOptions } = options, config = {
|
|
7603
7321
|
...restOptions,
|
|
7604
7322
|
configFile,
|
|
7605
7323
|
configLoader: ctx.vite.config.inlineConfig.configLoader,
|
|
@@ -7609,25 +7327,20 @@ async function initializeProject(workspacePath, ctx, options) {
|
|
|
7609
7327
|
workspacePath
|
|
7610
7328
|
})]
|
|
7611
7329
|
};
|
|
7612
|
-
await createViteServer(config);
|
|
7613
|
-
return project;
|
|
7330
|
+
return await createViteServer(config), project;
|
|
7614
7331
|
}
|
|
7615
7332
|
function generateHash(str) {
|
|
7616
7333
|
let hash = 0;
|
|
7617
7334
|
if (str.length === 0) return `${hash}`;
|
|
7618
7335
|
for (let i = 0; i < str.length; i++) {
|
|
7619
7336
|
const char = str.charCodeAt(i);
|
|
7620
|
-
hash = (hash << 5) - hash + char;
|
|
7621
|
-
hash = hash & hash;
|
|
7337
|
+
hash = (hash << 5) - hash + char, hash = hash & hash;
|
|
7622
7338
|
}
|
|
7623
7339
|
return `${hash}`;
|
|
7624
7340
|
}
|
|
7625
7341
|
|
|
7626
7342
|
async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projectsDefinition, names) {
|
|
7627
|
-
const { configFiles, projectConfigs, nonConfigDirectories } = await resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDefinition)
|
|
7628
|
-
// cli options that affect the project config,
|
|
7629
|
-
// not all options are allowed to be overridden
|
|
7630
|
-
const overridesOptions = [
|
|
7343
|
+
const { configFiles, projectConfigs, nonConfigDirectories } = await resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDefinition), overridesOptions = [
|
|
7631
7344
|
"logHeapUsage",
|
|
7632
7345
|
"allowOnly",
|
|
7633
7346
|
"sequence",
|
|
@@ -7646,21 +7359,12 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7646
7359
|
"inspect",
|
|
7647
7360
|
"inspectBrk",
|
|
7648
7361
|
"fileParallelism"
|
|
7649
|
-
]
|
|
7650
|
-
const cliOverrides = overridesOptions.reduce((acc, name) => {
|
|
7362
|
+
], cliOverrides = overridesOptions.reduce((acc, name) => {
|
|
7651
7363
|
if (name in cliOptions) acc[name] = cliOptions[name];
|
|
7652
7364
|
return acc;
|
|
7653
|
-
}, {});
|
|
7654
|
-
const projectPromises = [];
|
|
7655
|
-
const fileProjects = [...configFiles, ...nonConfigDirectories];
|
|
7656
|
-
const concurrent = limitConcurrency(nodeos__default.availableParallelism?.() || nodeos__default.cpus().length || 5);
|
|
7365
|
+
}, {}), projectPromises = [], fileProjects = [...configFiles, ...nonConfigDirectories], concurrent = limitConcurrency(nodeos__default.availableParallelism?.() || nodeos__default.cpus().length || 5);
|
|
7657
7366
|
projectConfigs.forEach((options, index) => {
|
|
7658
|
-
const configRoot = vitest.config.root;
|
|
7659
|
-
// if extends a config file, resolve the file path
|
|
7660
|
-
const configFile = typeof options.extends === "string" ? resolve(configRoot, options.extends) : options.extends === true ? vitest.vite.config.configFile || false : false;
|
|
7661
|
-
// if `root` is configured, resolve it relative to the workspace file or vite root (like other options)
|
|
7662
|
-
// if `root` is not specified, inline configs use the same root as the root project
|
|
7663
|
-
const root = options.root ? resolve(configRoot, options.root) : vitest.config.root;
|
|
7367
|
+
const configRoot = vitest.config.root, configFile = typeof options.extends === "string" ? resolve(configRoot, options.extends) : options.extends === true ? vitest.vite.config.configFile || false : false, root = options.root ? resolve(configRoot, options.root) : vitest.config.root;
|
|
7664
7368
|
projectPromises.push(concurrent(() => initializeProject(index, vitest, {
|
|
7665
7369
|
...options,
|
|
7666
7370
|
root,
|
|
@@ -7678,8 +7382,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7678
7382
|
if (project) projectPromises.push(Promise.resolve(project));
|
|
7679
7383
|
continue;
|
|
7680
7384
|
}
|
|
7681
|
-
const configFile = path.endsWith("/") ? false : path;
|
|
7682
|
-
const root = path.endsWith("/") ? path : dirname(path);
|
|
7385
|
+
const configFile = path.endsWith("/") ? false : path, root = path.endsWith("/") ? path : dirname(path);
|
|
7683
7386
|
projectPromises.push(concurrent(() => initializeProject(path, vitest, {
|
|
7684
7387
|
root,
|
|
7685
7388
|
configFile,
|
|
@@ -7692,9 +7395,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7692
7395
|
vitest.config.project.length ? `The filter matched no projects: ${vitest.config.project.join(", ")}. ` : "",
|
|
7693
7396
|
`The projects definition: ${JSON.stringify(projectsDefinition, null, 4)}.`
|
|
7694
7397
|
].join(""));
|
|
7695
|
-
const resolvedProjectsPromises = await Promise.allSettled(projectPromises);
|
|
7696
|
-
const errors = [];
|
|
7697
|
-
const resolvedProjects = [];
|
|
7398
|
+
const resolvedProjectsPromises = await Promise.allSettled(projectPromises), errors = [], resolvedProjects = [];
|
|
7698
7399
|
for (const result of resolvedProjectsPromises) if (result.status === "rejected") {
|
|
7699
7400
|
if (result.reason instanceof VitestFilteredOutProjectError)
|
|
7700
7401
|
// filter out filtered out projects
|
|
@@ -7706,8 +7407,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7706
7407
|
for (const project of resolvedProjects) {
|
|
7707
7408
|
const name = project.name;
|
|
7708
7409
|
if (names.has(name)) {
|
|
7709
|
-
const duplicate = resolvedProjects.find((p) => p.name === name && p !== project)
|
|
7710
|
-
const filesError = fileProjects.length ? [
|
|
7410
|
+
const duplicate = resolvedProjects.find((p) => p.name === name && p !== project), filesError = fileProjects.length ? [
|
|
7711
7411
|
"\n\nYour config matched these files:\n",
|
|
7712
7412
|
fileProjects.map((p) => ` - ${relative(vitest.config.root, p)}`).join("\n"),
|
|
7713
7413
|
"\n\n"
|
|
@@ -7729,24 +7429,18 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7729
7429
|
const removeProjects = /* @__PURE__ */ new Set();
|
|
7730
7430
|
resolvedProjects.forEach((project) => {
|
|
7731
7431
|
if (!project.config.browser.enabled) return;
|
|
7732
|
-
const instances = project.config.browser.instances || [];
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
}
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
"Read more: https://vitest.dev/guide/browser/config#browser-instances"
|
|
7745
|
-
].filter(Boolean).join("")));
|
|
7746
|
-
}
|
|
7747
|
-
const originalName = project.config.name;
|
|
7748
|
-
// if original name is in the --project=name filter, keep all instances
|
|
7749
|
-
const filteredInstances = vitest.matchesProjectFilter(originalName) ? instances : instances.filter((instance) => {
|
|
7432
|
+
const instances = project.config.browser.instances || [], browser = project.config.browser.name;
|
|
7433
|
+
if (instances.length === 0 && browser) instances.push({
|
|
7434
|
+
browser,
|
|
7435
|
+
name: project.name ? `${project.name} (${browser})` : browser
|
|
7436
|
+
}), vitest.logger.warn(withLabel("yellow", "Vitest", [
|
|
7437
|
+
`No browser "instances" were defined`,
|
|
7438
|
+
project.name ? ` for the "${project.name}" project. ` : ". ",
|
|
7439
|
+
`Running tests in "${project.config.browser.name}" browser. `,
|
|
7440
|
+
"The \"browser.name\" field is deprecated since Vitest 3. ",
|
|
7441
|
+
"Read more: https://vitest.dev/guide/browser/config#browser-instances"
|
|
7442
|
+
].filter(Boolean).join("")));
|
|
7443
|
+
const originalName = project.config.name, filteredInstances = vitest.matchesProjectFilter(originalName) ? instances : instances.filter((instance) => {
|
|
7750
7444
|
const newName = instance.name;
|
|
7751
7445
|
return vitest.matchesProjectFilter(newName);
|
|
7752
7446
|
});
|
|
@@ -7759,8 +7453,7 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7759
7453
|
filteredInstances.forEach((config, index) => {
|
|
7760
7454
|
const browser = config.browser;
|
|
7761
7455
|
if (!browser) {
|
|
7762
|
-
const nth = index + 1;
|
|
7763
|
-
const ending = nth === 2 ? "nd" : nth === 3 ? "rd" : "th";
|
|
7456
|
+
const nth = index + 1, ending = nth === 2 ? "nd" : nth === 3 ? "rd" : "th";
|
|
7764
7457
|
throw new Error(`The browser configuration must have a "browser" property. The ${nth}${ending} item in "browser.instances" doesn't have it. Make sure your${originalName ? ` "${originalName}"` : ""} configuration is correct.`);
|
|
7765
7458
|
}
|
|
7766
7459
|
const name = config.name;
|
|
@@ -7775,18 +7468,15 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7775
7468
|
clonedConfig.name = name;
|
|
7776
7469
|
const clone = TestProject._cloneBrowserProject(project, clonedConfig);
|
|
7777
7470
|
resolvedProjects.push(clone);
|
|
7778
|
-
});
|
|
7779
|
-
|
|
7780
|
-
});
|
|
7781
|
-
resolvedProjects = resolvedProjects.filter((project) => !removeProjects.has(project));
|
|
7471
|
+
}), removeProjects.add(project);
|
|
7472
|
+
}), resolvedProjects = resolvedProjects.filter((project) => !removeProjects.has(project));
|
|
7782
7473
|
const headedBrowserProjects = resolvedProjects.filter((project) => {
|
|
7783
7474
|
return project.config.browser.enabled && !project.config.browser.headless;
|
|
7784
7475
|
});
|
|
7785
7476
|
if (headedBrowserProjects.length > 1) {
|
|
7786
7477
|
const message = [`Found multiple projects that run browser tests in headed mode: "${headedBrowserProjects.map((p) => p.name).join("\", \"")}".`, ` Vitest cannot run multiple headed browsers at the same time.`].join("");
|
|
7787
7478
|
if (!isTTY) throw new Error(`${message} Please, filter projects with --browser=name or --project=name flag or run tests with "headless: true" option.`);
|
|
7788
|
-
const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; })
|
|
7789
|
-
const { projectName } = await prompts.default({
|
|
7479
|
+
const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; }), { projectName } = await prompts.default({
|
|
7790
7480
|
type: "select",
|
|
7791
7481
|
name: "projectName",
|
|
7792
7482
|
choices: headedBrowserProjects.map((project) => ({
|
|
@@ -7801,10 +7491,9 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7801
7491
|
return resolvedProjects;
|
|
7802
7492
|
}
|
|
7803
7493
|
function cloneConfig(project, { browser,...config }) {
|
|
7804
|
-
const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, browser: _browser, name,...overrideConfig } = config;
|
|
7805
|
-
const currentConfig = project.config.browser;
|
|
7494
|
+
const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, browser: _browser, name,...overrideConfig } = config, currentConfig = project.config.browser, clonedConfig = deepClone(project.config);
|
|
7806
7495
|
return mergeConfig({
|
|
7807
|
-
...
|
|
7496
|
+
...clonedConfig,
|
|
7808
7497
|
browser: {
|
|
7809
7498
|
...project.config.browser,
|
|
7810
7499
|
locators: locators ? { testIdAttribute: locators.testIdAttribute ?? currentConfig.locators.testIdAttribute } : project.config.browser.locators,
|
|
@@ -7816,18 +7505,15 @@ function cloneConfig(project, { browser,...config }) {
|
|
|
7816
7505
|
name: browser,
|
|
7817
7506
|
providerOptions: config,
|
|
7818
7507
|
instances: void 0
|
|
7819
|
-
}
|
|
7508
|
+
},
|
|
7509
|
+
include: overrideConfig.include && overrideConfig.include.length > 0 ? [] : clonedConfig.include,
|
|
7510
|
+
exclude: overrideConfig.exclude && overrideConfig.exclude.length > 0 ? [] : clonedConfig.exclude,
|
|
7511
|
+
includeSource: overrideConfig.includeSource && overrideConfig.includeSource.length > 0 ? [] : clonedConfig.includeSource
|
|
7820
7512
|
}, overrideConfig);
|
|
7821
7513
|
}
|
|
7822
7514
|
async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDefinition) {
|
|
7823
7515
|
// project configurations that were specified directly
|
|
7824
|
-
const projectsOptions = [];
|
|
7825
|
-
// custom config files that were specified directly or resolved from a directory
|
|
7826
|
-
const projectsConfigFiles = [];
|
|
7827
|
-
// custom glob matches that should be resolved as directories or config files
|
|
7828
|
-
const projectsGlobMatches = [];
|
|
7829
|
-
// directories that don't have a config file inside, but should be treated as projects
|
|
7830
|
-
const nonConfigProjectDirectories = [];
|
|
7516
|
+
const projectsOptions = [], projectsConfigFiles = [], projectsGlobMatches = [], nonConfigProjectDirectories = [];
|
|
7831
7517
|
for (const definition of projectsDefinition) if (typeof definition === "string") {
|
|
7832
7518
|
const stringOption = definition.replace("<rootDir>", vitest.config.root);
|
|
7833
7519
|
// if the string doesn't contain a glob, we can resolve it directly
|
|
@@ -7871,8 +7557,7 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDe
|
|
|
7871
7557
|
"**/*.timestamp-*",
|
|
7872
7558
|
"**/.DS_Store"
|
|
7873
7559
|
]
|
|
7874
|
-
};
|
|
7875
|
-
const projectsFs = await glob(projectsGlobMatches, globOptions);
|
|
7560
|
+
}, projectsFs = await glob(projectsGlobMatches, globOptions);
|
|
7876
7561
|
await Promise.all(projectsFs.map(async (path) => {
|
|
7877
7562
|
// directories are allowed with a glob like `packages/*`
|
|
7878
7563
|
// in this case every directory is treated as a project
|
|
@@ -7891,21 +7576,15 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDe
|
|
|
7891
7576
|
};
|
|
7892
7577
|
}
|
|
7893
7578
|
async function resolveDirectoryConfig(directory) {
|
|
7894
|
-
const files = new Set(await promises.readdir(directory));
|
|
7895
|
-
|
|
7896
|
-
// this simulates how `findUp` works in packages/vitest/src/node/create.ts:29
|
|
7897
|
-
const configFile = configFiles.find((file) => files.has(file));
|
|
7898
|
-
if (configFile) return resolve(directory, configFile);
|
|
7899
|
-
return null;
|
|
7579
|
+
const files = new Set(await promises.readdir(directory)), configFile = configFiles.find((file) => files.has(file));
|
|
7580
|
+
return configFile ? resolve(directory, configFile) : null;
|
|
7900
7581
|
}
|
|
7901
7582
|
function getDefaultTestProject(vitest) {
|
|
7902
|
-
const filter = vitest.config.project;
|
|
7903
|
-
const project = vitest._ensureRootProject();
|
|
7583
|
+
const filter = vitest.config.project, project = vitest._ensureRootProject();
|
|
7904
7584
|
if (!filter.length) return project;
|
|
7905
7585
|
// check for the project name and browser names
|
|
7906
7586
|
const hasProjects = getPotentialProjectNames(project).some((p) => vitest.matchesProjectFilter(p));
|
|
7907
|
-
|
|
7908
|
-
return null;
|
|
7587
|
+
return hasProjects ? project : null;
|
|
7909
7588
|
}
|
|
7910
7589
|
function getPotentialProjectNames(project) {
|
|
7911
7590
|
const names = [project.name];
|
|
@@ -7925,8 +7604,7 @@ async function loadCustomReporterModule(path, runner) {
|
|
|
7925
7604
|
return customReporterModule.default;
|
|
7926
7605
|
}
|
|
7927
7606
|
function createReporters(reporterReferences, ctx) {
|
|
7928
|
-
const runner = ctx.runner
|
|
7929
|
-
const promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
|
|
7607
|
+
const runner = ctx.runner, promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
|
|
7930
7608
|
if (Array.isArray(referenceOrInstance)) {
|
|
7931
7609
|
const [reporterName, reporterOptions] = referenceOrInstance;
|
|
7932
7610
|
if (reporterName === "html") {
|
|
@@ -7967,14 +7645,12 @@ function parseFilter(filter) {
|
|
|
7967
7645
|
filename: parsedFilename,
|
|
7968
7646
|
lineNumber: Number.parseInt(lineNumber)
|
|
7969
7647
|
};
|
|
7970
|
-
|
|
7971
|
-
|
|
7648
|
+
if (lineNumber.match(/^\d+-\d+$/)) throw new RangeLocationFilterProvidedError(filter);
|
|
7649
|
+
return { filename: filter };
|
|
7972
7650
|
}
|
|
7973
7651
|
function groupFilters(filters) {
|
|
7974
|
-
const groupedFilters_ = groupBy(filters, (f) => f.filename)
|
|
7975
|
-
|
|
7976
|
-
const [filename, filters] = entry;
|
|
7977
|
-
const testLocations = filters.map((f) => f.lineNumber);
|
|
7652
|
+
const groupedFilters_ = groupBy(filters, (f) => f.filename), groupedFilters = Object.fromEntries(Object.entries(groupedFilters_).map((entry) => {
|
|
7653
|
+
const [filename, filters] = entry, testLocations = filters.map((f) => f.lineNumber);
|
|
7978
7654
|
return [filename, testLocations.filter((l) => l !== void 0)];
|
|
7979
7655
|
}));
|
|
7980
7656
|
return groupedFilters;
|
|
@@ -7993,45 +7669,35 @@ class VitestSpecifications {
|
|
|
7993
7669
|
if (project._isCachedTestFile(moduleId)) specs.push(project.createSpecification(moduleId));
|
|
7994
7670
|
if (project._isCachedTypecheckFile(moduleId)) specs.push(project.createSpecification(moduleId, [], "typescript"));
|
|
7995
7671
|
}
|
|
7996
|
-
specs.forEach((spec) => this.ensureSpecificationCached(spec));
|
|
7997
|
-
return specs;
|
|
7672
|
+
return specs.forEach((spec) => this.ensureSpecificationCached(spec)), specs;
|
|
7998
7673
|
}
|
|
7999
7674
|
async getRelevantTestSpecifications(filters = []) {
|
|
8000
7675
|
return this.filterTestsBySource(await this.globTestSpecifications(filters));
|
|
8001
7676
|
}
|
|
8002
7677
|
async globTestSpecifications(filters = []) {
|
|
8003
|
-
const files = [];
|
|
8004
|
-
const dir = process.cwd();
|
|
8005
|
-
const parsedFilters = filters.map((f) => parseFilter(f));
|
|
7678
|
+
const files = [], dir = process.cwd(), parsedFilters = filters.map((f) => parseFilter(f));
|
|
8006
7679
|
// Require includeTaskLocation when a location filter is passed
|
|
8007
7680
|
if (!this.vitest.config.includeTaskLocation && parsedFilters.some((f) => f.lineNumber !== void 0)) throw new IncludeTaskLocationDisabledError();
|
|
8008
7681
|
const testLines = groupFilters(parsedFilters.map((f) => ({
|
|
8009
7682
|
...f,
|
|
8010
7683
|
filename: resolve(dir, f.filename)
|
|
8011
|
-
})));
|
|
8012
|
-
|
|
8013
|
-
const testLocHasMatch = {};
|
|
8014
|
-
await Promise.all(this.vitest.projects.map(async (project) => {
|
|
7684
|
+
}))), testLocHasMatch = {};
|
|
7685
|
+
return await Promise.all(this.vitest.projects.map(async (project) => {
|
|
8015
7686
|
const { testFiles, typecheckTestFiles } = await project.globTestFiles(parsedFilters.map((f) => f.filename));
|
|
8016
7687
|
testFiles.forEach((file) => {
|
|
8017
7688
|
const lines = testLines[file];
|
|
8018
7689
|
testLocHasMatch[file] = true;
|
|
8019
7690
|
const spec = project.createSpecification(file, lines);
|
|
8020
|
-
this.ensureSpecificationCached(spec);
|
|
8021
|
-
|
|
8022
|
-
});
|
|
8023
|
-
typecheckTestFiles.forEach((file) => {
|
|
7691
|
+
this.ensureSpecificationCached(spec), files.push(spec);
|
|
7692
|
+
}), typecheckTestFiles.forEach((file) => {
|
|
8024
7693
|
const lines = testLines[file];
|
|
8025
7694
|
testLocHasMatch[file] = true;
|
|
8026
7695
|
const spec = project.createSpecification(file, lines, "typescript");
|
|
8027
|
-
this.ensureSpecificationCached(spec);
|
|
8028
|
-
files.push(spec);
|
|
7696
|
+
this.ensureSpecificationCached(spec), files.push(spec);
|
|
8029
7697
|
});
|
|
8030
|
-
}))
|
|
8031
|
-
Object.entries(testLines).forEach(([filepath, loc]) => {
|
|
7698
|
+
})), Object.entries(testLines).forEach(([filepath, loc]) => {
|
|
8032
7699
|
if (loc.length !== 0 && !testLocHasMatch[filepath]) throw new LocationFilterFileNotFoundError(relative(dir, filepath));
|
|
8033
|
-
});
|
|
8034
|
-
return files;
|
|
7700
|
+
}), files;
|
|
8035
7701
|
}
|
|
8036
7702
|
clearCache(moduleId) {
|
|
8037
7703
|
if (moduleId) this._cachedSpecs.delete(moduleId);
|
|
@@ -8041,30 +7707,20 @@ class VitestSpecifications {
|
|
|
8041
7707
|
return this._cachedSpecs.get(moduleId);
|
|
8042
7708
|
}
|
|
8043
7709
|
ensureSpecificationCached(spec) {
|
|
8044
|
-
const file = spec.moduleId;
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
if (index === -1) {
|
|
8048
|
-
specs.push(spec);
|
|
8049
|
-
this._cachedSpecs.set(file, specs);
|
|
8050
|
-
} else specs.splice(index, 1, spec);
|
|
7710
|
+
const file = spec.moduleId, specs = this._cachedSpecs.get(file) || [], index = specs.findIndex((_s) => _s.project === spec.project && _s.pool === spec.pool);
|
|
7711
|
+
if (index === -1) specs.push(spec), this._cachedSpecs.set(file, specs);
|
|
7712
|
+
else specs.splice(index, 1, spec);
|
|
8051
7713
|
return specs;
|
|
8052
7714
|
}
|
|
8053
7715
|
async filterTestsBySource(specs) {
|
|
8054
7716
|
if (this.vitest.config.changed && !this.vitest.config.related) {
|
|
8055
|
-
const { VitestGit } = await import('./git.
|
|
8056
|
-
|
|
8057
|
-
const related = await vitestGit.findChangedFiles({ changedSince: this.vitest.config.changed });
|
|
8058
|
-
if (!related) {
|
|
8059
|
-
process.exitCode = 1;
|
|
8060
|
-
throw new GitNotFoundError();
|
|
8061
|
-
}
|
|
7717
|
+
const { VitestGit } = await import('./git.BFNcloKD.js'), vitestGit = new VitestGit(this.vitest.config.root), related = await vitestGit.findChangedFiles({ changedSince: this.vitest.config.changed });
|
|
7718
|
+
if (!related) throw process.exitCode = 1, new GitNotFoundError();
|
|
8062
7719
|
this.vitest.config.related = Array.from(new Set(related));
|
|
8063
7720
|
}
|
|
8064
7721
|
const related = this.vitest.config.related;
|
|
8065
7722
|
if (!related) return specs;
|
|
8066
|
-
const forceRerunTriggers = this.vitest.config.forceRerunTriggers;
|
|
8067
|
-
const matcher = forceRerunTriggers.length ? pm(forceRerunTriggers) : void 0;
|
|
7723
|
+
const forceRerunTriggers = this.vitest.config.forceRerunTriggers, matcher = forceRerunTriggers.length ? pm(forceRerunTriggers) : void 0;
|
|
8068
7724
|
if (matcher && related.some((file) => matcher(file))) return specs;
|
|
8069
7725
|
// don't run anything if no related sources are found
|
|
8070
7726
|
// if we are in watch mode, we want to process all tests
|
|
@@ -8072,8 +7728,7 @@ class VitestSpecifications {
|
|
|
8072
7728
|
const testGraphs = await Promise.all(specs.map(async (spec) => {
|
|
8073
7729
|
const deps = await this.getTestDependencies(spec);
|
|
8074
7730
|
return [spec, deps];
|
|
8075
|
-
}));
|
|
8076
|
-
const runningTests = [];
|
|
7731
|
+
})), runningTests = [];
|
|
8077
7732
|
for (const [specification, deps] of testGraphs)
|
|
8078
7733
|
// if deps or the test itself were changed
|
|
8079
7734
|
if (related.some((path) => path === specification.moduleId || deps.has(path))) runningTests.push(specification);
|
|
@@ -8083,8 +7738,7 @@ class VitestSpecifications {
|
|
|
8083
7738
|
const addImports = async (project, filepath) => {
|
|
8084
7739
|
if (deps.has(filepath)) return;
|
|
8085
7740
|
deps.add(filepath);
|
|
8086
|
-
const mod = project.vite.environments.ssr.moduleGraph.getModuleById(filepath);
|
|
8087
|
-
const transformed = mod?.transformResult || await project.vite.environments.ssr.transformRequest(filepath);
|
|
7741
|
+
const mod = project.vite.environments.ssr.moduleGraph.getModuleById(filepath), transformed = mod?.transformResult || await project.vite.environments.ssr.transformRequest(filepath);
|
|
8088
7742
|
if (!transformed) return;
|
|
8089
7743
|
const dependencies = [...transformed.deps || [], ...transformed.dynamicDeps || []];
|
|
8090
7744
|
await Promise.all(dependencies.map(async (dep) => {
|
|
@@ -8092,9 +7746,7 @@ class VitestSpecifications {
|
|
|
8092
7746
|
if (!fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath)) await addImports(project, fsPath);
|
|
8093
7747
|
}));
|
|
8094
7748
|
};
|
|
8095
|
-
await addImports(spec.project, spec.moduleId);
|
|
8096
|
-
deps.delete(spec.moduleId);
|
|
8097
|
-
return deps;
|
|
7749
|
+
return await addImports(spec.project, spec.moduleId), deps.delete(spec.moduleId), deps;
|
|
8098
7750
|
}
|
|
8099
7751
|
}
|
|
8100
7752
|
|
|
@@ -8120,10 +7772,7 @@ class ReportedTaskImplementation {
|
|
|
8120
7772
|
location;
|
|
8121
7773
|
/** @internal */
|
|
8122
7774
|
constructor(task, project) {
|
|
8123
|
-
this.task = task;
|
|
8124
|
-
this.project = project;
|
|
8125
|
-
this.id = task.id;
|
|
8126
|
-
this.location = task.location;
|
|
7775
|
+
this.task = task, this.project = project, this.id = task.id, this.location = task.location;
|
|
8127
7776
|
}
|
|
8128
7777
|
/**
|
|
8129
7778
|
* Checks if the test did not fail the suite.
|
|
@@ -8145,8 +7794,7 @@ class ReportedTaskImplementation {
|
|
|
8145
7794
|
*/
|
|
8146
7795
|
static register(task, project) {
|
|
8147
7796
|
const state = new this(task, project);
|
|
8148
|
-
storeTask(project, task, state);
|
|
8149
|
-
return state;
|
|
7797
|
+
return storeTask(project, task, state), state;
|
|
8150
7798
|
}
|
|
8151
7799
|
}
|
|
8152
7800
|
class TestCase extends ReportedTaskImplementation {
|
|
@@ -8170,9 +7818,7 @@ class TestCase extends ReportedTaskImplementation {
|
|
|
8170
7818
|
parent;
|
|
8171
7819
|
/** @internal */
|
|
8172
7820
|
constructor(task, project) {
|
|
8173
|
-
super(task, project);
|
|
8174
|
-
this.name = task.name;
|
|
8175
|
-
this.module = getReportedTask(project, task.file);
|
|
7821
|
+
super(task, project), this.name = task.name, this.module = getReportedTask(project, task.file);
|
|
8176
7822
|
const suite = this.task.suite;
|
|
8177
7823
|
if (suite) this.parent = getReportedTask(project, suite);
|
|
8178
7824
|
else this.parent = this.module;
|
|
@@ -8194,8 +7840,7 @@ class TestCase extends ReportedTaskImplementation {
|
|
|
8194
7840
|
* - **skipped**: Test was skipped during collection or dynamically with `ctx.skip()`.
|
|
8195
7841
|
*/
|
|
8196
7842
|
result() {
|
|
8197
|
-
const result = this.task.result;
|
|
8198
|
-
const mode = result?.state || this.task.mode;
|
|
7843
|
+
const result = this.task.result, mode = result?.state || this.task.mode;
|
|
8199
7844
|
if (!result && (mode === "skip" || mode === "todo")) return {
|
|
8200
7845
|
state: "skipped",
|
|
8201
7846
|
note: void 0,
|
|
@@ -8206,16 +7851,14 @@ class TestCase extends ReportedTaskImplementation {
|
|
|
8206
7851
|
errors: void 0
|
|
8207
7852
|
};
|
|
8208
7853
|
const state = result.state === "fail" ? "failed" : result.state === "pass" ? "passed" : "skipped";
|
|
8209
|
-
|
|
7854
|
+
return state === "skipped" ? {
|
|
8210
7855
|
state,
|
|
8211
7856
|
note: result.note,
|
|
8212
7857
|
errors: void 0
|
|
8213
|
-
}
|
|
8214
|
-
if (state === "passed") return {
|
|
7858
|
+
} : state === "passed" ? {
|
|
8215
7859
|
state,
|
|
8216
7860
|
errors: result.errors
|
|
8217
|
-
}
|
|
8218
|
-
return {
|
|
7861
|
+
} : {
|
|
8219
7862
|
state,
|
|
8220
7863
|
errors: result.errors || []
|
|
8221
7864
|
};
|
|
@@ -8234,8 +7877,7 @@ class TestCase extends ReportedTaskImplementation {
|
|
|
8234
7877
|
const result = this.task.result;
|
|
8235
7878
|
// startTime should always be available if the test has properly finished
|
|
8236
7879
|
if (!result || !result.startTime) return void 0;
|
|
8237
|
-
const duration = result.duration || 0;
|
|
8238
|
-
const slow = duration > this.project.globalConfig.slowTestThreshold;
|
|
7880
|
+
const duration = result.duration || 0, slow = duration > this.project.globalConfig.slowTestThreshold;
|
|
8239
7881
|
return {
|
|
8240
7882
|
slow,
|
|
8241
7883
|
heap: result.heap,
|
|
@@ -8251,8 +7893,7 @@ class TestCollection {
|
|
|
8251
7893
|
#task;
|
|
8252
7894
|
#project;
|
|
8253
7895
|
constructor(task, project) {
|
|
8254
|
-
this.#task = task;
|
|
8255
|
-
this.#project = project;
|
|
7896
|
+
this.#task = task, this.#project = project;
|
|
8256
7897
|
}
|
|
8257
7898
|
/**
|
|
8258
7899
|
* Returns the test or suite at a specific index.
|
|
@@ -8305,10 +7946,7 @@ class TestCollection {
|
|
|
8305
7946
|
* Filters all suites that are part of this collection and its children.
|
|
8306
7947
|
*/
|
|
8307
7948
|
*allSuites() {
|
|
8308
|
-
for (const child of this) if (child.type === "suite")
|
|
8309
|
-
yield child;
|
|
8310
|
-
yield* child.children.allSuites();
|
|
8311
|
-
}
|
|
7949
|
+
for (const child of this) if (child.type === "suite") yield child, yield* child.children.allSuites();
|
|
8312
7950
|
}
|
|
8313
7951
|
*[Symbol.iterator]() {
|
|
8314
7952
|
for (const task of this.#task.tasks) yield getReportedTask(this.#project, task);
|
|
@@ -8321,8 +7959,7 @@ class SuiteImplementation extends ReportedTaskImplementation {
|
|
|
8321
7959
|
children;
|
|
8322
7960
|
/** @internal */
|
|
8323
7961
|
constructor(task, project) {
|
|
8324
|
-
super(task, project);
|
|
8325
|
-
this.children = new TestCollection(task, project);
|
|
7962
|
+
super(task, project), this.children = new TestCollection(task, project);
|
|
8326
7963
|
}
|
|
8327
7964
|
/**
|
|
8328
7965
|
* Errors that happened outside of the test run during collection, like syntax errors.
|
|
@@ -8352,9 +7989,7 @@ class TestSuite extends SuiteImplementation {
|
|
|
8352
7989
|
options;
|
|
8353
7990
|
/** @internal */
|
|
8354
7991
|
constructor(task, project) {
|
|
8355
|
-
super(task, project);
|
|
8356
|
-
this.name = task.name;
|
|
8357
|
-
this.module = getReportedTask(project, task.file);
|
|
7992
|
+
super(task, project), this.name = task.name, this.module = getReportedTask(project, task.file);
|
|
8358
7993
|
const suite = this.task.suite;
|
|
8359
7994
|
if (suite) this.parent = getReportedTask(project, suite);
|
|
8360
7995
|
else this.parent = this.module;
|
|
@@ -8385,29 +8020,21 @@ class TestModule extends SuiteImplementation {
|
|
|
8385
8020
|
moduleId;
|
|
8386
8021
|
/** @internal */
|
|
8387
8022
|
constructor(task, project) {
|
|
8388
|
-
super(task, project);
|
|
8389
|
-
this.moduleId = task.filepath;
|
|
8023
|
+
super(task, project), this.moduleId = task.filepath;
|
|
8390
8024
|
}
|
|
8391
8025
|
/**
|
|
8392
8026
|
* Checks the running state of the test file.
|
|
8393
8027
|
*/
|
|
8394
8028
|
state() {
|
|
8395
8029
|
const state = this.task.result?.state;
|
|
8396
|
-
|
|
8397
|
-
return getSuiteState(this.task);
|
|
8030
|
+
return state === "queued" ? "queued" : getSuiteState(this.task);
|
|
8398
8031
|
}
|
|
8399
8032
|
/**
|
|
8400
8033
|
* Useful information about the module like duration, memory usage, etc.
|
|
8401
8034
|
* If the module was not executed yet, all diagnostic values will return `0`.
|
|
8402
8035
|
*/
|
|
8403
8036
|
diagnostic() {
|
|
8404
|
-
const setupDuration = this.task.setupDuration || 0;
|
|
8405
|
-
const collectDuration = this.task.collectDuration || 0;
|
|
8406
|
-
const prepareDuration = this.task.prepareDuration || 0;
|
|
8407
|
-
const environmentSetupDuration = this.task.environmentLoad || 0;
|
|
8408
|
-
const duration = this.task.result?.duration || 0;
|
|
8409
|
-
const heap = this.task.result?.heap;
|
|
8410
|
-
const importDurations = this.task.importDurations ?? {};
|
|
8037
|
+
const setupDuration = this.task.setupDuration || 0, collectDuration = this.task.collectDuration || 0, prepareDuration = this.task.prepareDuration || 0, environmentSetupDuration = this.task.environmentLoad || 0, duration = this.task.result?.duration || 0, heap = this.task.result?.heap, importDurations = this.task.importDurations ?? {};
|
|
8411
8038
|
return {
|
|
8412
8039
|
environmentSetupDuration,
|
|
8413
8040
|
prepareDuration,
|
|
@@ -8439,8 +8066,7 @@ function getReportedTask(project, runnerTask) {
|
|
|
8439
8066
|
return reportedTask;
|
|
8440
8067
|
}
|
|
8441
8068
|
function getSuiteState(task) {
|
|
8442
|
-
const mode = task.mode;
|
|
8443
|
-
const state = task.result?.state;
|
|
8069
|
+
const mode = task.mode, state = task.result?.state;
|
|
8444
8070
|
if (mode === "skip" || mode === "todo" || state === "skip" || state === "todo") return "skipped";
|
|
8445
8071
|
if (state == null || state === "run" || state === "only") return "pending";
|
|
8446
8072
|
if (state === "fail") return "failed";
|
|
@@ -8449,8 +8075,7 @@ function getSuiteState(task) {
|
|
|
8449
8075
|
}
|
|
8450
8076
|
|
|
8451
8077
|
function isAggregateError(err) {
|
|
8452
|
-
|
|
8453
|
-
return err instanceof Error && "errors" in err;
|
|
8078
|
+
return typeof AggregateError !== "undefined" && err instanceof AggregateError ? true : err instanceof Error && "errors" in err;
|
|
8454
8079
|
}
|
|
8455
8080
|
class StateManager {
|
|
8456
8081
|
filesMap = /* @__PURE__ */ new Map();
|
|
@@ -8481,12 +8106,7 @@ class StateManager {
|
|
|
8481
8106
|
const _error = error;
|
|
8482
8107
|
if (_error && typeof _error === "object" && _error.code === "VITEST_PENDING") {
|
|
8483
8108
|
const task = this.idMap.get(_error.taskId);
|
|
8484
|
-
if (task) {
|
|
8485
|
-
task.mode = "skip";
|
|
8486
|
-
task.result ??= { state: "skip" };
|
|
8487
|
-
task.result.state = "skip";
|
|
8488
|
-
task.result.note = _error.note;
|
|
8489
|
-
}
|
|
8109
|
+
if (task) task.mode = "skip", task.result ??= { state: "skip" }, task.result.state = "skip", task.result.note = _error.note;
|
|
8490
8110
|
return;
|
|
8491
8111
|
}
|
|
8492
8112
|
if (!this.onUnhandledError || this.onUnhandledError(error) !== false) this.errorsSet.add(error);
|
|
@@ -8510,12 +8130,8 @@ class StateManager {
|
|
|
8510
8130
|
* Return files that were running or collected.
|
|
8511
8131
|
*/
|
|
8512
8132
|
getFiles(keys) {
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
// print typecheck files first
|
|
8516
|
-
if (f1.meta?.typecheck && f2.meta?.typecheck) return 0;
|
|
8517
|
-
if (f1.meta?.typecheck) return -1;
|
|
8518
|
-
return 1;
|
|
8133
|
+
return keys ? keys.map((key) => this.filesMap.get(key)).flat().filter((file) => file && !file.local) : Array.from(this.filesMap.values()).flat().filter((file) => !file.local).sort((f1, f2) => {
|
|
8134
|
+
return f1.meta?.typecheck && f2.meta?.typecheck ? 0 : f1.meta?.typecheck ? -1 : 1;
|
|
8519
8135
|
});
|
|
8520
8136
|
}
|
|
8521
8137
|
getTestModules(keys) {
|
|
@@ -8534,25 +8150,17 @@ class StateManager {
|
|
|
8534
8150
|
}
|
|
8535
8151
|
collectFiles(project, files = []) {
|
|
8536
8152
|
files.forEach((file) => {
|
|
8537
|
-
const existing = this.filesMap.get(file.filepath) || [];
|
|
8538
|
-
const otherFiles = existing.filter((i) => i.projectName !== file.projectName || i.meta.typecheck !== file.meta.typecheck);
|
|
8539
|
-
const currentFile = existing.find((i) => i.projectName === file.projectName);
|
|
8153
|
+
const existing = this.filesMap.get(file.filepath) || [], otherFiles = existing.filter((i) => i.projectName !== file.projectName || i.meta.typecheck !== file.meta.typecheck), currentFile = existing.find((i) => i.projectName === file.projectName);
|
|
8540
8154
|
// keep logs for the previous file because it should always be initiated before the collections phase
|
|
8541
8155
|
// which means that all logs are collected during the collection and not inside tests
|
|
8542
8156
|
if (currentFile) file.logs = currentFile.logs;
|
|
8543
|
-
otherFiles.push(file);
|
|
8544
|
-
this.filesMap.set(file.filepath, otherFiles);
|
|
8545
|
-
this.updateId(file, project);
|
|
8157
|
+
otherFiles.push(file), this.filesMap.set(file.filepath, otherFiles), this.updateId(file, project);
|
|
8546
8158
|
});
|
|
8547
8159
|
}
|
|
8548
8160
|
clearFiles(project, paths = []) {
|
|
8549
8161
|
paths.forEach((path) => {
|
|
8550
|
-
const files = this.filesMap.get(path);
|
|
8551
|
-
|
|
8552
|
-
fileTask.local = true;
|
|
8553
|
-
TestModule.register(fileTask, project);
|
|
8554
|
-
this.idMap.set(fileTask.id, fileTask);
|
|
8555
|
-
if (!files) {
|
|
8162
|
+
const files = this.filesMap.get(path), fileTask = createFileTask(path, project.config.root, project.config.name);
|
|
8163
|
+
if (fileTask.local = true, TestModule.register(fileTask, project), this.idMap.set(fileTask.id, fileTask), !files) {
|
|
8556
8164
|
this.filesMap.set(path, [fileTask]);
|
|
8557
8165
|
return;
|
|
8558
8166
|
}
|
|
@@ -8563,14 +8171,14 @@ class StateManager {
|
|
|
8563
8171
|
});
|
|
8564
8172
|
}
|
|
8565
8173
|
updateId(task, project) {
|
|
8566
|
-
if (this.idMap.get(task.id)
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
}
|
|
8174
|
+
if (this.idMap.get(task.id) !== task) {
|
|
8175
|
+
if (task.type === "suite" && "filepath" in task) TestModule.register(task, project);
|
|
8176
|
+
else if (task.type === "suite") TestSuite.register(task, project);
|
|
8177
|
+
else TestCase.register(task, project);
|
|
8178
|
+
if (this.idMap.set(task.id, task), task.type === "suite") task.tasks.forEach((task) => {
|
|
8179
|
+
this.updateId(task, project);
|
|
8180
|
+
});
|
|
8181
|
+
}
|
|
8574
8182
|
}
|
|
8575
8183
|
getReportedEntity(task) {
|
|
8576
8184
|
return this.reportedTasksMap.get(task);
|
|
@@ -8579,10 +8187,8 @@ class StateManager {
|
|
|
8579
8187
|
for (const [id, result, meta] of packs) {
|
|
8580
8188
|
const task = this.idMap.get(id);
|
|
8581
8189
|
if (task) {
|
|
8582
|
-
task.result = result;
|
|
8583
|
-
task.meta = meta;
|
|
8584
8190
|
// skipped with new PendingError
|
|
8585
|
-
if (result?.state === "skip") task.mode = "skip";
|
|
8191
|
+
if (task.result = result, task.meta = meta, result?.state === "skip") task.mode = "skip";
|
|
8586
8192
|
}
|
|
8587
8193
|
}
|
|
8588
8194
|
}
|
|
@@ -9059,10 +8665,7 @@ class TestRun {
|
|
|
9059
8665
|
}
|
|
9060
8666
|
async start(specifications) {
|
|
9061
8667
|
const filepaths = specifications.map((spec) => spec.moduleId);
|
|
9062
|
-
this.vitest.state.collectPaths(filepaths);
|
|
9063
|
-
await this.vitest.report("onPathsCollected", Array.from(new Set(filepaths)));
|
|
9064
|
-
await this.vitest.report("onSpecsCollected", specifications.map((spec) => spec.toJSON()));
|
|
9065
|
-
await this.vitest.report("onTestRunStart", [...specifications]);
|
|
8668
|
+
this.vitest.state.collectPaths(filepaths), await this.vitest.report("onTestRunStart", [...specifications]);
|
|
9066
8669
|
}
|
|
9067
8670
|
async enqueued(project, file) {
|
|
9068
8671
|
this.vitest.state.collectFiles(project, [file]);
|
|
@@ -9070,25 +8673,17 @@ class TestRun {
|
|
|
9070
8673
|
await this.vitest.report("onTestModuleQueued", testModule);
|
|
9071
8674
|
}
|
|
9072
8675
|
async collected(project, files) {
|
|
9073
|
-
this.vitest.state.collectFiles(project, files)
|
|
9074
|
-
await Promise.all([this.vitest.report("onCollected", files), ...files.map((file) => {
|
|
8676
|
+
this.vitest.state.collectFiles(project, files), await Promise.all(files.map((file) => {
|
|
9075
8677
|
const testModule = this.vitest.state.getReportedEntity(file);
|
|
9076
8678
|
return this.vitest.report("onTestModuleCollected", testModule);
|
|
9077
|
-
})
|
|
8679
|
+
}));
|
|
9078
8680
|
}
|
|
9079
8681
|
async log(log) {
|
|
9080
|
-
this.vitest.state.updateUserLog(log);
|
|
9081
|
-
await this.vitest.report("onUserConsoleLog", log);
|
|
8682
|
+
this.vitest.state.updateUserLog(log), await this.vitest.report("onUserConsoleLog", log);
|
|
9082
8683
|
}
|
|
9083
8684
|
async annotate(testId, annotation) {
|
|
9084
|
-
const task = this.vitest.state.idMap.get(testId);
|
|
9085
|
-
|
|
9086
|
-
assert$1(task && entity, `Entity must be found for task ${task?.name || testId}`);
|
|
9087
|
-
assert$1(entity.type === "test", `Annotation can only be added to a test, instead got ${entity.type}`);
|
|
9088
|
-
await this.resolveTestAttachment(entity, annotation);
|
|
9089
|
-
entity.task.annotations.push(annotation);
|
|
9090
|
-
await this.vitest.report("onTestCaseAnnotate", entity, annotation);
|
|
9091
|
-
return annotation;
|
|
8685
|
+
const task = this.vitest.state.idMap.get(testId), entity = task && this.vitest.state.getReportedEntity(task);
|
|
8686
|
+
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;
|
|
9092
8687
|
}
|
|
9093
8688
|
async updated(update, events) {
|
|
9094
8689
|
this.vitest.state.updateTasks(update);
|
|
@@ -9101,30 +8696,21 @@ class TestRun {
|
|
|
9101
8696
|
await this.vitest.report("onTaskUpdate", update, events);
|
|
9102
8697
|
}
|
|
9103
8698
|
async end(specifications, errors, coverage) {
|
|
8699
|
+
if (coverage) await this.vitest.report("onCoverage", coverage);
|
|
9104
8700
|
// specification won't have the File task if they were filtered by the --shard command
|
|
9105
|
-
const modules = specifications.map((spec) => spec.testModule).filter((s) => s != null);
|
|
9106
|
-
const files = modules.map((m) => m.task);
|
|
9107
|
-
const state = this.vitest.isCancelling ? "interrupted" : this.hasFailed(modules) ? "failed" : "passed";
|
|
8701
|
+
const modules = specifications.map((spec) => spec.testModule).filter((s) => s != null), state = this.vitest.isCancelling ? "interrupted" : this.hasFailed(modules) ? "failed" : "passed";
|
|
9108
8702
|
if (state !== "passed") process.exitCode = 1;
|
|
9109
|
-
|
|
9110
|
-
await Promise.all([this.vitest.report("onTestRunEnd", modules, [...errors], state), this.vitest.report("onFinished", files, errors, coverage)]);
|
|
9111
|
-
} finally {
|
|
9112
|
-
if (coverage) await this.vitest.report("onCoverage", coverage);
|
|
9113
|
-
}
|
|
8703
|
+
this.vitest.report("onTestRunEnd", modules, [...errors], state);
|
|
9114
8704
|
}
|
|
9115
8705
|
hasFailed(modules) {
|
|
9116
|
-
|
|
9117
|
-
return modules.some((m) => !m.ok());
|
|
8706
|
+
return modules.length ? modules.some((m) => !m.ok()) : !this.vitest.config.passWithNoTests;
|
|
9118
8707
|
}
|
|
9119
8708
|
async reportEvent(id, event, data) {
|
|
9120
|
-
const task = this.vitest.state.idMap.get(id);
|
|
9121
|
-
|
|
9122
|
-
assert$1(task && entity, `Entity must be found for task ${task?.name || id}`);
|
|
9123
|
-
if (event === "suite-prepare" && entity.type === "suite") return await this.vitest.report("onTestSuiteReady", entity);
|
|
8709
|
+
const task = this.vitest.state.idMap.get(id), entity = task && this.vitest.state.getReportedEntity(task);
|
|
8710
|
+
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);
|
|
9124
8711
|
if (event === "suite-prepare" && entity.type === "module") return await this.vitest.report("onTestModuleStart", entity);
|
|
9125
8712
|
if (event === "suite-finished") {
|
|
9126
|
-
assert$1(entity.type === "suite" || entity.type === "module", "Entity type must be suite or module")
|
|
9127
|
-
if (entity.state() === "skipped")
|
|
8713
|
+
if (assert$1(entity.type === "suite" || entity.type === "module", "Entity type must be suite or module"), entity.state() === "skipped")
|
|
9128
8714
|
// everything inside suite or a module is skipped,
|
|
9129
8715
|
// so we won't get any children events
|
|
9130
8716
|
// we need to report everything manually
|
|
@@ -9136,8 +8722,7 @@ class TestRun {
|
|
|
9136
8722
|
if (event === "test-prepare" && entity.type === "test") return await this.vitest.report("onTestCaseReady", entity);
|
|
9137
8723
|
if (event === "test-finished" && entity.type === "test") return await this.vitest.report("onTestCaseResult", entity);
|
|
9138
8724
|
if (event.startsWith("before-hook") || event.startsWith("after-hook")) {
|
|
9139
|
-
const isBefore = event.startsWith("before-hook")
|
|
9140
|
-
const hook = entity.type === "test" ? {
|
|
8725
|
+
const isBefore = event.startsWith("before-hook"), hook = entity.type === "test" ? {
|
|
9141
8726
|
name: isBefore ? "beforeEach" : "afterEach",
|
|
9142
8727
|
entity
|
|
9143
8728
|
} : {
|
|
@@ -9149,37 +8734,25 @@ class TestRun {
|
|
|
9149
8734
|
// this can only happen in --merge-reports, and annotation is already resolved
|
|
9150
8735
|
if (event === "test-annotation") {
|
|
9151
8736
|
const annotation = data?.annotation;
|
|
9152
|
-
assert$1(annotation && entity.type === "test");
|
|
9153
|
-
await this.vitest.report("onTestCaseAnnotate", entity, annotation);
|
|
8737
|
+
assert$1(annotation && entity.type === "test"), await this.vitest.report("onTestCaseAnnotate", entity, annotation);
|
|
9154
8738
|
}
|
|
9155
8739
|
}
|
|
9156
8740
|
}
|
|
9157
8741
|
async resolveTestAttachment(test, annotation) {
|
|
9158
|
-
const project = test.project;
|
|
9159
|
-
const attachment = annotation.attachment;
|
|
8742
|
+
const project = test.project, attachment = annotation.attachment;
|
|
9160
8743
|
if (!attachment) return attachment;
|
|
9161
8744
|
const path = attachment.path;
|
|
9162
8745
|
if (path && !path.startsWith("http://") && !path.startsWith("https://")) {
|
|
9163
|
-
const currentPath = resolve(project.config.root, path);
|
|
9164
|
-
|
|
9165
|
-
const newPath = resolve(project.config.attachmentsDir, `${sanitizeFilePath(annotation.message)}-${hash}${extname(currentPath)}`);
|
|
9166
|
-
await mkdir(dirname(newPath), { recursive: true });
|
|
9167
|
-
await copyFile(currentPath, newPath);
|
|
9168
|
-
attachment.path = newPath;
|
|
8746
|
+
const currentPath = resolve(project.config.root, path), hash = createHash("sha1").update(currentPath).digest("hex"), newPath = resolve(project.config.attachmentsDir, `${sanitizeFilePath(annotation.message)}-${hash}${extname(currentPath)}`);
|
|
8747
|
+
await mkdir(dirname(newPath), { recursive: true }), await copyFile(currentPath, newPath), attachment.path = newPath;
|
|
9169
8748
|
const contentType = attachment.contentType ?? mime.getType(basename(currentPath));
|
|
9170
8749
|
attachment.contentType = contentType || void 0;
|
|
9171
8750
|
}
|
|
9172
8751
|
return attachment;
|
|
9173
8752
|
}
|
|
9174
8753
|
async reportChildren(children) {
|
|
9175
|
-
for (const child of children) if (child.type === "test")
|
|
9176
|
-
|
|
9177
|
-
await this.vitest.report("onTestCaseResult", child);
|
|
9178
|
-
} else {
|
|
9179
|
-
await this.vitest.report("onTestSuiteReady", child);
|
|
9180
|
-
await this.reportChildren(child.children);
|
|
9181
|
-
await this.vitest.report("onTestSuiteResult", child);
|
|
9182
|
-
}
|
|
8754
|
+
for (const child of children) if (child.type === "test") await this.vitest.report("onTestCaseReady", child), await this.vitest.report("onTestCaseResult", child);
|
|
8755
|
+
else await this.vitest.report("onTestSuiteReady", child), await this.reportChildren(child.children), await this.vitest.report("onTestSuiteResult", child);
|
|
9183
8756
|
}
|
|
9184
8757
|
}
|
|
9185
8758
|
function sanitizeFilePath(s) {
|
|
@@ -9207,23 +8780,15 @@ class VitestWatcher {
|
|
|
9207
8780
|
* @internal
|
|
9208
8781
|
*/
|
|
9209
8782
|
onWatcherRerun(cb) {
|
|
9210
|
-
this._onRerun.push(cb);
|
|
9211
|
-
return this;
|
|
8783
|
+
return this._onRerun.push(cb), this;
|
|
9212
8784
|
}
|
|
9213
8785
|
unregisterWatcher = noop;
|
|
9214
8786
|
registerWatcher() {
|
|
9215
8787
|
const watcher = this.vitest.vite.watcher;
|
|
9216
8788
|
if (this.vitest.config.forceRerunTriggers.length) watcher.add(this.vitest.config.forceRerunTriggers);
|
|
9217
|
-
watcher.on("change", this.onChange)
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
this.unregisterWatcher = () => {
|
|
9221
|
-
watcher.off("change", this.onChange);
|
|
9222
|
-
watcher.off("unlink", this.onUnlink);
|
|
9223
|
-
watcher.off("add", this.onAdd);
|
|
9224
|
-
this.unregisterWatcher = noop;
|
|
9225
|
-
};
|
|
9226
|
-
return this;
|
|
8789
|
+
return watcher.on("change", this.onChange), watcher.on("unlink", this.onUnlink), watcher.on("add", this.onAdd), this.unregisterWatcher = () => {
|
|
8790
|
+
watcher.off("change", this.onChange), watcher.off("unlink", this.onUnlink), watcher.off("add", this.onAdd), this.unregisterWatcher = noop;
|
|
8791
|
+
}, this;
|
|
9227
8792
|
}
|
|
9228
8793
|
scheduleRerun(file) {
|
|
9229
8794
|
this._onRerun.forEach((cb) => cb(file));
|
|
@@ -9231,25 +8796,17 @@ class VitestWatcher {
|
|
|
9231
8796
|
getTestFilesFromWatcherTrigger(id) {
|
|
9232
8797
|
if (!this.vitest.config.watchTriggerPatterns) return false;
|
|
9233
8798
|
let triggered = false;
|
|
9234
|
-
this.vitest.config.watchTriggerPatterns.forEach((definition) => {
|
|
8799
|
+
return this.vitest.config.watchTriggerPatterns.forEach((definition) => {
|
|
9235
8800
|
const exec = definition.pattern.exec(id);
|
|
9236
8801
|
if (exec) {
|
|
9237
8802
|
const files = definition.testsToRun(id, exec);
|
|
9238
|
-
if (Array.isArray(files))
|
|
9239
|
-
|
|
9240
|
-
files.forEach((file) => this.changedTests.add(resolve(this.vitest.config.root, file)));
|
|
9241
|
-
} else if (typeof files === "string") {
|
|
9242
|
-
triggered = true;
|
|
9243
|
-
this.changedTests.add(resolve(this.vitest.config.root, files));
|
|
9244
|
-
}
|
|
8803
|
+
if (Array.isArray(files)) triggered = true, files.forEach((file) => this.changedTests.add(resolve(this.vitest.config.root, file)));
|
|
8804
|
+
else if (typeof files === "string") triggered = true, this.changedTests.add(resolve(this.vitest.config.root, files));
|
|
9245
8805
|
}
|
|
9246
|
-
});
|
|
9247
|
-
return triggered;
|
|
8806
|
+
}), triggered;
|
|
9248
8807
|
}
|
|
9249
8808
|
onChange = (id) => {
|
|
9250
|
-
id = slash(id);
|
|
9251
|
-
this.vitest.logger.clearHighlightCache(id);
|
|
9252
|
-
this.vitest.invalidateFile(id);
|
|
8809
|
+
id = slash(id), this.vitest.logger.clearHighlightCache(id), this.vitest.invalidateFile(id);
|
|
9253
8810
|
const testFiles = this.getTestFilesFromWatcherTrigger(id);
|
|
9254
8811
|
if (testFiles) this.scheduleRerun(id);
|
|
9255
8812
|
else {
|
|
@@ -9258,21 +8815,10 @@ class VitestWatcher {
|
|
|
9258
8815
|
}
|
|
9259
8816
|
};
|
|
9260
8817
|
onUnlink = (id) => {
|
|
9261
|
-
id = slash(id);
|
|
9262
|
-
this.vitest.logger.clearHighlightCache(id);
|
|
9263
|
-
this.invalidates.add(id);
|
|
9264
|
-
if (this.vitest.state.filesMap.has(id)) {
|
|
9265
|
-
this.vitest.projects.forEach((project) => project._removeCachedTestFile(id));
|
|
9266
|
-
this.vitest.state.filesMap.delete(id);
|
|
9267
|
-
this.vitest.cache.results.removeFromCache(id);
|
|
9268
|
-
this.vitest.cache.stats.removeStats(id);
|
|
9269
|
-
this.changedTests.delete(id);
|
|
9270
|
-
this.vitest.report("onTestRemoved", id);
|
|
9271
|
-
}
|
|
8818
|
+
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);
|
|
9272
8819
|
};
|
|
9273
8820
|
onAdd = (id) => {
|
|
9274
|
-
id = slash(id);
|
|
9275
|
-
this.vitest.invalidateFile(id);
|
|
8821
|
+
id = slash(id), this.vitest.invalidateFile(id);
|
|
9276
8822
|
const testFiles = this.getTestFilesFromWatcherTrigger(id);
|
|
9277
8823
|
if (testFiles) {
|
|
9278
8824
|
this.scheduleRerun(id);
|
|
@@ -9280,13 +8826,10 @@ class VitestWatcher {
|
|
|
9280
8826
|
}
|
|
9281
8827
|
let fileContent;
|
|
9282
8828
|
const matchingProjects = [];
|
|
9283
|
-
this.vitest.projects.forEach((project) => {
|
|
8829
|
+
if (this.vitest.projects.forEach((project) => {
|
|
9284
8830
|
if (project.matchesTestGlob(id, () => fileContent ??= readFileSync(id, "utf-8"))) matchingProjects.push(project);
|
|
9285
|
-
});
|
|
9286
|
-
|
|
9287
|
-
this.changedTests.add(id);
|
|
9288
|
-
this.scheduleRerun(id);
|
|
9289
|
-
} else {
|
|
8831
|
+
}), matchingProjects.length > 0) this.changedTests.add(id), this.scheduleRerun(id);
|
|
8832
|
+
else {
|
|
9290
8833
|
// it's possible that file was already there but watcher triggered "add" event instead
|
|
9291
8834
|
const needsRerun = this.handleFileChanged(id);
|
|
9292
8835
|
if (needsRerun) this.scheduleRerun(id);
|
|
@@ -9294,51 +8837,33 @@ class VitestWatcher {
|
|
|
9294
8837
|
};
|
|
9295
8838
|
handleSetupFile(filepath) {
|
|
9296
8839
|
let isSetupFile = false;
|
|
9297
|
-
this.vitest.projects.forEach((project) => {
|
|
9298
|
-
|
|
9299
|
-
this.vitest.state.filesMap.forEach((files) => {
|
|
8840
|
+
return this.vitest.projects.forEach((project) => {
|
|
8841
|
+
project.config.setupFiles.includes(filepath) && this.vitest.state.filesMap.forEach((files) => {
|
|
9300
8842
|
files.forEach((file) => {
|
|
9301
|
-
if (file.projectName === project.name)
|
|
9302
|
-
isSetupFile = true;
|
|
9303
|
-
this.changedTests.add(file.filepath);
|
|
9304
|
-
}
|
|
8843
|
+
if (file.projectName === project.name) isSetupFile = true, this.changedTests.add(file.filepath);
|
|
9305
8844
|
});
|
|
9306
8845
|
});
|
|
9307
|
-
});
|
|
9308
|
-
return isSetupFile;
|
|
8846
|
+
}), isSetupFile;
|
|
9309
8847
|
}
|
|
9310
8848
|
/**
|
|
9311
8849
|
* @returns A value indicating whether rerun is needed (changedTests was mutated)
|
|
9312
8850
|
*/
|
|
9313
8851
|
handleFileChanged(filepath) {
|
|
9314
8852
|
if (this.changedTests.has(filepath) || this.invalidates.has(filepath)) return false;
|
|
9315
|
-
if (pm.isMatch(filepath, this.vitest.config.forceRerunTriggers))
|
|
9316
|
-
this.vitest.state.getFilepaths().forEach((file) => this.changedTests.add(file));
|
|
9317
|
-
return true;
|
|
9318
|
-
}
|
|
8853
|
+
if (pm.isMatch(filepath, this.vitest.config.forceRerunTriggers)) return this.vitest.state.getFilepaths().forEach((file) => this.changedTests.add(file)), true;
|
|
9319
8854
|
if (this.handleSetupFile(filepath)) return true;
|
|
9320
8855
|
const projects = this.vitest.projects.filter((project) => {
|
|
9321
8856
|
const moduleGraph = project.browser?.vite.moduleGraph || project.vite.moduleGraph;
|
|
9322
8857
|
return moduleGraph.getModulesByFile(filepath)?.size;
|
|
9323
8858
|
});
|
|
9324
|
-
if (!projects.length)
|
|
9325
|
-
// if there are no modules it's possible that server was restarted
|
|
9326
|
-
// we don't have information about importers anymore, so let's check if the file is a test file at least
|
|
9327
|
-
if (this.vitest.state.filesMap.has(filepath) || this.vitest.projects.some((project) => project._isCachedTestFile(filepath))) {
|
|
9328
|
-
this.changedTests.add(filepath);
|
|
9329
|
-
return true;
|
|
9330
|
-
}
|
|
9331
|
-
return false;
|
|
9332
|
-
}
|
|
8859
|
+
if (!projects.length) return this.vitest.state.filesMap.has(filepath) || this.vitest.projects.some((project) => project._isCachedTestFile(filepath)) ? (this.changedTests.add(filepath), true) : false;
|
|
9333
8860
|
const files = [];
|
|
9334
8861
|
for (const project of projects) {
|
|
9335
8862
|
const mods = project.browser?.vite.moduleGraph.getModulesByFile(filepath) || project.vite.moduleGraph.getModulesByFile(filepath);
|
|
9336
8863
|
if (!mods || !mods.size) continue;
|
|
9337
|
-
this.invalidates.add(filepath);
|
|
9338
8864
|
// one of test files that we already run, or one of test files that we can run
|
|
9339
|
-
if (this.vitest.state.filesMap.has(filepath) || project._isCachedTestFile(filepath)) {
|
|
9340
|
-
this.changedTests.add(filepath);
|
|
9341
|
-
files.push(filepath);
|
|
8865
|
+
if (this.invalidates.add(filepath), this.vitest.state.filesMap.has(filepath) || project._isCachedTestFile(filepath)) {
|
|
8866
|
+
this.changedTests.add(filepath), files.push(filepath);
|
|
9342
8867
|
continue;
|
|
9343
8868
|
}
|
|
9344
8869
|
let rerun = false;
|
|
@@ -9409,12 +8934,7 @@ class Vitest {
|
|
|
9409
8934
|
_cache;
|
|
9410
8935
|
_snapshot;
|
|
9411
8936
|
constructor(mode, cliOptions, options = {}) {
|
|
9412
|
-
this.mode = mode;
|
|
9413
|
-
this._cliOptions = cliOptions;
|
|
9414
|
-
this.logger = new Logger(this, options.stdout, options.stderr);
|
|
9415
|
-
this.packageInstaller = options.packageInstaller || new VitestPackageInstaller();
|
|
9416
|
-
this.specifications = new VitestSpecifications(this);
|
|
9417
|
-
this.watcher = new VitestWatcher(this).onWatcherRerun((file) => this.scheduleRerun([file]));
|
|
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([file]));
|
|
9418
8938
|
}
|
|
9419
8939
|
_onRestartListeners = [];
|
|
9420
8940
|
_onClose = [];
|
|
@@ -9434,8 +8954,7 @@ class Vitest {
|
|
|
9434
8954
|
* The global config.
|
|
9435
8955
|
*/
|
|
9436
8956
|
get config() {
|
|
9437
|
-
assert(this._config, "config");
|
|
9438
|
-
return this._config;
|
|
8957
|
+
return assert(this._config, "config"), this._config;
|
|
9439
8958
|
}
|
|
9440
8959
|
/** @deprecated use `vitest.vite` instead */
|
|
9441
8960
|
get server() {
|
|
@@ -9445,30 +8964,26 @@ class Vitest {
|
|
|
9445
8964
|
* Global Vite's dev server instance.
|
|
9446
8965
|
*/
|
|
9447
8966
|
get vite() {
|
|
9448
|
-
assert(this._vite, "vite", "server");
|
|
9449
|
-
return this._vite;
|
|
8967
|
+
return assert(this._vite, "vite", "server"), this._vite;
|
|
9450
8968
|
}
|
|
9451
8969
|
/**
|
|
9452
8970
|
* The global test state manager.
|
|
9453
8971
|
* @experimental The State API is experimental and not subject to semver.
|
|
9454
8972
|
*/
|
|
9455
8973
|
get state() {
|
|
9456
|
-
assert(this._state, "state");
|
|
9457
|
-
return this._state;
|
|
8974
|
+
return assert(this._state, "state"), this._state;
|
|
9458
8975
|
}
|
|
9459
8976
|
/**
|
|
9460
8977
|
* The global snapshot manager. You can access the current state on `snapshot.summary`.
|
|
9461
8978
|
*/
|
|
9462
8979
|
get snapshot() {
|
|
9463
|
-
assert(this._snapshot, "snapshot", "snapshot manager");
|
|
9464
|
-
return this._snapshot;
|
|
8980
|
+
return assert(this._snapshot, "snapshot", "snapshot manager"), this._snapshot;
|
|
9465
8981
|
}
|
|
9466
8982
|
/**
|
|
9467
8983
|
* Test results and test file stats cache. Primarily used by the sequencer to sort tests.
|
|
9468
8984
|
*/
|
|
9469
8985
|
get cache() {
|
|
9470
|
-
assert(this._cache, "cache");
|
|
9471
|
-
return this._cache;
|
|
8986
|
+
return assert(this._cache, "cache"), this._cache;
|
|
9472
8987
|
}
|
|
9473
8988
|
/** @deprecated internal */
|
|
9474
8989
|
setServer(options, server) {
|
|
@@ -9476,48 +8991,21 @@ class Vitest {
|
|
|
9476
8991
|
}
|
|
9477
8992
|
/** @internal */
|
|
9478
8993
|
async _setServer(options, server) {
|
|
9479
|
-
this.watcher.unregisterWatcher();
|
|
9480
|
-
clearTimeout(this._rerunTimer);
|
|
9481
|
-
this.restartsCount += 1;
|
|
9482
|
-
this.pool?.close?.();
|
|
9483
|
-
this.pool = void 0;
|
|
9484
|
-
this.closingPromise = void 0;
|
|
9485
|
-
this.projects = [];
|
|
9486
|
-
this.coverageProvider = void 0;
|
|
9487
|
-
this.runningPromise = void 0;
|
|
9488
|
-
this.coreWorkspaceProject = void 0;
|
|
9489
|
-
this.specifications.clearCache();
|
|
9490
|
-
this._onUserTestsRerun = [];
|
|
9491
|
-
this._vite = 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.coverageProvider = void 0, this.runningPromise = void 0, this.coreWorkspaceProject = void 0, this.specifications.clearCache(), this._onUserTestsRerun = [], this._vite = server;
|
|
9492
8995
|
const resolved = resolveConfig(this, options, server.config);
|
|
9493
|
-
this._config = resolved;
|
|
9494
|
-
this._state = new StateManager({ onUnhandledError: resolved.onUnhandledError });
|
|
9495
|
-
this._cache = new VitestCache(this.version);
|
|
9496
|
-
this._snapshot = new SnapshotManager({ ...resolved.snapshotOptions });
|
|
9497
|
-
this._testRun = new TestRun(this);
|
|
9498
|
-
if (this.config.watch) this.watcher.registerWatcher();
|
|
8996
|
+
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();
|
|
9499
8997
|
this._resolver = new VitestResolver(server.config.cacheDir, resolved);
|
|
9500
8998
|
const environment = server.environments.__vitest__;
|
|
9501
|
-
this.runner = new ServerModuleRunner(environment, this._resolver, resolved)
|
|
9502
|
-
if (this.config.watch) {
|
|
8999
|
+
if (this.runner = new ServerModuleRunner(environment, this._resolver, resolved), this.config.watch) {
|
|
9503
9000
|
// hijack server restart
|
|
9504
9001
|
const serverRestart = server.restart;
|
|
9505
|
-
server.restart = async (...args) => {
|
|
9506
|
-
await Promise.all(this._onRestartListeners.map((fn) => fn()));
|
|
9507
|
-
this.report("onServerRestart");
|
|
9508
|
-
await this.close();
|
|
9509
|
-
await serverRestart(...args);
|
|
9510
|
-
};
|
|
9511
9002
|
// since we set `server.hmr: false`, Vite does not auto restart itself
|
|
9512
|
-
server.
|
|
9003
|
+
server.restart = async (...args) => {
|
|
9004
|
+
await Promise.all(this._onRestartListeners.map((fn) => fn())), this.report("onServerRestart"), await this.close(), await serverRestart(...args);
|
|
9005
|
+
}, server.watcher.on("change", async (file) => {
|
|
9513
9006
|
file = normalize(file);
|
|
9514
9007
|
const isConfig = file === server.config.configFile || this.projects.some((p) => p.vite.config.configFile === file);
|
|
9515
|
-
if (isConfig)
|
|
9516
|
-
await Promise.all(this._onRestartListeners.map((fn) => fn("config")));
|
|
9517
|
-
this.report("onServerRestart", "config");
|
|
9518
|
-
await this.close();
|
|
9519
|
-
await serverRestart();
|
|
9520
|
-
}
|
|
9008
|
+
if (isConfig) await Promise.all(this._onRestartListeners.map((fn) => fn("config"))), this.report("onServerRestart", "config"), await this.close(), await serverRestart();
|
|
9521
9009
|
});
|
|
9522
9010
|
}
|
|
9523
9011
|
this.cache.results.setConfig(resolved.root, resolved.cache);
|
|
@@ -9525,28 +9013,24 @@ class Vitest {
|
|
|
9525
9013
|
await this.cache.results.readFromCache();
|
|
9526
9014
|
} catch {}
|
|
9527
9015
|
const projects = await this.resolveProjects(this._cliOptions);
|
|
9528
|
-
this.projects = projects
|
|
9529
|
-
await Promise.all(projects.flatMap((project) => {
|
|
9016
|
+
if (this.projects = projects, await Promise.all(projects.flatMap((project) => {
|
|
9530
9017
|
const hooks = project.vite.config.getSortedPluginHooks("configureVitest");
|
|
9531
9018
|
return hooks.map((hook) => hook({
|
|
9532
9019
|
project,
|
|
9533
9020
|
vitest: this,
|
|
9534
9021
|
injectTestProjects: this.injectTestProject
|
|
9535
9022
|
}));
|
|
9536
|
-
}))
|
|
9537
|
-
if (this._cliOptions.browser?.enabled) {
|
|
9023
|
+
})), this._cliOptions.browser?.enabled) {
|
|
9538
9024
|
const browserProjects = this.projects.filter((p) => p.config.browser.enabled);
|
|
9539
9025
|
if (!browserProjects.length) throw new Error(`Vitest received --browser flag, but no project had a browser configuration.`);
|
|
9540
9026
|
}
|
|
9541
9027
|
if (!this.projects.length) {
|
|
9542
9028
|
const filter = toArray(resolved.project).join("\", \"");
|
|
9543
|
-
|
|
9544
|
-
else throw new Error(`Vitest wasn't able to resolve any project.`);
|
|
9029
|
+
throw filter ? new Error(`No projects matched the filter "${filter}".`) : new Error(`Vitest wasn't able to resolve any project.`);
|
|
9545
9030
|
}
|
|
9546
9031
|
if (!this.coreWorkspaceProject) this.coreWorkspaceProject = TestProject._createBasicProject(this);
|
|
9547
9032
|
if (this.config.testNamePattern) this.configOverride.testNamePattern = this.config.testNamePattern;
|
|
9548
|
-
this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray(resolved.benchmark?.reporters), this.runner) : await createReporters(resolved.reporters, this);
|
|
9549
|
-
await Promise.all(this._onSetServer.map((fn) => fn()));
|
|
9033
|
+
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()));
|
|
9550
9034
|
}
|
|
9551
9035
|
/**
|
|
9552
9036
|
* Inject new test projects into the workspace.
|
|
@@ -9554,10 +9038,8 @@ class Vitest {
|
|
|
9554
9038
|
* @returns An array of new test projects. Can be empty if the name was filtered out.
|
|
9555
9039
|
*/
|
|
9556
9040
|
injectTestProject = async (config) => {
|
|
9557
|
-
const currentNames = new Set(this.projects.map((p) => p.name));
|
|
9558
|
-
|
|
9559
|
-
this.projects.push(...projects);
|
|
9560
|
-
return projects;
|
|
9041
|
+
const currentNames = new Set(this.projects.map((p) => p.name)), projects = await resolveProjects(this, this._cliOptions, void 0, Array.isArray(config) ? config : [config], currentNames);
|
|
9042
|
+
return this.projects.push(...projects), projects;
|
|
9561
9043
|
};
|
|
9562
9044
|
/**
|
|
9563
9045
|
* Provide a value to the test context. This value will be available to all tests with `inject`.
|
|
@@ -9573,9 +9055,7 @@ class Vitest {
|
|
|
9573
9055
|
}
|
|
9574
9056
|
/** @internal */
|
|
9575
9057
|
_ensureRootProject() {
|
|
9576
|
-
|
|
9577
|
-
this.coreWorkspaceProject = TestProject._createBasicProject(this);
|
|
9578
|
-
return this.coreWorkspaceProject;
|
|
9058
|
+
return this.coreWorkspaceProject ||= TestProject._createBasicProject(this), this.coreWorkspaceProject;
|
|
9579
9059
|
}
|
|
9580
9060
|
/** @deprecated use `getRootProject` instead */
|
|
9581
9061
|
getCoreWorkspaceProject() {
|
|
@@ -9592,8 +9072,7 @@ class Vitest {
|
|
|
9592
9072
|
* @deprecated use Reported Task API instead
|
|
9593
9073
|
*/
|
|
9594
9074
|
getProjectByTaskId(taskId) {
|
|
9595
|
-
const task = this.state.idMap.get(taskId);
|
|
9596
|
-
const projectName = task.projectName || task?.file?.projectName || "";
|
|
9075
|
+
const task = this.state.idMap.get(taskId), projectName = task.projectName || task?.file?.projectName || "";
|
|
9597
9076
|
return this.getProjectByName(projectName);
|
|
9598
9077
|
}
|
|
9599
9078
|
getProjectByName(name) {
|
|
@@ -9615,8 +9094,7 @@ class Vitest {
|
|
|
9615
9094
|
// user can filter projects with --project flag, `getDefaultTestProject`
|
|
9616
9095
|
// returns the project only if it matches the filter
|
|
9617
9096
|
const project = getDefaultTestProject(this);
|
|
9618
|
-
|
|
9619
|
-
return resolveBrowserProjects(this, new Set([project.name]), [project]);
|
|
9097
|
+
return project ? resolveBrowserProjects(this, new Set([project.name]), [project]) : [];
|
|
9620
9098
|
}
|
|
9621
9099
|
/**
|
|
9622
9100
|
* Glob test files in every project and create a TestSpecification for each file and pool.
|
|
@@ -9626,13 +9104,10 @@ class Vitest {
|
|
|
9626
9104
|
return this.specifications.globTestSpecifications(filters);
|
|
9627
9105
|
}
|
|
9628
9106
|
async initCoverageProvider() {
|
|
9629
|
-
if (this.coverageProvider
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
await this.coverageProvider.initialize(this);
|
|
9633
|
-
this.config.coverage = this.coverageProvider.resolveOptions();
|
|
9107
|
+
if (this.coverageProvider === void 0) {
|
|
9108
|
+
if (this.coverageProvider = await getCoverageProvider(this.config.coverage, this.runner), this.coverageProvider) await this.coverageProvider.initialize(this), this.config.coverage = this.coverageProvider.resolveOptions();
|
|
9109
|
+
return this.coverageProvider;
|
|
9634
9110
|
}
|
|
9635
|
-
return this.coverageProvider;
|
|
9636
9111
|
}
|
|
9637
9112
|
/**
|
|
9638
9113
|
* Merge reports from multiple runs located in the specified directory (value from `--merge-reports` if not specified).
|
|
@@ -9645,23 +9120,15 @@ class Vitest {
|
|
|
9645
9120
|
errors,
|
|
9646
9121
|
coverages,
|
|
9647
9122
|
executionTimes
|
|
9648
|
-
};
|
|
9649
|
-
await this.report("onInit", this);
|
|
9650
|
-
await this.report("onPathsCollected", files.flatMap((f) => f.filepath));
|
|
9123
|
+
}, await this.report("onInit", this);
|
|
9651
9124
|
const specifications = [];
|
|
9652
9125
|
for (const file of files) {
|
|
9653
|
-
const project = this.getProjectByName(file.projectName || "");
|
|
9654
|
-
const specification = project.createSpecification(file.filepath, void 0, file.pool);
|
|
9126
|
+
const project = this.getProjectByName(file.projectName || ""), specification = project.createSpecification(file.filepath, void 0, file.pool);
|
|
9655
9127
|
specifications.push(specification);
|
|
9656
9128
|
}
|
|
9657
|
-
await this.report("onSpecsCollected", specifications.map((spec) => spec.toJSON()));
|
|
9658
9129
|
await this._testRun.start(specifications).catch(noop);
|
|
9659
9130
|
for (const file of files) await this._reportFileTask(file);
|
|
9660
|
-
this._checkUnhandledErrors(errors)
|
|
9661
|
-
await this._testRun.end(specifications, errors).catch(noop);
|
|
9662
|
-
await this.initCoverageProvider();
|
|
9663
|
-
await this.coverageProvider?.mergeReports?.(coverages);
|
|
9664
|
-
return {
|
|
9131
|
+
return this._checkUnhandledErrors(errors), await this._testRun.end(specifications, errors).catch(noop), await this.initCoverageProvider(), await this.coverageProvider?.mergeReports?.(coverages), {
|
|
9665
9132
|
testModules: this.state.getTestModules(),
|
|
9666
9133
|
unhandledErrors: this.state.getUnhandledErrors()
|
|
9667
9134
|
};
|
|
@@ -9669,10 +9136,8 @@ class Vitest {
|
|
|
9669
9136
|
/** @internal */
|
|
9670
9137
|
async _reportFileTask(file) {
|
|
9671
9138
|
const project = this.getProjectByName(file.projectName || "");
|
|
9672
|
-
await this._testRun.enqueued(project, file).catch(noop);
|
|
9673
|
-
|
|
9674
|
-
const logs = [];
|
|
9675
|
-
const { packs, events } = convertTasksToEvents(file, (task) => {
|
|
9139
|
+
await this._testRun.enqueued(project, file).catch(noop), await this._testRun.collected(project, [file]).catch(noop);
|
|
9140
|
+
const logs = [], { packs, events } = convertTasksToEvents(file, (task) => {
|
|
9676
9141
|
if (task.logs) logs.push(...task.logs);
|
|
9677
9142
|
});
|
|
9678
9143
|
logs.sort((log1, log2) => log1.time - log2.time);
|
|
@@ -9681,12 +9146,10 @@ class Vitest {
|
|
|
9681
9146
|
}
|
|
9682
9147
|
async collect(filters) {
|
|
9683
9148
|
const files = await this.specifications.getRelevantTestSpecifications(filters);
|
|
9684
|
-
|
|
9685
|
-
if (!files.length) return {
|
|
9149
|
+
return files.length ? this.collectTests(files) : {
|
|
9686
9150
|
testModules: [],
|
|
9687
9151
|
unhandledErrors: []
|
|
9688
9152
|
};
|
|
9689
|
-
return this.collectTests(files);
|
|
9690
9153
|
}
|
|
9691
9154
|
/** @deprecated use `getRelevantTestSpecifications` instead */
|
|
9692
9155
|
listFiles(filters) {
|
|
@@ -9709,8 +9172,7 @@ class Vitest {
|
|
|
9709
9172
|
*/
|
|
9710
9173
|
async start(filters) {
|
|
9711
9174
|
try {
|
|
9712
|
-
await this.initCoverageProvider();
|
|
9713
|
-
await this.coverageProvider?.clean(this.config.coverage.clean);
|
|
9175
|
+
await this.initCoverageProvider(), await this.coverageProvider?.clean(this.config.coverage.clean);
|
|
9714
9176
|
} finally {
|
|
9715
9177
|
await this.report("onInit", this);
|
|
9716
9178
|
}
|
|
@@ -9720,20 +9182,13 @@ class Vitest {
|
|
|
9720
9182
|
if (!files.length) {
|
|
9721
9183
|
await this._testRun.start([]);
|
|
9722
9184
|
const coverage = await this.coverageProvider?.generateCoverage?.({ allTestsRun: true });
|
|
9723
|
-
await this._testRun.end([], [], coverage);
|
|
9724
|
-
// Report coverage for uncovered files
|
|
9725
|
-
await this.reportCoverage(coverage, true);
|
|
9726
|
-
if (!this.config.watch || !(this.config.changed || this.config.related?.length)) throw new FilesNotFoundError(this.mode);
|
|
9185
|
+
if (await this._testRun.end([], [], coverage), await this.reportCoverage(coverage, true), !this.config.watch || !(this.config.changed || this.config.related?.length)) throw new FilesNotFoundError(this.mode);
|
|
9727
9186
|
}
|
|
9728
9187
|
let testModules = {
|
|
9729
9188
|
testModules: [],
|
|
9730
9189
|
unhandledErrors: []
|
|
9731
9190
|
};
|
|
9732
|
-
if (files.length)
|
|
9733
|
-
// populate once, update cache on watch
|
|
9734
|
-
await this.cache.stats.populateStats(this.config.root, files);
|
|
9735
|
-
testModules = await this.runFiles(files, true);
|
|
9736
|
-
}
|
|
9191
|
+
if (files.length) await this.cache.stats.populateStats(this.config.root, files), testModules = await this.runFiles(files, true);
|
|
9737
9192
|
if (this.config.watch) await this.report("onWatcherStart");
|
|
9738
9193
|
return testModules;
|
|
9739
9194
|
}
|
|
@@ -9743,14 +9198,11 @@ class Vitest {
|
|
|
9743
9198
|
*/
|
|
9744
9199
|
async init() {
|
|
9745
9200
|
try {
|
|
9746
|
-
await this.initCoverageProvider();
|
|
9747
|
-
await this.coverageProvider?.clean(this.config.coverage.clean);
|
|
9201
|
+
await this.initCoverageProvider(), await this.coverageProvider?.clean(this.config.coverage.clean);
|
|
9748
9202
|
} finally {
|
|
9749
9203
|
await this.report("onInit", this);
|
|
9750
9204
|
}
|
|
9751
|
-
|
|
9752
|
-
await this.globTestSpecifications();
|
|
9753
|
-
if (this.config.watch) await this.report("onWatcherStart");
|
|
9205
|
+
if (await this.globTestSpecifications(), this.config.watch) await this.report("onWatcherStart");
|
|
9754
9206
|
}
|
|
9755
9207
|
/**
|
|
9756
9208
|
* @deprecated remove when vscode extension supports "getModuleSpecifications"
|
|
@@ -9783,8 +9235,7 @@ class Vitest {
|
|
|
9783
9235
|
* @param allTestsRun Indicates whether all tests were run. This only matters for coverage.
|
|
9784
9236
|
*/
|
|
9785
9237
|
runTestSpecifications(specifications, allTestsRun = false) {
|
|
9786
|
-
specifications.forEach((spec) => this.specifications.ensureSpecificationCached(spec));
|
|
9787
|
-
return this.runFiles(specifications, allTestsRun);
|
|
9238
|
+
return specifications.forEach((spec) => this.specifications.ensureSpecificationCached(spec)), this.runFiles(specifications, allTestsRun);
|
|
9788
9239
|
}
|
|
9789
9240
|
/**
|
|
9790
9241
|
* Rerun files and trigger `onWatcherRerun`, `onWatcherStart` and `onTestsRerun` events.
|
|
@@ -9796,24 +9247,14 @@ class Vitest {
|
|
|
9796
9247
|
const files = specifications.map((spec) => spec.moduleId);
|
|
9797
9248
|
await Promise.all([this.report("onWatcherRerun", files, "rerun test"), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
|
|
9798
9249
|
const result = await this.runTestSpecifications(specifications, allTestsRun);
|
|
9799
|
-
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
9800
|
-
return result;
|
|
9250
|
+
return await this.report("onWatcherStart", this.state.getFiles(files)), result;
|
|
9801
9251
|
}
|
|
9802
9252
|
async runFiles(specs, allTestsRun) {
|
|
9803
|
-
await this._testRun.start(specs)
|
|
9804
|
-
// previous run
|
|
9805
|
-
await this.runningPromise;
|
|
9806
|
-
this._onCancelListeners = [];
|
|
9807
|
-
this.isCancelling = false;
|
|
9808
|
-
// schedule the new run
|
|
9809
|
-
this.runningPromise = (async () => {
|
|
9253
|
+
return await this._testRun.start(specs), await this.runningPromise, this._onCancelListeners = [], this.isCancelling = false, this.runningPromise = (async () => {
|
|
9810
9254
|
try {
|
|
9811
9255
|
if (!this.pool) this.pool = createPool(this);
|
|
9812
9256
|
const invalidates = Array.from(this.watcher.invalidates);
|
|
9813
|
-
this.watcher.invalidates.clear();
|
|
9814
|
-
this.snapshot.clear();
|
|
9815
|
-
this.state.clearErrors();
|
|
9816
|
-
if (!this.isFirstRun && this.config.coverage.cleanOnRerun) await this.coverageProvider?.clean();
|
|
9257
|
+
if (this.watcher.invalidates.clear(), this.snapshot.clear(), this.state.clearErrors(), !this.isFirstRun && this.config.coverage.cleanOnRerun) await this.coverageProvider?.clean();
|
|
9817
9258
|
await this.initializeGlobalSetup(specs);
|
|
9818
9259
|
try {
|
|
9819
9260
|
await this.pool.runTests(specs, invalidates);
|
|
@@ -9830,21 +9271,12 @@ class Vitest {
|
|
|
9830
9271
|
unhandledErrors: this.state.getUnhandledErrors()
|
|
9831
9272
|
};
|
|
9832
9273
|
} finally {
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
const errors = this.state.getUnhandledErrors();
|
|
9836
|
-
this._checkUnhandledErrors(errors);
|
|
9837
|
-
await this._testRun.end(specs, errors, coverage);
|
|
9838
|
-
await this.reportCoverage(coverage, allTestsRun);
|
|
9274
|
+
const coverage = await this.coverageProvider?.generateCoverage({ allTestsRun }), errors = this.state.getUnhandledErrors();
|
|
9275
|
+
this._checkUnhandledErrors(errors), await this._testRun.end(specs, errors, coverage), await this.reportCoverage(coverage, allTestsRun);
|
|
9839
9276
|
}
|
|
9840
9277
|
})().finally(() => {
|
|
9841
|
-
this.runningPromise = void 0;
|
|
9842
|
-
|
|
9843
|
-
// all subsequent runs will treat this as a fresh run
|
|
9844
|
-
this.config.changed = false;
|
|
9845
|
-
this.config.related = void 0;
|
|
9846
|
-
});
|
|
9847
|
-
return await this.runningPromise;
|
|
9278
|
+
this.runningPromise = void 0, this.isFirstRun = false, this.config.changed = false, this.config.related = void 0;
|
|
9279
|
+
}), await this.runningPromise;
|
|
9848
9280
|
}
|
|
9849
9281
|
/**
|
|
9850
9282
|
* Collect tests in specified modules. Vitest will run the files to collect tests.
|
|
@@ -9852,19 +9284,10 @@ class Vitest {
|
|
|
9852
9284
|
*/
|
|
9853
9285
|
async collectTests(specifications) {
|
|
9854
9286
|
const filepaths = specifications.map((spec) => spec.moduleId);
|
|
9855
|
-
this.state.collectPaths(filepaths)
|
|
9856
|
-
// previous run
|
|
9857
|
-
await this.runningPromise;
|
|
9858
|
-
this._onCancelListeners = [];
|
|
9859
|
-
this.isCancelling = false;
|
|
9860
|
-
// schedule the new run
|
|
9861
|
-
this.runningPromise = (async () => {
|
|
9287
|
+
return this.state.collectPaths(filepaths), await this.runningPromise, this._onCancelListeners = [], this.isCancelling = false, this.runningPromise = (async () => {
|
|
9862
9288
|
if (!this.pool) this.pool = createPool(this);
|
|
9863
9289
|
const invalidates = Array.from(this.watcher.invalidates);
|
|
9864
|
-
this.watcher.invalidates.clear();
|
|
9865
|
-
this.snapshot.clear();
|
|
9866
|
-
this.state.clearErrors();
|
|
9867
|
-
await this.initializeGlobalSetup(specifications);
|
|
9290
|
+
this.watcher.invalidates.clear(), this.snapshot.clear(), this.state.clearErrors(), await this.initializeGlobalSetup(specifications);
|
|
9868
9291
|
try {
|
|
9869
9292
|
await this.pool.collectTests(specifications, invalidates);
|
|
9870
9293
|
} catch (err) {
|
|
@@ -9879,28 +9302,21 @@ class Vitest {
|
|
|
9879
9302
|
unhandledErrors: this.state.getUnhandledErrors()
|
|
9880
9303
|
};
|
|
9881
9304
|
})().finally(() => {
|
|
9882
|
-
this.runningPromise = void 0;
|
|
9883
|
-
|
|
9884
|
-
this.config.changed = false;
|
|
9885
|
-
this.config.related = void 0;
|
|
9886
|
-
});
|
|
9887
|
-
return await this.runningPromise;
|
|
9305
|
+
this.runningPromise = void 0, this.config.changed = false, this.config.related = void 0;
|
|
9306
|
+
}), await this.runningPromise;
|
|
9888
9307
|
}
|
|
9889
9308
|
/**
|
|
9890
9309
|
* Gracefully cancel the current test run. Vitest will wait until all running tests are finished before cancelling.
|
|
9891
9310
|
*/
|
|
9892
9311
|
async cancelCurrentRun(reason) {
|
|
9893
|
-
this.isCancelling = true;
|
|
9894
|
-
await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason)));
|
|
9895
|
-
await this.runningPromise;
|
|
9312
|
+
this.isCancelling = true, await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason))), await this.runningPromise;
|
|
9896
9313
|
}
|
|
9897
9314
|
/** @internal */
|
|
9898
9315
|
async _initBrowserServers() {
|
|
9899
9316
|
await Promise.all(this.projects.map((p) => p._initBrowserServer()));
|
|
9900
9317
|
}
|
|
9901
9318
|
async initializeGlobalSetup(paths) {
|
|
9902
|
-
const projects = new Set(paths.map((spec) => spec.project));
|
|
9903
|
-
const coreProject = this.getRootProject();
|
|
9319
|
+
const projects = new Set(paths.map((spec) => spec.project)), coreProject = this.getRootProject();
|
|
9904
9320
|
if (!projects.has(coreProject)) projects.add(coreProject);
|
|
9905
9321
|
for (const project of projects) await project._initializeGlobalSetup();
|
|
9906
9322
|
}
|
|
@@ -9914,8 +9330,7 @@ class Vitest {
|
|
|
9914
9330
|
const specifications = files.flatMap((file) => this.getModuleSpecifications(file));
|
|
9915
9331
|
await Promise.all([this.report("onWatcherRerun", files, trigger), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
|
|
9916
9332
|
const testResult = await this.runFiles(specifications, allTestsRun);
|
|
9917
|
-
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
9918
|
-
return testResult;
|
|
9333
|
+
return await this.report("onWatcherStart", this.state.getFiles(files)), testResult;
|
|
9919
9334
|
}
|
|
9920
9335
|
/** @internal */
|
|
9921
9336
|
async rerunTask(id) {
|
|
@@ -9935,9 +9350,8 @@ class Vitest {
|
|
|
9935
9350
|
// Empty test name pattern should reset filename pattern as well
|
|
9936
9351
|
if (pattern === "") this.filenamePattern = void 0;
|
|
9937
9352
|
const testNamePattern = pattern ? new RegExp(pattern) : void 0;
|
|
9938
|
-
this.configOverride.testNamePattern = testNamePattern;
|
|
9939
9353
|
// filter only test files that have tests matching the pattern
|
|
9940
|
-
if (testNamePattern) files = files.filter((filepath) => {
|
|
9354
|
+
if (this.configOverride.testNamePattern = testNamePattern, testNamePattern) files = files.filter((filepath) => {
|
|
9941
9355
|
const files = this.state.getFiles([filepath]);
|
|
9942
9356
|
return !files.length || files.some((file) => {
|
|
9943
9357
|
const tasks = getTasks(file);
|
|
@@ -9961,9 +9375,7 @@ class Vitest {
|
|
|
9961
9375
|
* @param files The list of files on the file system
|
|
9962
9376
|
*/
|
|
9963
9377
|
async updateSnapshot(files) {
|
|
9964
|
-
|
|
9965
|
-
files = files || [...this.state.getFailedFilepaths(), ...this.snapshot.summary.uncheckedKeysByFile.map((s) => s.filePath)];
|
|
9966
|
-
this.enableSnapshotUpdate();
|
|
9378
|
+
files = files || [...this.state.getFailedFilepaths(), ...this.snapshot.summary.uncheckedKeysByFile.map((s) => s.filePath)], this.enableSnapshotUpdate();
|
|
9967
9379
|
try {
|
|
9968
9380
|
return await this.rerunFiles(files, "update snapshot", false);
|
|
9969
9381
|
} finally {
|
|
@@ -9981,15 +9393,13 @@ class Vitest {
|
|
|
9981
9393
|
this.configOverride.snapshotOptions = {
|
|
9982
9394
|
updateSnapshot: "all",
|
|
9983
9395
|
snapshotEnvironment: null
|
|
9984
|
-
};
|
|
9985
|
-
this.snapshot.options.updateSnapshot = "all";
|
|
9396
|
+
}, this.snapshot.options.updateSnapshot = "all";
|
|
9986
9397
|
}
|
|
9987
9398
|
/**
|
|
9988
9399
|
* Disable the mode that allows updating snapshots when running tests.
|
|
9989
9400
|
*/
|
|
9990
9401
|
resetSnapshotUpdate() {
|
|
9991
|
-
delete this.configOverride.snapshotOptions;
|
|
9992
|
-
this.snapshot.options.updateSnapshot = this.config.snapshotOptions.updateSnapshot;
|
|
9402
|
+
delete this.configOverride.snapshotOptions, this.snapshot.options.updateSnapshot = this.config.snapshotOptions.updateSnapshot;
|
|
9993
9403
|
}
|
|
9994
9404
|
/**
|
|
9995
9405
|
* Set the global test name pattern to a regexp.
|
|
@@ -10009,39 +9419,26 @@ class Vitest {
|
|
|
10009
9419
|
// we can't use a single `triggerId` yet because vscode extension relies on this
|
|
10010
9420
|
async scheduleRerun(triggerId) {
|
|
10011
9421
|
const currentCount = this.restartsCount;
|
|
10012
|
-
clearTimeout(this._rerunTimer)
|
|
10013
|
-
await this.runningPromise;
|
|
10014
|
-
clearTimeout(this._rerunTimer);
|
|
10015
|
-
// server restarted
|
|
10016
|
-
if (this.restartsCount !== currentCount) return;
|
|
10017
|
-
this._rerunTimer = setTimeout(async () => {
|
|
9422
|
+
clearTimeout(this._rerunTimer), await this.runningPromise, clearTimeout(this._rerunTimer), this.restartsCount === currentCount && (this._rerunTimer = setTimeout(async () => {
|
|
10018
9423
|
if (this.watcher.changedTests.size === 0) {
|
|
10019
9424
|
this.watcher.invalidates.clear();
|
|
10020
9425
|
return;
|
|
10021
9426
|
}
|
|
10022
9427
|
// server restarted
|
|
10023
9428
|
if (this.restartsCount !== currentCount) return;
|
|
10024
|
-
this.isFirstRun = false;
|
|
10025
|
-
this.snapshot.clear();
|
|
9429
|
+
this.isFirstRun = false, this.snapshot.clear();
|
|
10026
9430
|
let files = Array.from(this.watcher.changedTests);
|
|
10027
9431
|
if (this.filenamePattern) {
|
|
10028
9432
|
const filteredFiles = await this.globTestSpecifications(this.filenamePattern);
|
|
10029
|
-
files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file));
|
|
10030
9433
|
// A file that does not match the current filename pattern was changed
|
|
10031
|
-
if (files.length === 0) return;
|
|
9434
|
+
if (files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file)), files.length === 0) return;
|
|
10032
9435
|
}
|
|
10033
9436
|
this.watcher.changedTests.clear();
|
|
10034
|
-
const triggerIds = new Set(triggerId.map((id) => relative(this.config.root, id)))
|
|
10035
|
-
|
|
10036
|
-
// get file specifications and filter them if needed
|
|
10037
|
-
const specifications = files.flatMap((file) => this.getModuleSpecifications(file)).filter((specification) => {
|
|
10038
|
-
if (this._onFilterWatchedSpecification.length === 0) return true;
|
|
10039
|
-
return this._onFilterWatchedSpecification.every((fn) => fn(specification));
|
|
9437
|
+
const triggerIds = new Set(triggerId.map((id) => relative(this.config.root, id))), triggerLabel = Array.from(triggerIds).join(", "), specifications = files.flatMap((file) => this.getModuleSpecifications(file)).filter((specification) => {
|
|
9438
|
+
return this._onFilterWatchedSpecification.length === 0 ? true : this._onFilterWatchedSpecification.every((fn) => fn(specification));
|
|
10040
9439
|
});
|
|
10041
|
-
await Promise.all([this.report("onWatcherRerun", files, triggerLabel), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
|
|
10042
|
-
|
|
10043
|
-
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
10044
|
-
}, WATCHER_DEBOUNCE);
|
|
9440
|
+
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));
|
|
9441
|
+
}, WATCHER_DEBOUNCE));
|
|
10045
9442
|
}
|
|
10046
9443
|
/**
|
|
10047
9444
|
* Invalidate a file in all projects.
|
|
@@ -10065,8 +9462,7 @@ class Vitest {
|
|
|
10065
9462
|
}
|
|
10066
9463
|
async reportCoverage(coverage, allTestsRun) {
|
|
10067
9464
|
if (this.state.getCountOfFailedTests() > 0) {
|
|
10068
|
-
await this.coverageProvider?.onTestFailure?.();
|
|
10069
|
-
if (!this.config.coverage.reportOnFailure) return;
|
|
9465
|
+
if (await this.coverageProvider?.onTestFailure?.(), !this.config.coverage.reportOnFailure) return;
|
|
10070
9466
|
}
|
|
10071
9467
|
if (this.coverageProvider) {
|
|
10072
9468
|
await this.coverageProvider.reportCoverage(coverage, { allTestsRun });
|
|
@@ -10089,11 +9485,9 @@ class Vitest {
|
|
|
10089
9485
|
// it's possible that it's not initialized at all because it's not running any tests
|
|
10090
9486
|
if (this.coreWorkspaceProject && !this.projects.includes(this.coreWorkspaceProject)) closePromises.push(this.coreWorkspaceProject.close().then(() => this._vite = void 0));
|
|
10091
9487
|
if (this.pool) closePromises.push((async () => {
|
|
10092
|
-
await this.pool?.close?.();
|
|
10093
|
-
this.pool = void 0;
|
|
9488
|
+
await this.pool?.close?.(), this.pool = void 0;
|
|
10094
9489
|
})());
|
|
10095
|
-
closePromises.push(...this._onClose.map((fn) => fn()))
|
|
10096
|
-
return Promise.allSettled(closePromises).then((results) => {
|
|
9490
|
+
return closePromises.push(...this._onClose.map((fn) => fn())), Promise.allSettled(closePromises).then((results) => {
|
|
10097
9491
|
results.forEach((r) => {
|
|
10098
9492
|
if (r.status === "rejected") this.logger.error("error during close", r.reason);
|
|
10099
9493
|
});
|
|
@@ -10106,11 +9500,9 @@ class Vitest {
|
|
|
10106
9500
|
* @param force If true, the process will exit immediately after closing the projects.
|
|
10107
9501
|
*/
|
|
10108
9502
|
async exit(force = false) {
|
|
10109
|
-
setTimeout(() => {
|
|
9503
|
+
if (setTimeout(() => {
|
|
10110
9504
|
this.report("onProcessTimeout").then(() => {
|
|
10111
|
-
console.warn(`close timed out after ${this.config.teardownTimeout}ms`)
|
|
10112
|
-
this.state.getProcessTimeoutCauses().forEach((cause) => console.warn(cause));
|
|
10113
|
-
if (!this.pool) {
|
|
9505
|
+
if (console.warn(`close timed out after ${this.config.teardownTimeout}ms`), this.state.getProcessTimeoutCauses().forEach((cause) => console.warn(cause)), !this.pool) {
|
|
10114
9506
|
const runningServers = [this._vite, ...this.projects.map((p) => p._vite)].filter(Boolean).length;
|
|
10115
9507
|
if (runningServers === 1) console.warn("Tests closed successfully but something prevents Vite server from exiting");
|
|
10116
9508
|
else if (runningServers > 1) console.warn(`Tests closed successfully but something prevents ${runningServers} Vite servers from exiting`);
|
|
@@ -10119,9 +9511,7 @@ class Vitest {
|
|
|
10119
9511
|
}
|
|
10120
9512
|
process.exit();
|
|
10121
9513
|
});
|
|
10122
|
-
}, this.config.teardownTimeout).unref();
|
|
10123
|
-
await this.close();
|
|
10124
|
-
if (force) process.exit();
|
|
9514
|
+
}, this.config.teardownTimeout).unref(), await this.close(), force) process.exit();
|
|
10125
9515
|
}
|
|
10126
9516
|
/** @internal */
|
|
10127
9517
|
async report(name, ...args) {
|
|
@@ -10203,9 +9593,7 @@ class Vitest {
|
|
|
10203
9593
|
*/
|
|
10204
9594
|
matchesProjectFilter(name) {
|
|
10205
9595
|
const projects = this._config?.project || this._cliOptions?.project;
|
|
10206
|
-
|
|
10207
|
-
if (!projects || !projects.length) return true;
|
|
10208
|
-
return toArray(projects).some((project) => {
|
|
9596
|
+
return !projects || !projects.length ? true : toArray(projects).some((project) => {
|
|
10209
9597
|
const regexp = wildcardPatternToRegExp(project);
|
|
10210
9598
|
return regexp.test(name);
|
|
10211
9599
|
});
|
|
@@ -10218,8 +9606,7 @@ function assert(condition, property, name = property) {
|
|
|
10218
9606
|
async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(options))) {
|
|
10219
9607
|
const userConfig = deepMerge({}, options);
|
|
10220
9608
|
async function UIPlugin() {
|
|
10221
|
-
await vitest.packageInstaller.ensureInstalled("@vitest/ui", options.root || process.cwd(), vitest.version);
|
|
10222
|
-
return (await import('@vitest/ui')).default(vitest);
|
|
9609
|
+
return await vitest.packageInstaller.ensureInstalled("@vitest/ui", options.root || process.cwd(), vitest.version), (await import('@vitest/ui')).default(vitest);
|
|
10223
9610
|
}
|
|
10224
9611
|
return [
|
|
10225
9612
|
{
|
|
@@ -10245,14 +9632,9 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10245
9632
|
let open = false;
|
|
10246
9633
|
if (testConfig.ui && testConfig.open) open = testConfig.uiBase ?? "/__vitest__/";
|
|
10247
9634
|
const resolveOptions = getDefaultResolveOptions();
|
|
10248
|
-
|
|
9635
|
+
let config = {
|
|
10249
9636
|
root: viteConfig.test?.root || options.root,
|
|
10250
9637
|
define: { "process.env.NODE_ENV": "process.env.NODE_ENV" },
|
|
10251
|
-
esbuild: viteConfig.esbuild === false ? false : {
|
|
10252
|
-
target: viteConfig.esbuild?.target || "node18",
|
|
10253
|
-
sourcemap: "external",
|
|
10254
|
-
legalComments: "inline"
|
|
10255
|
-
},
|
|
10256
9638
|
resolve: {
|
|
10257
9639
|
...resolveOptions,
|
|
10258
9640
|
alias: testConfig.alias
|
|
@@ -10282,21 +9664,29 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10282
9664
|
deps: testConfig.deps ?? viteConfig.test?.deps
|
|
10283
9665
|
}
|
|
10284
9666
|
};
|
|
9667
|
+
if ("rolldownVersion" in vite) config = {
|
|
9668
|
+
...config,
|
|
9669
|
+
oxc: viteConfig.oxc === false ? false : { target: viteConfig.oxc?.target || "node18" }
|
|
9670
|
+
};
|
|
9671
|
+
else config = {
|
|
9672
|
+
...config,
|
|
9673
|
+
esbuild: viteConfig.esbuild === false ? false : {
|
|
9674
|
+
target: viteConfig.esbuild?.target || "node18",
|
|
9675
|
+
sourcemap: "external",
|
|
9676
|
+
legalComments: "inline"
|
|
9677
|
+
}
|
|
9678
|
+
};
|
|
10285
9679
|
// inherit so it's available in VitestOptimizer
|
|
10286
9680
|
// I cannot wait to rewrite all of this in Vitest 4
|
|
10287
9681
|
if (options.cache != null) config.test.cache = options.cache;
|
|
10288
9682
|
if (vitest.configOverride.project)
|
|
10289
9683
|
// project filter was set by the user, so we need to filter the project
|
|
10290
9684
|
options.project = vitest.configOverride.project;
|
|
10291
|
-
config.customLogger = createViteLogger(vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false });
|
|
10292
|
-
config.customLogger = silenceImportViteIgnoreWarning(config.customLogger);
|
|
10293
9685
|
// chokidar fsevents is unstable on macos when emitting "ready" event
|
|
10294
|
-
if (process.platform === "darwin" && false);
|
|
9686
|
+
if (config.customLogger = createViteLogger(vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false }), config.customLogger = silenceImportViteIgnoreWarning(config.customLogger), process.platform === "darwin" && false);
|
|
10295
9687
|
const classNameStrategy = typeof testConfig.css !== "boolean" && testConfig.css?.modules?.classNameStrategy || "stable";
|
|
10296
9688
|
if (classNameStrategy !== "scoped") {
|
|
10297
|
-
config.css ??= {}
|
|
10298
|
-
config.css.modules ??= {};
|
|
10299
|
-
if (config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
|
|
9689
|
+
if (config.css ??= {}, config.css.modules ??= {}, config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
|
|
10300
9690
|
const root = vitest.config.root || options.root || process.cwd();
|
|
10301
9691
|
return generateScopedClassName(classNameStrategy, name, relative(root, filename));
|
|
10302
9692
|
};
|
|
@@ -10307,17 +9697,11 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10307
9697
|
const viteConfigTest = viteConfig.test || {};
|
|
10308
9698
|
if (viteConfigTest.watch === false) viteConfigTest.run = true;
|
|
10309
9699
|
if ("alias" in viteConfigTest) delete viteConfigTest.alias;
|
|
10310
|
-
|
|
10311
|
-
options = deepMerge({}, configDefaults, viteConfigTest, options);
|
|
10312
|
-
options.api = resolveApiServerConfig(options, defaultPort);
|
|
9700
|
+
options = deepMerge({}, configDefaults, viteConfigTest, options), options.api = resolveApiServerConfig(options, defaultPort);
|
|
10313
9701
|
// we replace every "import.meta.env" with "process.env"
|
|
10314
9702
|
// to allow reassigning, so we need to put all envs on process.env
|
|
10315
9703
|
const { PROD, DEV,...envs } = viteConfig.env;
|
|
10316
|
-
|
|
10317
|
-
// so we are making them truthy
|
|
10318
|
-
process.env.PROD ??= PROD ? "1" : "";
|
|
10319
|
-
process.env.DEV ??= DEV ? "1" : "";
|
|
10320
|
-
for (const name in envs) process.env[name] ??= envs[name];
|
|
9704
|
+
for (const name in process.env.PROD ??= PROD ? "1" : "", process.env.DEV ??= DEV ? "1" : "", envs) process.env[name] ??= envs[name];
|
|
10321
9705
|
// don't watch files in run mode
|
|
10322
9706
|
if (!options.watch) viteConfig.server.watch = null;
|
|
10323
9707
|
if (options.ui)
|
|
@@ -10337,8 +9721,7 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10337
9721
|
order: "post",
|
|
10338
9722
|
async handler(server) {
|
|
10339
9723
|
if (options.watch && false);
|
|
10340
|
-
await vitest._setServer(options, server);
|
|
10341
|
-
if (options.api && options.watch) (await Promise.resolve().then(function () { return setup$1; })).setup(vitest);
|
|
9724
|
+
if (await vitest._setServer(options, server), options.api && options.watch) (await Promise.resolve().then(function () { return setup$1; })).setup(vitest);
|
|
10342
9725
|
// #415, in run mode we don't need the watcher, close it would improve the performance
|
|
10343
9726
|
if (!options.watch) await server.watcher.close();
|
|
10344
9727
|
}
|
|
@@ -10360,25 +9743,19 @@ function removeUndefinedValues(obj) {
|
|
|
10360
9743
|
}
|
|
10361
9744
|
|
|
10362
9745
|
async function createVitest(mode, options, viteOverrides = {}, vitestOptions = {}) {
|
|
10363
|
-
const ctx = new Vitest(mode, deepClone(options), vitestOptions);
|
|
10364
|
-
const root = slash(resolve$1(options.root || process.cwd()));
|
|
10365
|
-
const configPath = options.config === false ? false : options.config ? resolve$1(root, options.config) : await findUp(configFiles, { cwd: root });
|
|
9746
|
+
const ctx = new Vitest(mode, deepClone(options), vitestOptions), root = slash(resolve$1(options.root || process.cwd())), configPath = options.config === false ? false : options.config ? resolve$1(root, options.config) : await findUp(configFiles, { cwd: root });
|
|
10366
9747
|
options.config = configPath;
|
|
10367
|
-
const { browser: _removeBrowser,...restOptions } = options
|
|
10368
|
-
const config = {
|
|
9748
|
+
const { browser: _removeBrowser,...restOptions } = options, config = {
|
|
10369
9749
|
configFile: configPath,
|
|
10370
9750
|
configLoader: options.configLoader,
|
|
10371
9751
|
mode: options.mode || mode,
|
|
10372
9752
|
plugins: await VitestPlugin(restOptions, ctx)
|
|
10373
|
-
};
|
|
10374
|
-
const server = await createViteServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
|
|
9753
|
+
}, server = await createViteServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
|
|
10375
9754
|
if (ctx.config.api?.port) await server.listen();
|
|
10376
9755
|
return ctx;
|
|
10377
9756
|
}
|
|
10378
9757
|
|
|
10379
|
-
const MAX_RESULT_COUNT = 10;
|
|
10380
|
-
const SELECTION_MAX_INDEX = 7;
|
|
10381
|
-
const ESC = "\x1B[";
|
|
9758
|
+
const MAX_RESULT_COUNT = 10, SELECTION_MAX_INDEX = 7, ESC = "\x1B[";
|
|
10382
9759
|
class WatchFilter {
|
|
10383
9760
|
filterRL;
|
|
10384
9761
|
currentKeyword = void 0;
|
|
@@ -10389,23 +9766,17 @@ class WatchFilter {
|
|
|
10389
9766
|
stdin;
|
|
10390
9767
|
stdout;
|
|
10391
9768
|
constructor(message, stdin = process.stdin, stdout$1 = stdout()) {
|
|
10392
|
-
this.message = message
|
|
10393
|
-
this.stdin = stdin;
|
|
10394
|
-
this.stdout = stdout$1;
|
|
10395
|
-
this.filterRL = readline.createInterface({
|
|
9769
|
+
if (this.message = message, this.stdin = stdin, this.stdout = stdout$1, this.filterRL = readline.createInterface({
|
|
10396
9770
|
input: this.stdin,
|
|
10397
9771
|
escapeCodeTimeout: 50
|
|
10398
|
-
});
|
|
10399
|
-
readline.emitKeypressEvents(this.stdin, this.filterRL);
|
|
10400
|
-
if (this.stdin.isTTY) this.stdin.setRawMode(true);
|
|
9772
|
+
}), readline.emitKeypressEvents(this.stdin, this.filterRL), this.stdin.isTTY) this.stdin.setRawMode(true);
|
|
10401
9773
|
}
|
|
10402
9774
|
async filter(filterFunc) {
|
|
10403
9775
|
this.write(this.promptLine());
|
|
10404
9776
|
const resultPromise = createDefer();
|
|
10405
9777
|
this.onKeyPress = this.filterHandler(filterFunc, (result) => {
|
|
10406
9778
|
resultPromise.resolve(result);
|
|
10407
|
-
});
|
|
10408
|
-
this.stdin.on("keypress", this.onKeyPress);
|
|
9779
|
+
}), this.stdin.on("keypress", this.onKeyPress);
|
|
10409
9780
|
try {
|
|
10410
9781
|
return await resultPromise;
|
|
10411
9782
|
} finally {
|
|
@@ -10421,13 +9792,11 @@ class WatchFilter {
|
|
|
10421
9792
|
break;
|
|
10422
9793
|
case key?.ctrl && key?.name === "c":
|
|
10423
9794
|
case key?.name === "escape":
|
|
10424
|
-
this.write(`${ESC}1G${ESC}0J`);
|
|
10425
|
-
onSubmit(void 0);
|
|
9795
|
+
this.write(`${ESC}1G${ESC}0J`), onSubmit(void 0);
|
|
10426
9796
|
return;
|
|
10427
9797
|
case key?.name === "enter":
|
|
10428
9798
|
case key?.name === "return":
|
|
10429
|
-
onSubmit(this.results[this.selectionIndex] || this.currentKeyword || "");
|
|
10430
|
-
this.currentKeyword = void 0;
|
|
9799
|
+
onSubmit(this.results[this.selectionIndex] || this.currentKeyword || ""), this.currentKeyword = void 0;
|
|
10431
9800
|
break;
|
|
10432
9801
|
case key?.name === "up":
|
|
10433
9802
|
if (this.selectionIndex && this.selectionIndex > 0) this.selectionIndex--;
|
|
@@ -10454,17 +9823,13 @@ class WatchFilter {
|
|
|
10454
9823
|
const resultCountLine = this.results.length === 1 ? `Pattern matches ${this.results.length} result` : `Pattern matches ${this.results.length} results`;
|
|
10455
9824
|
let resultBody = "";
|
|
10456
9825
|
if (this.results.length > MAX_RESULT_COUNT) {
|
|
10457
|
-
const offset = this.selectionIndex > SELECTION_MAX_INDEX ? this.selectionIndex - SELECTION_MAX_INDEX : 0;
|
|
10458
|
-
|
|
10459
|
-
const remainingResultCount = this.results.length - offset - displayResults.length;
|
|
10460
|
-
resultBody = `${displayResults.map((result, index) => index + offset === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n")}`;
|
|
10461
|
-
if (remainingResultCount > 0) resultBody += `
|
|
9826
|
+
const offset = this.selectionIndex > SELECTION_MAX_INDEX ? this.selectionIndex - SELECTION_MAX_INDEX : 0, displayResults = this.results.slice(offset, MAX_RESULT_COUNT + offset), remainingResultCount = this.results.length - offset - displayResults.length;
|
|
9827
|
+
if (resultBody = `${displayResults.map((result, index) => index + offset === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n")}`, remainingResultCount > 0) resultBody += `
|
|
10462
9828
|
${c.dim(` ...and ${remainingResultCount} more ${remainingResultCount === 1 ? "result" : "results"}`)}`;
|
|
10463
9829
|
} else resultBody = this.results.map((result, index) => index === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n");
|
|
10464
9830
|
printStr += `\n${resultCountLine}\n${resultBody}`;
|
|
10465
9831
|
}
|
|
10466
|
-
this.eraseAndPrint(printStr);
|
|
10467
|
-
this.restoreCursor();
|
|
9832
|
+
this.eraseAndPrint(printStr), this.restoreCursor();
|
|
10468
9833
|
}
|
|
10469
9834
|
keywordOffset() {
|
|
10470
9835
|
return `? ${this.message} › `.length + 1;
|
|
@@ -10480,14 +9845,10 @@ ${c.dim(` ...and ${remainingResultCount} more ${remainingResultCount === 1 ? "
|
|
|
10480
9845
|
// We have to take care of screen width in case of long lines
|
|
10481
9846
|
rows += 1 + Math.floor(Math.max(stripVTControlCharacters(line).length - 1, 0) / columns);
|
|
10482
9847
|
}
|
|
10483
|
-
this.write(`${ESC}1G`);
|
|
10484
|
-
this.write(`${ESC}J`);
|
|
10485
|
-
this.write(str);
|
|
10486
|
-
this.write(`${ESC}${rows - 1}A`);
|
|
9848
|
+
this.write(`${ESC}1G`), this.write(`${ESC}J`), this.write(str), this.write(`${ESC}${rows - 1}A`);
|
|
10487
9849
|
}
|
|
10488
9850
|
close() {
|
|
10489
|
-
this.filterRL.close();
|
|
10490
|
-
if (this.onKeyPress) this.stdin.removeListener("keypress", this.onKeyPress);
|
|
9851
|
+
if (this.filterRL.close(), this.onKeyPress) this.stdin.removeListener("keypress", this.onKeyPress);
|
|
10491
9852
|
if (this.stdin.isTTY) this.stdin.setRawMode(false);
|
|
10492
9853
|
}
|
|
10493
9854
|
restoreCursor() {
|
|
@@ -10512,8 +9873,7 @@ const keys = [
|
|
|
10512
9873
|
["w", "filter by a project name"],
|
|
10513
9874
|
["b", "start the browser server if not started yet"],
|
|
10514
9875
|
["q", "quit"]
|
|
10515
|
-
]
|
|
10516
|
-
const cancelKeys = [
|
|
9876
|
+
], cancelKeys = [
|
|
10517
9877
|
"space",
|
|
10518
9878
|
"c",
|
|
10519
9879
|
"h",
|
|
@@ -10531,17 +9891,12 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10531
9891
|
// Cancel run and exit when ctrl-c or esc is pressed.
|
|
10532
9892
|
// If cancelling takes long and key is pressed multiple times, exit forcefully.
|
|
10533
9893
|
if (str === "" || str === "\x1B" || key && key.ctrl && key.name === "c") {
|
|
10534
|
-
if (!ctx.isCancelling)
|
|
10535
|
-
ctx.logger.log(c.red("Cancelling test run. Press CTRL+c again to exit forcefully.\n"));
|
|
10536
|
-
process.exitCode = 130;
|
|
10537
|
-
await ctx.cancelCurrentRun("keyboard-input");
|
|
10538
|
-
}
|
|
9894
|
+
if (!ctx.isCancelling) ctx.logger.log(c.red("Cancelling test run. Press CTRL+c again to exit forcefully.\n")), process.exitCode = 130, await ctx.cancelCurrentRun("keyboard-input");
|
|
10539
9895
|
return ctx.exit(true);
|
|
10540
9896
|
}
|
|
10541
9897
|
// window not support suspend
|
|
10542
9898
|
if (!isWindows && key && key.ctrl && key.name === "z") {
|
|
10543
|
-
process.kill(process.ppid, "SIGTSTP");
|
|
10544
|
-
process.kill(process.pid, "SIGTSTP");
|
|
9899
|
+
process.kill(process.ppid, "SIGTSTP"), process.kill(process.pid, "SIGTSTP");
|
|
10545
9900
|
return;
|
|
10546
9901
|
}
|
|
10547
9902
|
const name = key?.name;
|
|
@@ -10570,24 +9925,17 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10570
9925
|
if (name === "t") return inputNamePattern();
|
|
10571
9926
|
// change fileNamePattern
|
|
10572
9927
|
if (name === "p") return inputFilePattern();
|
|
10573
|
-
if (name === "b") {
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
ctx.logger.log();
|
|
10577
|
-
ctx.logger.printBrowserBanner(project);
|
|
10578
|
-
});
|
|
10579
|
-
return null;
|
|
10580
|
-
}
|
|
9928
|
+
if (name === "b") return await ctx._initBrowserServers(), ctx.projects.forEach((project) => {
|
|
9929
|
+
ctx.logger.log(), ctx.logger.printBrowserBanner(project);
|
|
9930
|
+
}), null;
|
|
10581
9931
|
}
|
|
10582
9932
|
async function keypressHandler(str, key) {
|
|
10583
9933
|
await _keypressHandler(str, key);
|
|
10584
9934
|
}
|
|
10585
9935
|
async function inputNamePattern() {
|
|
10586
9936
|
off();
|
|
10587
|
-
const watchFilter = new WatchFilter("Input test name pattern (RegExp)", stdin, stdout)
|
|
10588
|
-
|
|
10589
|
-
const files = ctx.state.getFiles();
|
|
10590
|
-
const tests = getTests(files);
|
|
9937
|
+
const watchFilter = new WatchFilter("Input test name pattern (RegExp)", stdin, stdout), filter = await watchFilter.filter((str) => {
|
|
9938
|
+
const files = ctx.state.getFiles(), tests = getTests(files);
|
|
10591
9939
|
try {
|
|
10592
9940
|
const reg = new RegExp(str);
|
|
10593
9941
|
return tests.map((test) => test.name).filter((testName) => testName.match(reg));
|
|
@@ -10596,11 +9944,8 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10596
9944
|
return [];
|
|
10597
9945
|
}
|
|
10598
9946
|
});
|
|
10599
|
-
on();
|
|
10600
|
-
|
|
10601
|
-
const files = ctx.state.getFilepaths();
|
|
10602
|
-
// if running in standalone mode, Vitest instance doesn't know about any test file
|
|
10603
|
-
const cliFiles = ctx.config.standalone && !files.length ? await ctx._globTestFilepaths() : void 0;
|
|
9947
|
+
if (on(), typeof filter === "undefined") return;
|
|
9948
|
+
const files = ctx.state.getFilepaths(), cliFiles = ctx.config.standalone && !files.length ? await ctx._globTestFilepaths() : void 0;
|
|
10604
9949
|
await ctx.changeNamePattern(filter?.trim() || "", cliFiles, "change pattern");
|
|
10605
9950
|
}
|
|
10606
9951
|
async function inputProjectName() {
|
|
@@ -10611,41 +9956,31 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10611
9956
|
message: "Input a single project name",
|
|
10612
9957
|
initial: ctx.config.project[0] || ""
|
|
10613
9958
|
}]);
|
|
10614
|
-
on();
|
|
10615
|
-
await ctx.changeProjectName(filter.trim());
|
|
9959
|
+
on(), await ctx.changeProjectName(filter.trim());
|
|
10616
9960
|
}
|
|
10617
9961
|
async function inputFilePattern() {
|
|
10618
9962
|
off();
|
|
10619
|
-
const watchFilter = new WatchFilter("Input filename pattern", stdin, stdout)
|
|
10620
|
-
const filter = await watchFilter.filter(async (str) => {
|
|
9963
|
+
const watchFilter = new WatchFilter("Input filename pattern", stdin, stdout), filter = await watchFilter.filter(async (str) => {
|
|
10621
9964
|
const files = await ctx.globTestFiles([str]);
|
|
10622
9965
|
return files.map((file) => relative(ctx.config.root, file[1])).filter((file, index, all) => all.indexOf(file) === index);
|
|
10623
9966
|
});
|
|
10624
|
-
on();
|
|
10625
|
-
if (typeof filter === "undefined") return;
|
|
9967
|
+
if (on(), typeof filter === "undefined") return;
|
|
10626
9968
|
latestFilename = filter?.trim() || "";
|
|
10627
9969
|
const lastResults = watchFilter.getLastResults();
|
|
10628
9970
|
await ctx.changeFilenamePattern(latestFilename, filter && lastResults.length ? lastResults.map((i) => resolve(ctx.config.root, i)) : void 0);
|
|
10629
9971
|
}
|
|
10630
9972
|
let rl;
|
|
10631
9973
|
function on() {
|
|
10632
|
-
off()
|
|
10633
|
-
rl = readline.createInterface({
|
|
9974
|
+
if (off(), rl = readline.createInterface({
|
|
10634
9975
|
input: stdin,
|
|
10635
9976
|
escapeCodeTimeout: 50
|
|
10636
|
-
});
|
|
10637
|
-
readline.emitKeypressEvents(stdin, rl);
|
|
10638
|
-
if (stdin.isTTY) stdin.setRawMode(true);
|
|
9977
|
+
}), readline.emitKeypressEvents(stdin, rl), stdin.isTTY) stdin.setRawMode(true);
|
|
10639
9978
|
stdin.on("keypress", keypressHandler);
|
|
10640
9979
|
}
|
|
10641
9980
|
function off() {
|
|
10642
|
-
rl?.close();
|
|
10643
|
-
rl = void 0;
|
|
10644
|
-
stdin.removeListener("keypress", keypressHandler);
|
|
10645
|
-
if (stdin.isTTY) stdin.setRawMode(false);
|
|
9981
|
+
if (rl?.close(), rl = void 0, stdin.removeListener("keypress", keypressHandler), stdin.isTTY) stdin.setRawMode(false);
|
|
10646
9982
|
}
|
|
10647
|
-
on()
|
|
10648
|
-
return function cleanup() {
|
|
9983
|
+
return on(), function cleanup() {
|
|
10649
9984
|
off();
|
|
10650
9985
|
};
|
|
10651
9986
|
}
|
|
@@ -10656,20 +9991,14 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10656
9991
|
* Returns a Vitest instance if initialized successfully.
|
|
10657
9992
|
*/
|
|
10658
9993
|
async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, vitestOptions) {
|
|
10659
|
-
const root = resolve(options.root || process.cwd());
|
|
10660
|
-
const ctx = await prepareVitest(mode, options, viteOverrides, vitestOptions, cliFilters);
|
|
9994
|
+
const root = resolve(options.root || process.cwd()), ctx = await prepareVitest(mode, options, viteOverrides, vitestOptions, cliFilters);
|
|
10661
9995
|
if (mode === "test" && ctx.config.coverage.enabled) {
|
|
10662
|
-
const provider = ctx.config.coverage.provider || "v8";
|
|
10663
|
-
const requiredPackages = CoverageProviderMap[provider];
|
|
9996
|
+
const provider = ctx.config.coverage.provider || "v8", requiredPackages = CoverageProviderMap[provider];
|
|
10664
9997
|
if (requiredPackages) {
|
|
10665
|
-
if (!await ctx.packageInstaller.ensureInstalled(requiredPackages, root, ctx.version))
|
|
10666
|
-
process.exitCode = 1;
|
|
10667
|
-
return ctx;
|
|
10668
|
-
}
|
|
9998
|
+
if (!await ctx.packageInstaller.ensureInstalled(requiredPackages, root, ctx.version)) return process.exitCode = 1, ctx;
|
|
10669
9999
|
}
|
|
10670
10000
|
}
|
|
10671
|
-
const stdin = vitestOptions?.stdin || process.stdin;
|
|
10672
|
-
const stdout = vitestOptions?.stdout || process.stdout;
|
|
10001
|
+
const stdin = vitestOptions?.stdin || process.stdin, stdout = vitestOptions?.stdout || process.stdout;
|
|
10673
10002
|
let stdinCleanup;
|
|
10674
10003
|
if (stdin.isTTY && ctx.config.watch) stdinCleanup = registerConsoleShortcuts(ctx, stdin, stdout);
|
|
10675
10004
|
ctx.onAfterSetServer(() => {
|
|
@@ -10681,55 +10010,27 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, v
|
|
|
10681
10010
|
else if (ctx.config.standalone) await ctx.init();
|
|
10682
10011
|
else await ctx.start(cliFilters);
|
|
10683
10012
|
} catch (e) {
|
|
10684
|
-
|
|
10685
|
-
if (e instanceof GitNotFoundError) {
|
|
10686
|
-
ctx.logger.error(e.message);
|
|
10687
|
-
return ctx;
|
|
10688
|
-
}
|
|
10689
|
-
if (e instanceof IncludeTaskLocationDisabledError || e instanceof RangeLocationFilterProvidedError || e instanceof LocationFilterFileNotFoundError) {
|
|
10690
|
-
ctx.logger.printError(e, { verbose: false });
|
|
10691
|
-
return ctx;
|
|
10692
|
-
}
|
|
10693
|
-
process.exitCode = 1;
|
|
10694
|
-
ctx.logger.printError(e, {
|
|
10013
|
+
return e instanceof FilesNotFoundError ? ctx : e instanceof GitNotFoundError ? (ctx.logger.error(e.message), ctx) : e instanceof IncludeTaskLocationDisabledError || e instanceof RangeLocationFilterProvidedError || e instanceof LocationFilterFileNotFoundError ? (ctx.logger.printError(e, { verbose: false }), ctx) : (process.exitCode = 1, ctx.logger.printError(e, {
|
|
10695
10014
|
fullStack: true,
|
|
10696
10015
|
type: "Unhandled Error"
|
|
10697
|
-
});
|
|
10698
|
-
ctx.logger.error("\n\n");
|
|
10699
|
-
return ctx;
|
|
10016
|
+
}), ctx.logger.error("\n\n"), ctx);
|
|
10700
10017
|
}
|
|
10701
|
-
|
|
10702
|
-
stdinCleanup?.();
|
|
10703
|
-
await ctx.close();
|
|
10704
|
-
return ctx;
|
|
10018
|
+
return ctx.shouldKeepServer() ? ctx : (stdinCleanup?.(), await ctx.close(), ctx);
|
|
10705
10019
|
}
|
|
10706
10020
|
async function prepareVitest(mode, options = {}, viteOverrides, vitestOptions, cliFilters) {
|
|
10707
|
-
process.env.TEST = "true";
|
|
10708
|
-
process.env.VITEST = "true";
|
|
10709
|
-
process.env.NODE_ENV ??= "test";
|
|
10710
|
-
if (options.run) options.watch = false;
|
|
10021
|
+
if (process.env.TEST = "true", process.env.VITEST = "true", process.env.NODE_ENV ??= "test", options.run) options.watch = false;
|
|
10711
10022
|
if (options.standalone && (cliFilters?.length || 0) > 0) options.standalone = false;
|
|
10712
10023
|
// this shouldn't affect _application root_ that can be changed inside config
|
|
10713
|
-
const root = resolve(options.root || process.cwd());
|
|
10714
|
-
|
|
10715
|
-
const environmentPackage = getEnvPackageName(ctx.config.environment);
|
|
10716
|
-
if (environmentPackage && !await ctx.packageInstaller.ensureInstalled(environmentPackage, root)) {
|
|
10717
|
-
process.exitCode = 1;
|
|
10718
|
-
return ctx;
|
|
10719
|
-
}
|
|
10720
|
-
return ctx;
|
|
10024
|
+
const root = resolve(options.root || process.cwd()), ctx = await createVitest(mode, options, viteOverrides, vitestOptions), environmentPackage = getEnvPackageName(ctx.config.environment);
|
|
10025
|
+
return environmentPackage && !await ctx.packageInstaller.ensureInstalled(environmentPackage, root) && (process.exitCode = 1), ctx;
|
|
10721
10026
|
}
|
|
10722
10027
|
function processCollected(ctx, files, options) {
|
|
10723
10028
|
let errorsPrinted = false;
|
|
10724
|
-
forEachSuite(files, (suite) => {
|
|
10029
|
+
if (forEachSuite(files, (suite) => {
|
|
10725
10030
|
suite.errors().forEach((error) => {
|
|
10726
|
-
errorsPrinted = true;
|
|
10727
|
-
ctx.logger.printError(error, { project: suite.project });
|
|
10031
|
+
errorsPrinted = true, ctx.logger.printError(error, { project: suite.project });
|
|
10728
10032
|
});
|
|
10729
|
-
});
|
|
10730
|
-
if (errorsPrinted) return;
|
|
10731
|
-
if (typeof options.json !== "undefined") return processJsonOutput(files, options);
|
|
10732
|
-
return formatCollectedAsString(files).forEach((test) => console.log(test));
|
|
10033
|
+
}), !errorsPrinted) return typeof options.json === "undefined" ? formatCollectedAsString(files).forEach((test) => console.log(test)) : processJsonOutput(files, options);
|
|
10733
10034
|
}
|
|
10734
10035
|
function outputFileList(files, options) {
|
|
10735
10036
|
if (typeof options.json !== "undefined") return outputJsonFileList(files, options);
|
|
@@ -10739,8 +10040,7 @@ function outputJsonFileList(files, options) {
|
|
|
10739
10040
|
if (typeof options.json === "boolean") return console.log(JSON.stringify(formatFilesAsJSON(files), null, 2));
|
|
10740
10041
|
if (typeof options.json === "string") {
|
|
10741
10042
|
const jsonPath = resolve(options.root || process.cwd(), options.json);
|
|
10742
|
-
mkdirSync(dirname(jsonPath), { recursive: true });
|
|
10743
|
-
writeFileSync(jsonPath, JSON.stringify(formatFilesAsJSON(files), null, 2));
|
|
10043
|
+
mkdirSync(dirname(jsonPath), { recursive: true }), writeFileSync(jsonPath, JSON.stringify(formatFilesAsJSON(files), null, 2));
|
|
10744
10044
|
}
|
|
10745
10045
|
}
|
|
10746
10046
|
function formatFilesAsJSON(files) {
|
|
@@ -10761,8 +10061,7 @@ function processJsonOutput(files, options) {
|
|
|
10761
10061
|
if (typeof options.json === "boolean") return console.log(JSON.stringify(formatCollectedAsJSON(files), null, 2));
|
|
10762
10062
|
if (typeof options.json === "string") {
|
|
10763
10063
|
const jsonPath = resolve(options.root || process.cwd(), options.json);
|
|
10764
|
-
mkdirSync(dirname(jsonPath), { recursive: true });
|
|
10765
|
-
writeFileSync(jsonPath, JSON.stringify(formatCollectedAsJSON(files), null, 2));
|
|
10064
|
+
mkdirSync(dirname(jsonPath), { recursive: true }), writeFileSync(jsonPath, JSON.stringify(formatCollectedAsJSON(files), null, 2));
|
|
10766
10065
|
}
|
|
10767
10066
|
}
|
|
10768
10067
|
function forEachSuite(modules, callback) {
|
|
@@ -10773,7 +10072,7 @@ function forEachSuite(modules, callback) {
|
|
|
10773
10072
|
}
|
|
10774
10073
|
function formatCollectedAsJSON(files) {
|
|
10775
10074
|
const results = [];
|
|
10776
|
-
files.forEach((file) => {
|
|
10075
|
+
return files.forEach((file) => {
|
|
10777
10076
|
for (const test of file.children.allTests()) {
|
|
10778
10077
|
if (test.result().state === "skipped") continue;
|
|
10779
10078
|
const result = {
|
|
@@ -10784,19 +10083,17 @@ function formatCollectedAsJSON(files) {
|
|
|
10784
10083
|
if (test.location) result.location = test.location;
|
|
10785
10084
|
results.push(result);
|
|
10786
10085
|
}
|
|
10787
|
-
});
|
|
10788
|
-
return results;
|
|
10086
|
+
}), results;
|
|
10789
10087
|
}
|
|
10790
10088
|
function formatCollectedAsString(testModules) {
|
|
10791
10089
|
const results = [];
|
|
10792
|
-
testModules.forEach((testModule) => {
|
|
10090
|
+
return testModules.forEach((testModule) => {
|
|
10793
10091
|
for (const test of testModule.children.allTests()) {
|
|
10794
10092
|
if (test.result().state === "skipped") continue;
|
|
10795
10093
|
const fullName = `${test.module.task.name} > ${test.fullName}`;
|
|
10796
10094
|
results.push((test.project.name ? `[${test.project.name}] ` : "") + fullName);
|
|
10797
10095
|
}
|
|
10798
|
-
});
|
|
10799
|
-
return results;
|
|
10096
|
+
}), results;
|
|
10800
10097
|
}
|
|
10801
10098
|
const envPackageNames = {
|
|
10802
10099
|
"jsdom": "jsdom",
|
|
@@ -10804,10 +10101,7 @@ const envPackageNames = {
|
|
|
10804
10101
|
"edge-runtime": "@edge-runtime/vm"
|
|
10805
10102
|
};
|
|
10806
10103
|
function getEnvPackageName(env) {
|
|
10807
|
-
|
|
10808
|
-
if (env in envPackageNames) return envPackageNames[env];
|
|
10809
|
-
if (env[0] === "." || isAbsolute(env)) return null;
|
|
10810
|
-
return `vitest-environment-${env}`;
|
|
10104
|
+
return env === "node" ? null : env in envPackageNames ? envPackageNames[env] : env[0] === "." || isAbsolute(env) ? null : `vitest-environment-${env}`;
|
|
10811
10105
|
}
|
|
10812
10106
|
|
|
10813
10107
|
var cliApi = /*#__PURE__*/Object.freeze({
|