vitest 3.2.0-beta.3 → 3.2.1
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 +29 -0
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +2 -2
- package/dist/chunks/{base.D4119yLM.js → base.Cg0miDlQ.js} +10 -14
- package/dist/chunks/{benchmark.Cf_PACH1.js → benchmark.CYdenmiT.js} +4 -6
- package/dist/chunks/{cac.DWaWHIIE.js → cac.C8BzMmTW.js} +66 -136
- package/dist/chunks/{cli-api.CnmEXkxs.js → cli-api.DmupRhea.js} +1251 -1336
- package/dist/chunks/{console.Cwr-MFPV.js → console.CtFJOzRO.js} +24 -45
- package/dist/chunks/{coverage.0iPg4Wrz.js → coverage.DVF1vEu8.js} +4 -12
- package/dist/chunks/{coverage.C73DaDgS.js → coverage.EIiagJJP.js} +484 -1003
- package/dist/chunks/{creator.C8WKy2eW.js → creator.GK6I-cL4.js} +29 -76
- package/dist/chunks/{date.ByMsSlOr.js → date.Bq6ZW5rf.js} +3 -8
- package/dist/chunks/{defaults.DpVH7vbg.js → defaults.B7q_naMc.js} +1 -1
- package/dist/chunks/{env.Dq0hM4Xv.js → env.D4Lgay0q.js} +1 -1
- package/dist/chunks/{execute.B3q-2LPV.js → execute.B7h3T_Hc.js} +104 -220
- package/dist/chunks/{git.DXfdBEfR.js → git.BVQ8w_Sw.js} +1 -3
- package/dist/chunks/{global.d.BNLIi6yo.d.ts → global.d.MAmajcmJ.d.ts} +2 -0
- package/dist/chunks/{globals.CI21aWXF.js → globals.DEHgCU4V.js} +5 -5
- package/dist/chunks/{index.Bter3jj9.js → index.BZ0g1JD2.js} +366 -628
- package/dist/chunks/{index.CbT4iuwc.js → index.BbB8_kAK.js} +22 -24
- package/dist/chunks/{index.JOzufsrU.js → index.CIyJn3t1.js} +37 -82
- package/dist/chunks/{index.DNgLEKsQ.js → index.CdQS2e2Q.js} +2 -2
- package/dist/chunks/{index.2jgTs_Q5.js → index.CmSc2RE5.js} +69 -107
- package/dist/chunks/{inspector.BFsh5KO0.js → inspector.C914Efll.js} +1 -1
- package/dist/chunks/{node.Be-ntJnD.js → node.fjCdwEIl.js} +1 -1
- package/dist/chunks/{reporters.d.Bt4IGtsa.d.ts → reporters.d.C1ogPriE.d.ts} +24 -4
- package/dist/chunks/{rpc.BKExFSRG.js → rpc.Iovn4oWe.js} +9 -19
- package/dist/chunks/{runBaseTests.B_M1TTsK.js → runBaseTests.Dd85QTll.js} +18 -31
- package/dist/chunks/{setup-common.CF-O-dZX.js → setup-common.Dd054P77.js} +15 -42
- package/dist/chunks/{typechecker.BgzF-6iO.js → typechecker.DRKU1-1g.js} +106 -186
- package/dist/chunks/{utils.DPCq3gzW.js → utils.CAioKnHs.js} +6 -14
- package/dist/chunks/{utils.BlI4TC7Y.js → utils.XdZDrNZV.js} +5 -13
- package/dist/chunks/{vi.pkoYCV6A.js → vi.bdSIJ99Y.js} +118 -267
- package/dist/chunks/{vite.d.B-Kx3KCF.d.ts → vite.d.DqE4-hhK.d.ts} +1 -1
- package/dist/chunks/{vm.DPYem2so.js → vm.BThCzidc.js} +98 -214
- package/dist/chunks/{worker.d.Bl1O4kuf.d.ts → worker.d.DvqK5Vmu.d.ts} +1 -1
- package/dist/chunks/{worker.d.BKbBp2ga.d.ts → worker.d.tQu2eJQy.d.ts} +3 -1
- package/dist/cli.js +4 -4
- package/dist/config.cjs +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.js +2 -2
- package/dist/coverage.d.ts +2 -2
- package/dist/coverage.js +5 -5
- package/dist/environments.js +1 -1
- package/dist/execute.d.ts +1 -1
- package/dist/execute.js +1 -1
- package/dist/index.d.ts +12 -11
- package/dist/index.js +5 -5
- package/dist/node.d.ts +7 -7
- package/dist/node.js +12 -14
- package/dist/reporters.d.ts +2 -2
- package/dist/reporters.js +4 -4
- package/dist/runners.d.ts +5 -2
- package/dist/runners.js +51 -80
- package/dist/snapshot.js +2 -2
- package/dist/suite.js +2 -2
- package/dist/worker.js +36 -42
- package/dist/workers/forks.js +4 -4
- package/dist/workers/runVmTests.js +15 -21
- package/dist/workers/threads.js +4 -4
- package/dist/workers/vmForks.js +6 -6
- package/dist/workers/vmThreads.js +6 -6
- package/dist/workers.d.ts +2 -2
- package/dist/workers.js +10 -10
- package/package.json +16 -14
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { promises, existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import {
|
|
3
|
-
import { C as CoverageProviderMap } from './coverage.
|
|
1
|
+
import fs, { promises, existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { relative, resolve, dirname, extname, normalize, join, basename, isAbsolute } from 'pathe';
|
|
3
|
+
import { C as CoverageProviderMap } from './coverage.DVF1vEu8.js';
|
|
4
4
|
import path, { resolve as resolve$1 } from 'node:path';
|
|
5
|
-
import { noop, isPrimitive, createDefer, highlight, toArray, deepMerge, nanoid,
|
|
5
|
+
import { noop, isPrimitive, createDefer, slash, highlight, toArray, deepMerge, nanoid, deepClone, notNullish } from '@vitest/utils';
|
|
6
6
|
import { f as findUp, p as prompt } from './index.X0nbfr6-.js';
|
|
7
7
|
import * as vite from 'vite';
|
|
8
8
|
import { searchForWorkspaceRoot, version, createServer, mergeConfig } from 'vite';
|
|
@@ -11,9 +11,9 @@ import { generateFileHash, limitConcurrency, createFileTask, hasFailed, getTasks
|
|
|
11
11
|
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
12
12
|
import { ViteNodeRunner } from 'vite-node/client';
|
|
13
13
|
import { ViteNodeServer } from 'vite-node/server';
|
|
14
|
-
import { v as version$1 } from './cac.
|
|
14
|
+
import { v as version$1 } from './cac.C8BzMmTW.js';
|
|
15
15
|
import { c as createBirpc } from './index.CJ0plNrh.js';
|
|
16
|
-
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, j as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.
|
|
16
|
+
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, j as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.BZ0g1JD2.js';
|
|
17
17
|
import require$$0$3 from 'events';
|
|
18
18
|
import require$$1$1 from 'https';
|
|
19
19
|
import require$$2 from 'http';
|
|
@@ -26,24 +26,24 @@ import require$$0 from 'zlib';
|
|
|
26
26
|
import require$$0$1 from 'buffer';
|
|
27
27
|
import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
|
|
28
28
|
import { parseErrorStacktrace } from '@vitest/utils/source-map';
|
|
29
|
-
import crypto from 'node:crypto';
|
|
29
|
+
import crypto, { createHash } from 'node:crypto';
|
|
30
30
|
import { distDir, rootDir } from '../path.js';
|
|
31
|
-
import {
|
|
32
|
-
import { c as convertTasksToEvents } from './typechecker.
|
|
31
|
+
import { h as hash, R as RandomSequencer, i as isPackageExists, g as getFilePoolName, d as isBrowserEnabled, r as resolveConfig, e as groupBy, f as getCoverageProvider, j as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.EIiagJJP.js';
|
|
32
|
+
import { c as convertTasksToEvents } from './typechecker.DRKU1-1g.js';
|
|
33
33
|
import { Console } from 'node:console';
|
|
34
34
|
import c from 'tinyrainbow';
|
|
35
35
|
import { createRequire } from 'node:module';
|
|
36
36
|
import url from 'node:url';
|
|
37
|
-
import { i as isTTY, a as isWindows } from './env.
|
|
38
|
-
import { rm } from 'node:fs/promises';
|
|
37
|
+
import { i as isTTY, a as isWindows } from './env.D4Lgay0q.js';
|
|
38
|
+
import { rm, mkdir, copyFile } from 'node:fs/promises';
|
|
39
39
|
import nodeos__default, { tmpdir } from 'node:os';
|
|
40
40
|
import pm from 'picomatch';
|
|
41
41
|
import { glob, isDynamicPattern } from 'tinyglobby';
|
|
42
42
|
import { normalizeRequestId, cleanUrl } from 'vite-node/utils';
|
|
43
43
|
import { hoistMocksPlugin, automockPlugin } from '@vitest/mocker/node';
|
|
44
|
-
import { c as configDefaults } from './defaults.
|
|
44
|
+
import { c as configDefaults } from './defaults.B7q_naMc.js';
|
|
45
45
|
import MagicString from 'magic-string';
|
|
46
|
-
import { a as BenchmarkReportsMap } from './index.
|
|
46
|
+
import { a as BenchmarkReportsMap } from './index.CIyJn3t1.js';
|
|
47
47
|
import assert$1 from 'node:assert';
|
|
48
48
|
import { serializeError } from '@vitest/utils/error';
|
|
49
49
|
import readline from 'node:readline';
|
|
@@ -5007,19 +5007,13 @@ var WebSocketServer = /*@__PURE__*/getDefaultExportFromCjs(websocketServerExport
|
|
|
5007
5007
|
|
|
5008
5008
|
async function getModuleGraph(ctx, projectName, id, browser = false) {
|
|
5009
5009
|
const graph = {};
|
|
5010
|
-
const externalized = new Set();
|
|
5011
|
-
const inlined = new Set();
|
|
5010
|
+
const externalized = /* @__PURE__ */ new Set();
|
|
5011
|
+
const inlined = /* @__PURE__ */ new Set();
|
|
5012
5012
|
const project = ctx.getProjectByName(projectName);
|
|
5013
|
-
async function get(mod, seen = new Map()) {
|
|
5014
|
-
if (!mod || !mod.id)
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
if (mod.id === "\0@vitest/browser/context") {
|
|
5018
|
-
return;
|
|
5019
|
-
}
|
|
5020
|
-
if (seen.has(mod)) {
|
|
5021
|
-
return seen.get(mod);
|
|
5022
|
-
}
|
|
5013
|
+
async function get(mod, seen = /* @__PURE__ */ new Map()) {
|
|
5014
|
+
if (!mod || !mod.id) return;
|
|
5015
|
+
if (mod.id === "\0@vitest/browser/context") return;
|
|
5016
|
+
if (seen.has(mod)) return seen.get(mod);
|
|
5023
5017
|
let id = clearId(mod.id);
|
|
5024
5018
|
seen.set(mod, id);
|
|
5025
5019
|
const rewrote = browser ? mod.file?.includes(project.browser.vite.config.cacheDir) ? mod.id : false : await project.vitenode.shouldExternalize(id);
|
|
@@ -5027,18 +5021,13 @@ async function getModuleGraph(ctx, projectName, id, browser = false) {
|
|
|
5027
5021
|
id = rewrote;
|
|
5028
5022
|
externalized.add(id);
|
|
5029
5023
|
seen.set(mod, id);
|
|
5030
|
-
} else
|
|
5031
|
-
inlined.add(id);
|
|
5032
|
-
}
|
|
5024
|
+
} else inlined.add(id);
|
|
5033
5025
|
const mods = Array.from(mod.importedModules).filter((i) => i.id && !i.id.includes("/vitest/dist/"));
|
|
5034
5026
|
graph[id] = (await Promise.all(mods.map((m) => get(m, seen)))).filter(Boolean);
|
|
5035
5027
|
return id;
|
|
5036
5028
|
}
|
|
5037
|
-
if (browser && project.browser)
|
|
5038
|
-
|
|
5039
|
-
} else {
|
|
5040
|
-
await get(project.vite.moduleGraph.getModuleById(id));
|
|
5041
|
-
}
|
|
5029
|
+
if (browser && project.browser) await get(project.browser.vite.moduleGraph.getModuleById(id));
|
|
5030
|
+
else await get(project.vite.moduleGraph.getModuleById(id));
|
|
5042
5031
|
return {
|
|
5043
5032
|
graph,
|
|
5044
5033
|
externalized: Array.from(externalized),
|
|
@@ -5071,9 +5060,7 @@ function stringifyReplace(key, value) {
|
|
|
5071
5060
|
stack: value.stack,
|
|
5072
5061
|
...cloned
|
|
5073
5062
|
};
|
|
5074
|
-
} else
|
|
5075
|
-
return value;
|
|
5076
|
-
}
|
|
5063
|
+
} else return value;
|
|
5077
5064
|
}
|
|
5078
5065
|
|
|
5079
5066
|
function isValidApiRequest(config, req) {
|
|
@@ -5081,9 +5068,7 @@ function isValidApiRequest(config, req) {
|
|
|
5081
5068
|
// validate token. token is injected in ui/tester/orchestrator html, which is cross origin protected.
|
|
5082
5069
|
try {
|
|
5083
5070
|
const token = url.searchParams.get("token");
|
|
5084
|
-
if (token && crypto.timingSafeEqual(Buffer.from(token), Buffer.from(config.api.token)))
|
|
5085
|
-
return true;
|
|
5086
|
-
}
|
|
5071
|
+
if (token && crypto.timingSafeEqual(Buffer.from(token), Buffer.from(config.api.token))) return true;
|
|
5087
5072
|
}
|
|
5088
5073
|
// an error is thrown when the length is incorrect
|
|
5089
5074
|
catch {}
|
|
@@ -5092,16 +5077,12 @@ catch {}
|
|
|
5092
5077
|
|
|
5093
5078
|
function setup(ctx, _server) {
|
|
5094
5079
|
const wss = new WebSocketServer({ noServer: true });
|
|
5095
|
-
const clients = new Map();
|
|
5080
|
+
const clients = /* @__PURE__ */ new Map();
|
|
5096
5081
|
const server = _server || ctx.server;
|
|
5097
5082
|
server.httpServer?.on("upgrade", (request, socket, head) => {
|
|
5098
|
-
if (!request.url)
|
|
5099
|
-
return;
|
|
5100
|
-
}
|
|
5083
|
+
if (!request.url) return;
|
|
5101
5084
|
const { pathname } = new URL(request.url, "http://localhost");
|
|
5102
|
-
if (pathname !== API_PATH)
|
|
5103
|
-
return;
|
|
5104
|
-
}
|
|
5085
|
+
if (pathname !== API_PATH) return;
|
|
5105
5086
|
if (!isValidApiRequest(ctx.config, request)) {
|
|
5106
5087
|
socket.destroy();
|
|
5107
5088
|
return;
|
|
@@ -5123,19 +5104,15 @@ function setup(ctx, _server) {
|
|
|
5123
5104
|
return ctx.state.getPaths();
|
|
5124
5105
|
},
|
|
5125
5106
|
async readTestFile(id) {
|
|
5126
|
-
if (!ctx.state.filesMap.has(id) || !existsSync(id))
|
|
5127
|
-
return null;
|
|
5128
|
-
}
|
|
5107
|
+
if (!ctx.state.filesMap.has(id) || !existsSync(id)) return null;
|
|
5129
5108
|
return promises.readFile(id, "utf-8");
|
|
5130
5109
|
},
|
|
5131
5110
|
async saveTestFile(id, content) {
|
|
5132
|
-
if (!ctx.state.filesMap.has(id) || !existsSync(id)) {
|
|
5133
|
-
throw new Error(`Test file "${id}" was not registered, so it cannot be updated using the API.`);
|
|
5134
|
-
}
|
|
5111
|
+
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.`);
|
|
5135
5112
|
return promises.writeFile(id, content, "utf-8");
|
|
5136
5113
|
},
|
|
5137
5114
|
async rerun(files, resetTestNamePattern) {
|
|
5138
|
-
await ctx.rerunFiles(files,
|
|
5115
|
+
await ctx.rerunFiles(files, void 0, true, resetTestNamePattern);
|
|
5139
5116
|
},
|
|
5140
5117
|
async rerunTask(id) {
|
|
5141
5118
|
await ctx.rerunTask(id);
|
|
@@ -5166,11 +5143,8 @@ function setup(ctx, _server) {
|
|
|
5166
5143
|
return getModuleGraph(ctx, project, id, browser);
|
|
5167
5144
|
},
|
|
5168
5145
|
async updateSnapshot(file) {
|
|
5169
|
-
if (!file)
|
|
5170
|
-
|
|
5171
|
-
} else {
|
|
5172
|
-
await ctx.updateSnapshot([file.filepath]);
|
|
5173
|
-
}
|
|
5146
|
+
if (!file) await ctx.updateSnapshot();
|
|
5147
|
+
else await ctx.updateSnapshot([file.filepath]);
|
|
5174
5148
|
},
|
|
5175
5149
|
getUnhandledErrors() {
|
|
5176
5150
|
return ctx.state.getUnhandledErrors();
|
|
@@ -5216,42 +5190,38 @@ class WebSocketReporter {
|
|
|
5216
5190
|
this.clients = clients;
|
|
5217
5191
|
}
|
|
5218
5192
|
onCollected(files) {
|
|
5219
|
-
if (this.clients.size === 0)
|
|
5220
|
-
return;
|
|
5221
|
-
}
|
|
5193
|
+
if (this.clients.size === 0) return;
|
|
5222
5194
|
this.clients.forEach((client) => {
|
|
5223
5195
|
client.onCollected?.(files)?.catch?.(noop);
|
|
5224
5196
|
});
|
|
5225
5197
|
}
|
|
5226
5198
|
onSpecsCollected(specs) {
|
|
5227
|
-
if (this.clients.size === 0)
|
|
5228
|
-
return;
|
|
5229
|
-
}
|
|
5199
|
+
if (this.clients.size === 0) return;
|
|
5230
5200
|
this.clients.forEach((client) => {
|
|
5231
5201
|
client.onSpecsCollected?.(specs)?.catch?.(noop);
|
|
5232
5202
|
});
|
|
5233
5203
|
}
|
|
5234
|
-
async
|
|
5235
|
-
if (this.clients.size === 0)
|
|
5236
|
-
|
|
5237
|
-
|
|
5204
|
+
async onTestCaseAnnotate(testCase, annotation) {
|
|
5205
|
+
if (this.clients.size === 0) return;
|
|
5206
|
+
this.clients.forEach((client) => {
|
|
5207
|
+
client.onTestAnnotate?.(testCase.id, annotation)?.catch?.(noop);
|
|
5208
|
+
});
|
|
5209
|
+
}
|
|
5210
|
+
async onTaskUpdate(packs, events) {
|
|
5211
|
+
if (this.clients.size === 0) return;
|
|
5238
5212
|
packs.forEach(([taskId, result]) => {
|
|
5239
5213
|
const task = this.ctx.state.idMap.get(taskId);
|
|
5240
5214
|
const isBrowser = task && task.file.pool === "browser";
|
|
5241
5215
|
result?.errors?.forEach((error) => {
|
|
5242
|
-
if (isPrimitive(error))
|
|
5243
|
-
return;
|
|
5244
|
-
}
|
|
5216
|
+
if (isPrimitive(error)) return;
|
|
5245
5217
|
if (isBrowser) {
|
|
5246
5218
|
const project = this.ctx.getProjectByName(task.file.projectName || "");
|
|
5247
5219
|
error.stacks = project.browser?.parseErrorStacktrace(error);
|
|
5248
|
-
} else
|
|
5249
|
-
error.stacks = parseErrorStacktrace(error);
|
|
5250
|
-
}
|
|
5220
|
+
} else error.stacks = parseErrorStacktrace(error);
|
|
5251
5221
|
});
|
|
5252
5222
|
});
|
|
5253
5223
|
this.clients.forEach((client) => {
|
|
5254
|
-
client.onTaskUpdate?.(packs)?.catch?.(noop);
|
|
5224
|
+
client.onTaskUpdate?.(packs, events)?.catch?.(noop);
|
|
5255
5225
|
});
|
|
5256
5226
|
}
|
|
5257
5227
|
onFinished(files, errors) {
|
|
@@ -5278,8 +5248,8 @@ var setup$1 = /*#__PURE__*/Object.freeze({
|
|
|
5278
5248
|
});
|
|
5279
5249
|
|
|
5280
5250
|
class BrowserSessions {
|
|
5281
|
-
sessions = new Map();
|
|
5282
|
-
sessionIds = new Set();
|
|
5251
|
+
sessions = /* @__PURE__ */ new Map();
|
|
5252
|
+
sessionIds = /* @__PURE__ */ new Set();
|
|
5283
5253
|
getSession(sessionId) {
|
|
5284
5254
|
return this.sessions.get(sessionId);
|
|
5285
5255
|
}
|
|
@@ -5308,6 +5278,116 @@ class BrowserSessions {
|
|
|
5308
5278
|
}
|
|
5309
5279
|
}
|
|
5310
5280
|
|
|
5281
|
+
class FilesStatsCache {
|
|
5282
|
+
cache = /* @__PURE__ */ new Map();
|
|
5283
|
+
getStats(key) {
|
|
5284
|
+
return this.cache.get(key);
|
|
5285
|
+
}
|
|
5286
|
+
async populateStats(root, specs) {
|
|
5287
|
+
const promises = specs.map((spec) => {
|
|
5288
|
+
const key = `${spec[0].name}:${relative(root, spec.moduleId)}`;
|
|
5289
|
+
return this.updateStats(spec.moduleId, key);
|
|
5290
|
+
});
|
|
5291
|
+
await Promise.all(promises);
|
|
5292
|
+
}
|
|
5293
|
+
async updateStats(fsPath, key) {
|
|
5294
|
+
if (!fs.existsSync(fsPath)) return;
|
|
5295
|
+
const stats = await fs.promises.stat(fsPath);
|
|
5296
|
+
this.cache.set(key, { size: stats.size });
|
|
5297
|
+
}
|
|
5298
|
+
removeStats(fsPath) {
|
|
5299
|
+
this.cache.forEach((_, key) => {
|
|
5300
|
+
if (key.endsWith(fsPath)) this.cache.delete(key);
|
|
5301
|
+
});
|
|
5302
|
+
}
|
|
5303
|
+
}
|
|
5304
|
+
|
|
5305
|
+
class ResultsCache {
|
|
5306
|
+
cache = /* @__PURE__ */ new Map();
|
|
5307
|
+
workspacesKeyMap = /* @__PURE__ */ new Map();
|
|
5308
|
+
cachePath = null;
|
|
5309
|
+
version;
|
|
5310
|
+
root = "/";
|
|
5311
|
+
constructor(version) {
|
|
5312
|
+
this.version = version;
|
|
5313
|
+
}
|
|
5314
|
+
getCachePath() {
|
|
5315
|
+
return this.cachePath;
|
|
5316
|
+
}
|
|
5317
|
+
setConfig(root, config) {
|
|
5318
|
+
this.root = root;
|
|
5319
|
+
if (config) this.cachePath = resolve(config.dir, "results.json");
|
|
5320
|
+
}
|
|
5321
|
+
getResults(key) {
|
|
5322
|
+
return this.cache.get(key);
|
|
5323
|
+
}
|
|
5324
|
+
async readFromCache() {
|
|
5325
|
+
if (!this.cachePath) return;
|
|
5326
|
+
if (!fs.existsSync(this.cachePath)) return;
|
|
5327
|
+
const resultsCache = await fs.promises.readFile(this.cachePath, "utf8");
|
|
5328
|
+
const { results, version } = JSON.parse(resultsCache || "[]");
|
|
5329
|
+
const [major, minor] = version.split(".");
|
|
5330
|
+
// handling changed in 0.30.0
|
|
5331
|
+
if (major > 0 || Number(minor) >= 30) {
|
|
5332
|
+
this.cache = new Map(results);
|
|
5333
|
+
this.version = version;
|
|
5334
|
+
results.forEach(([spec]) => {
|
|
5335
|
+
const [projectName, relativePath] = spec.split(":");
|
|
5336
|
+
const keyMap = this.workspacesKeyMap.get(relativePath) || [];
|
|
5337
|
+
keyMap.push(projectName);
|
|
5338
|
+
this.workspacesKeyMap.set(relativePath, keyMap);
|
|
5339
|
+
});
|
|
5340
|
+
}
|
|
5341
|
+
}
|
|
5342
|
+
updateResults(files) {
|
|
5343
|
+
files.forEach((file) => {
|
|
5344
|
+
const result = file.result;
|
|
5345
|
+
if (!result) return;
|
|
5346
|
+
const duration = result.duration || 0;
|
|
5347
|
+
// store as relative, so cache would be the same in CI and locally
|
|
5348
|
+
const relativePath = relative(this.root, file.filepath);
|
|
5349
|
+
this.cache.set(`${file.projectName || ""}:${relativePath}`, {
|
|
5350
|
+
duration: duration >= 0 ? duration : 0,
|
|
5351
|
+
failed: result.state === "fail"
|
|
5352
|
+
});
|
|
5353
|
+
});
|
|
5354
|
+
}
|
|
5355
|
+
removeFromCache(filepath) {
|
|
5356
|
+
this.cache.forEach((_, key) => {
|
|
5357
|
+
if (key.endsWith(filepath)) this.cache.delete(key);
|
|
5358
|
+
});
|
|
5359
|
+
}
|
|
5360
|
+
async writeToCache() {
|
|
5361
|
+
if (!this.cachePath) return;
|
|
5362
|
+
const results = Array.from(this.cache.entries());
|
|
5363
|
+
const cacheDirname = dirname(this.cachePath);
|
|
5364
|
+
if (!fs.existsSync(cacheDirname)) await fs.promises.mkdir(cacheDirname, { recursive: true });
|
|
5365
|
+
const cache = JSON.stringify({
|
|
5366
|
+
version: this.version,
|
|
5367
|
+
results
|
|
5368
|
+
});
|
|
5369
|
+
await fs.promises.writeFile(this.cachePath, cache);
|
|
5370
|
+
}
|
|
5371
|
+
}
|
|
5372
|
+
|
|
5373
|
+
class VitestCache {
|
|
5374
|
+
results;
|
|
5375
|
+
stats = new FilesStatsCache();
|
|
5376
|
+
constructor(version) {
|
|
5377
|
+
this.results = new ResultsCache(version);
|
|
5378
|
+
}
|
|
5379
|
+
getFileTestResults(key) {
|
|
5380
|
+
return this.results.getResults(key);
|
|
5381
|
+
}
|
|
5382
|
+
getFileStats(key) {
|
|
5383
|
+
return this.stats.getStats(key);
|
|
5384
|
+
}
|
|
5385
|
+
static resolveCacheDir(root, dir, projectName) {
|
|
5386
|
+
const baseDir = slash(dir || "node_modules/.vite");
|
|
5387
|
+
return resolve(root, baseDir, "vitest", hash("sha1", projectName || "", "hex"));
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
|
|
5311
5391
|
class FilesNotFoundError extends Error {
|
|
5312
5392
|
code = "VITEST_FILES_NOT_FOUND";
|
|
5313
5393
|
constructor(mode) {
|
|
@@ -5323,7 +5403,7 @@ class GitNotFoundError extends Error {
|
|
|
5323
5403
|
class LocationFilterFileNotFoundError extends Error {
|
|
5324
5404
|
code = "VITEST_LOCATION_FILTER_FILE_NOT_FOUND";
|
|
5325
5405
|
constructor(filename) {
|
|
5326
|
-
super(`Couldn\'t find file ${filename}. Note when specifying the test
|
|
5406
|
+
super(`Couldn\'t find file ${filename}. Note when specifying the test location you have to specify the full test filename.`);
|
|
5327
5407
|
}
|
|
5328
5408
|
}
|
|
5329
5409
|
class IncludeTaskLocationDisabledError extends Error {
|
|
@@ -5335,7 +5415,7 @@ class IncludeTaskLocationDisabledError extends Error {
|
|
|
5335
5415
|
class RangeLocationFilterProvidedError extends Error {
|
|
5336
5416
|
code = "VITEST_RANGE_LOCATION_FILTER_PROVIDED";
|
|
5337
5417
|
constructor(filter) {
|
|
5338
|
-
super(`Found "-" in location filter ${filter}. Note that range location filters
|
|
5418
|
+
super(`Found "-" in location filter ${filter}. Note that range location filters are not supported. Consider specifying the exact line numbers of your tests.`);
|
|
5339
5419
|
}
|
|
5340
5420
|
}
|
|
5341
5421
|
class VitestFilteredOutProjectError extends Error {
|
|
@@ -5355,9 +5435,7 @@ const HIGHLIGHT_SUPPORTED_EXTS = new Set(["js", "ts"].flatMap((lang) => [
|
|
|
5355
5435
|
]));
|
|
5356
5436
|
function highlightCode(id, source, colors) {
|
|
5357
5437
|
const ext = extname(id);
|
|
5358
|
-
if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext))
|
|
5359
|
-
return source;
|
|
5360
|
-
}
|
|
5438
|
+
if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext)) return source;
|
|
5361
5439
|
const isJsx = ext.endsWith("x");
|
|
5362
5440
|
return highlight(source, {
|
|
5363
5441
|
jsx: isJsx,
|
|
@@ -5375,7 +5453,7 @@ const SHOW_CURSOR = `${ESC$1}?25h`;
|
|
|
5375
5453
|
const CLEAR_SCREEN = "\x1Bc";
|
|
5376
5454
|
class Logger {
|
|
5377
5455
|
_clearScreenPending;
|
|
5378
|
-
_highlights = new Map();
|
|
5456
|
+
_highlights = /* @__PURE__ */ new Map();
|
|
5379
5457
|
cleanupListeners = [];
|
|
5380
5458
|
console;
|
|
5381
5459
|
constructor(ctx, outputStream = process.stdout, errorStream = process.stderr) {
|
|
@@ -5389,9 +5467,7 @@ class Logger {
|
|
|
5389
5467
|
this._highlights.clear();
|
|
5390
5468
|
this.addCleanupListeners();
|
|
5391
5469
|
this.registerUnhandledRejection();
|
|
5392
|
-
if (this.outputStream.isTTY)
|
|
5393
|
-
this.outputStream.write(HIDE_CURSOR);
|
|
5394
|
-
}
|
|
5470
|
+
if (this.outputStream.isTTY) this.outputStream.write(HIDE_CURSOR);
|
|
5395
5471
|
}
|
|
5396
5472
|
log(...args) {
|
|
5397
5473
|
this._clearScreen();
|
|
@@ -5410,11 +5486,8 @@ class Logger {
|
|
|
5410
5486
|
this.console.log(message);
|
|
5411
5487
|
return;
|
|
5412
5488
|
}
|
|
5413
|
-
if (message) {
|
|
5414
|
-
|
|
5415
|
-
} else {
|
|
5416
|
-
this.outputStream.write(`${CLEAR_SCREEN}${ERASE_SCROLLBACK}`);
|
|
5417
|
-
}
|
|
5489
|
+
if (message) this.console.log(`${CLEAR_SCREEN}${ERASE_SCROLLBACK}${message}`);
|
|
5490
|
+
else this.outputStream.write(`${CLEAR_SCREEN}${ERASE_SCROLLBACK}`);
|
|
5418
5491
|
}
|
|
5419
5492
|
clearScreen(message, force = false) {
|
|
5420
5493
|
if (!this.ctx.config.clearScreen) {
|
|
@@ -5422,72 +5495,46 @@ class Logger {
|
|
|
5422
5495
|
return;
|
|
5423
5496
|
}
|
|
5424
5497
|
this._clearScreenPending = message;
|
|
5425
|
-
if (force)
|
|
5426
|
-
this._clearScreen();
|
|
5427
|
-
}
|
|
5498
|
+
if (force) this._clearScreen();
|
|
5428
5499
|
}
|
|
5429
5500
|
_clearScreen() {
|
|
5430
|
-
if (this._clearScreenPending == null)
|
|
5431
|
-
return;
|
|
5432
|
-
}
|
|
5501
|
+
if (this._clearScreenPending == null) return;
|
|
5433
5502
|
const log = this._clearScreenPending;
|
|
5434
|
-
this._clearScreenPending =
|
|
5503
|
+
this._clearScreenPending = void 0;
|
|
5435
5504
|
this.console.log(`${CURSOR_TO_START}${ERASE_DOWN}${log}`);
|
|
5436
5505
|
}
|
|
5437
5506
|
printError(err, options = {}) {
|
|
5438
5507
|
printError(err, this.ctx, this, options);
|
|
5439
5508
|
}
|
|
5440
5509
|
deprecate(message) {
|
|
5441
|
-
this.
|
|
5510
|
+
this.error(c.bold(c.bgYellow(" DEPRECATED ")), c.yellow(message));
|
|
5442
5511
|
}
|
|
5443
5512
|
clearHighlightCache(filename) {
|
|
5444
|
-
if (filename)
|
|
5445
|
-
|
|
5446
|
-
} else {
|
|
5447
|
-
this._highlights.clear();
|
|
5448
|
-
}
|
|
5513
|
+
if (filename) this._highlights.delete(filename);
|
|
5514
|
+
else this._highlights.clear();
|
|
5449
5515
|
}
|
|
5450
5516
|
highlight(filename, source) {
|
|
5451
|
-
if (this._highlights.has(filename))
|
|
5452
|
-
return this._highlights.get(filename);
|
|
5453
|
-
}
|
|
5517
|
+
if (this._highlights.has(filename)) return this._highlights.get(filename);
|
|
5454
5518
|
const code = highlightCode(filename, source);
|
|
5455
5519
|
this._highlights.set(filename, code);
|
|
5456
5520
|
return code;
|
|
5457
5521
|
}
|
|
5458
5522
|
printNoTestFound(filters) {
|
|
5459
5523
|
const config = this.ctx.config;
|
|
5460
|
-
if (config.watch && (config.changed || config.related?.length)) {
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
} else {
|
|
5465
|
-
if (config.passWithNoTests) {
|
|
5466
|
-
this.log(`No ${config.mode} files found, exiting with code 0\n`);
|
|
5467
|
-
} else {
|
|
5468
|
-
this.error(c.red(`No ${config.mode} files found, exiting with code 1\n`));
|
|
5469
|
-
}
|
|
5470
|
-
}
|
|
5524
|
+
if (config.watch && (config.changed || config.related?.length)) this.log(`No affected ${config.mode} files found\n`);
|
|
5525
|
+
else if (config.watch) this.log(c.red(`No ${config.mode} files found. You can change the file name pattern by pressing "p"\n`));
|
|
5526
|
+
else if (config.passWithNoTests) this.log(`No ${config.mode} files found, exiting with code 0\n`);
|
|
5527
|
+
else this.error(c.red(`No ${config.mode} files found, exiting with code 1\n`));
|
|
5471
5528
|
const comma = c.dim(", ");
|
|
5472
|
-
if (filters?.length)
|
|
5473
|
-
this.console.error(c.dim("filter: ") + c.yellow(filters.join(comma)));
|
|
5474
|
-
}
|
|
5529
|
+
if (filters?.length) this.console.error(c.dim("filter: ") + c.yellow(filters.join(comma)));
|
|
5475
5530
|
const projectsFilter = toArray(config.project);
|
|
5476
|
-
if (projectsFilter.length)
|
|
5477
|
-
this.console.error(c.dim("projects: ") + c.yellow(projectsFilter.join(comma)));
|
|
5478
|
-
}
|
|
5531
|
+
if (projectsFilter.length) this.console.error(c.dim("projects: ") + c.yellow(projectsFilter.join(comma)));
|
|
5479
5532
|
this.ctx.projects.forEach((project) => {
|
|
5480
5533
|
const config = project.config;
|
|
5481
5534
|
const printConfig = !project.isRootProject() && project.name;
|
|
5482
|
-
if (printConfig) {
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
if (config.include) {
|
|
5486
|
-
this.console.error(c.dim("include: ") + c.yellow(config.include.join(comma)));
|
|
5487
|
-
}
|
|
5488
|
-
if (config.exclude) {
|
|
5489
|
-
this.console.error(c.dim("exclude: ") + c.yellow(config.exclude.join(comma)));
|
|
5490
|
-
}
|
|
5535
|
+
if (printConfig) this.console.error(`\n${formatProjectName(project)}\n`);
|
|
5536
|
+
if (config.include) this.console.error(c.dim("include: ") + c.yellow(config.include.join(comma)));
|
|
5537
|
+
if (config.exclude) this.console.error(c.dim("exclude: ") + c.yellow(config.exclude.join(comma)));
|
|
5491
5538
|
if (config.typecheck.enabled) {
|
|
5492
5539
|
this.console.error(c.dim("typecheck include: ") + c.yellow(config.typecheck.include.join(comma)));
|
|
5493
5540
|
this.console.error(c.dim("typecheck exclude: ") + c.yellow(config.typecheck.exclude.join(comma)));
|
|
@@ -5500,9 +5547,7 @@ class Logger {
|
|
|
5500
5547
|
const color = this.ctx.config.watch ? "blue" : "cyan";
|
|
5501
5548
|
const mode = this.ctx.config.watch ? "DEV" : "RUN";
|
|
5502
5549
|
this.log(withLabel(color, mode, `v${this.ctx.version} `) + c.gray(this.ctx.config.root));
|
|
5503
|
-
if (this.ctx.config.sequence.sequencer === RandomSequencer) {
|
|
5504
|
-
this.log(PAD + c.gray(`Running tests with seed "${this.ctx.config.sequence.seed}"`));
|
|
5505
|
-
}
|
|
5550
|
+
if (this.ctx.config.sequence.sequencer === RandomSequencer) this.log(PAD + c.gray(`Running tests with seed "${this.ctx.config.sequence.seed}"`));
|
|
5506
5551
|
if (this.ctx.config.ui) {
|
|
5507
5552
|
const host = this.ctx.config.api?.host || "localhost";
|
|
5508
5553
|
const port = this.ctx.server.config.server.port;
|
|
@@ -5515,31 +5560,23 @@ class Logger {
|
|
|
5515
5560
|
const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] ?? fallbackUrl;
|
|
5516
5561
|
this.log(PAD + c.dim(c.green(`API started at ${new URL("/", origin)}`)));
|
|
5517
5562
|
}
|
|
5518
|
-
if (this.ctx.coverageProvider)
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
if (this.ctx.config.standalone) {
|
|
5522
|
-
this.log(c.yellow(`\nVitest is running in standalone mode. Edit a test file to rerun tests.`));
|
|
5523
|
-
} else {
|
|
5524
|
-
this.log();
|
|
5525
|
-
}
|
|
5563
|
+
if (this.ctx.coverageProvider) this.log(PAD + c.dim("Coverage enabled with ") + c.yellow(this.ctx.coverageProvider.name));
|
|
5564
|
+
if (this.ctx.config.standalone) this.log(c.yellow(`\nVitest is running in standalone mode. Edit a test file to rerun tests.`));
|
|
5565
|
+
else this.log();
|
|
5526
5566
|
}
|
|
5527
5567
|
printBrowserBanner(project) {
|
|
5528
|
-
if (!project.browser)
|
|
5529
|
-
return;
|
|
5530
|
-
}
|
|
5568
|
+
if (!project.browser) return;
|
|
5531
5569
|
const resolvedUrls = project.browser.vite.resolvedUrls;
|
|
5532
5570
|
const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0];
|
|
5533
|
-
if (!origin)
|
|
5534
|
-
return;
|
|
5535
|
-
}
|
|
5571
|
+
if (!origin) return;
|
|
5536
5572
|
const output = project.isRootProject() ? "" : formatProjectName(project);
|
|
5537
5573
|
const provider = project.browser.provider.name;
|
|
5538
5574
|
const providerString = provider === "preview" ? "" : ` by ${c.reset(c.bold(provider))}`;
|
|
5539
5575
|
this.log(c.dim(`${output}Browser runner started${providerString} ${c.dim("at")} ${c.blue(new URL("/", origin))}\n`));
|
|
5540
5576
|
}
|
|
5541
5577
|
printUnhandledErrors(errors) {
|
|
5542
|
-
const errorMessage = c.red(c.bold(`\nVitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run
|
|
5578
|
+
const errorMessage = c.red(c.bold(`\nVitest caught ${errors.length} unhandled error${errors.length > 1 ? "s" : ""} during the test run.
|
|
5579
|
+
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.`));
|
|
5543
5580
|
this.error(errorBanner("Unhandled Errors"));
|
|
5544
5581
|
this.error(errorMessage);
|
|
5545
5582
|
errors.forEach((err) => {
|
|
@@ -5568,17 +5605,13 @@ class Logger {
|
|
|
5568
5605
|
addCleanupListeners() {
|
|
5569
5606
|
const cleanup = () => {
|
|
5570
5607
|
this.cleanupListeners.forEach((fn) => fn());
|
|
5571
|
-
if (this.outputStream.isTTY)
|
|
5572
|
-
this.outputStream.write(SHOW_CURSOR);
|
|
5573
|
-
}
|
|
5608
|
+
if (this.outputStream.isTTY) this.outputStream.write(SHOW_CURSOR);
|
|
5574
5609
|
};
|
|
5575
5610
|
const onExit = (signal, exitCode) => {
|
|
5576
5611
|
cleanup();
|
|
5577
5612
|
// Interrupted signals don't set exit code automatically.
|
|
5578
5613
|
// Use same exit code as node: https://nodejs.org/api/process.html#signal-events
|
|
5579
|
-
if (process.exitCode ===
|
|
5580
|
-
process.exitCode = exitCode !== undefined ? 128 + exitCode : Number(signal);
|
|
5581
|
-
}
|
|
5614
|
+
if (process.exitCode === void 0) process.exitCode = exitCode !== void 0 ? 128 + exitCode : Number(signal);
|
|
5582
5615
|
process.exit();
|
|
5583
5616
|
};
|
|
5584
5617
|
process.once("SIGINT", onExit);
|
|
@@ -5614,9 +5647,7 @@ class VitestPackageInstaller {
|
|
|
5614
5647
|
return isPackageExists(name, options);
|
|
5615
5648
|
}
|
|
5616
5649
|
async ensureInstalled(dependency, root, version) {
|
|
5617
|
-
if (process.env.VITEST_SKIP_INSTALL_CHECKS)
|
|
5618
|
-
return true;
|
|
5619
|
-
}
|
|
5650
|
+
if (process.env.VITEST_SKIP_INSTALL_CHECKS) return true;
|
|
5620
5651
|
if (process.versions.pnp) {
|
|
5621
5652
|
const targetRequire = createRequire(__dirname);
|
|
5622
5653
|
try {
|
|
@@ -5624,13 +5655,9 @@ class VitestPackageInstaller {
|
|
|
5624
5655
|
return true;
|
|
5625
5656
|
} catch {}
|
|
5626
5657
|
}
|
|
5627
|
-
if (/* @__PURE__ */ isPackageExists(dependency, { paths: [root, __dirname] }))
|
|
5628
|
-
return true;
|
|
5629
|
-
}
|
|
5658
|
+
if (/* @__PURE__ */ isPackageExists(dependency, { paths: [root, __dirname] })) return true;
|
|
5630
5659
|
process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'\n\n`));
|
|
5631
|
-
if (!isTTY)
|
|
5632
|
-
return false;
|
|
5633
|
-
}
|
|
5660
|
+
if (!isTTY) return false;
|
|
5634
5661
|
const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; });
|
|
5635
5662
|
const { install } = await prompts.default({
|
|
5636
5663
|
type: "confirm",
|
|
@@ -5693,8 +5720,8 @@ function serializeConfig(config, coreConfig, viteConfig) {
|
|
|
5693
5720
|
reportsDirectory: coverage.reportsDirectory,
|
|
5694
5721
|
provider: coverage.provider,
|
|
5695
5722
|
enabled: coverage.enabled,
|
|
5696
|
-
htmlReporter: htmlReporter ? { subdir } :
|
|
5697
|
-
customProviderModule: "customProviderModule" in coverage ? coverage.customProviderModule :
|
|
5723
|
+
htmlReporter: htmlReporter ? { subdir } : void 0,
|
|
5724
|
+
customProviderModule: "customProviderModule" in coverage ? coverage.customProviderModule : void 0
|
|
5698
5725
|
};
|
|
5699
5726
|
})(config.coverage),
|
|
5700
5727
|
fakeTimers: config.fakeTimers,
|
|
@@ -5720,11 +5747,11 @@ function serializeConfig(config, coreConfig, viteConfig) {
|
|
|
5720
5747
|
moduleDirectories: config.deps.moduleDirectories
|
|
5721
5748
|
},
|
|
5722
5749
|
snapshotOptions: {
|
|
5723
|
-
snapshotEnvironment:
|
|
5750
|
+
snapshotEnvironment: void 0,
|
|
5724
5751
|
updateSnapshot: coreConfig.snapshotOptions.updateSnapshot,
|
|
5725
5752
|
snapshotFormat: {
|
|
5726
5753
|
...coreConfig.snapshotOptions.snapshotFormat,
|
|
5727
|
-
compareKeys:
|
|
5754
|
+
compareKeys: void 0
|
|
5728
5755
|
},
|
|
5729
5756
|
expand: config.snapshotOptions.expand ?? coreConfig.snapshotOptions.expand
|
|
5730
5757
|
},
|
|
@@ -5773,25 +5800,17 @@ async function loadGlobalSetupFile(file, runner) {
|
|
|
5773
5800
|
"default",
|
|
5774
5801
|
"setup",
|
|
5775
5802
|
"teardown"
|
|
5776
|
-
]) {
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
}
|
|
5781
|
-
if (m.
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
return {
|
|
5788
|
-
file,
|
|
5789
|
-
setup: m.setup,
|
|
5790
|
-
teardown: m.teardown
|
|
5791
|
-
};
|
|
5792
|
-
} else {
|
|
5793
|
-
throw new Error(`invalid globalSetup file ${file}. Must export setup, teardown or have a default export`);
|
|
5794
|
-
}
|
|
5803
|
+
]) if (m[exp] != null && typeof m[exp] !== "function") throw new Error(`invalid export in globalSetup file ${file}: ${exp} must be a function`);
|
|
5804
|
+
if (m.default) return {
|
|
5805
|
+
file,
|
|
5806
|
+
setup: m.default
|
|
5807
|
+
};
|
|
5808
|
+
else if (m.setup || m.teardown) return {
|
|
5809
|
+
file,
|
|
5810
|
+
setup: m.setup,
|
|
5811
|
+
teardown: m.teardown
|
|
5812
|
+
};
|
|
5813
|
+
else throw new Error(`invalid globalSetup file ${file}. Must export setup, teardown or have a default export`);
|
|
5795
5814
|
}
|
|
5796
5815
|
|
|
5797
5816
|
function CoverageTransform(ctx) {
|
|
@@ -5807,12 +5826,8 @@ function MocksPlugins(options = {}) {
|
|
|
5807
5826
|
const normalizedDistDir = normalize(distDir);
|
|
5808
5827
|
return [hoistMocksPlugin({
|
|
5809
5828
|
filter(id) {
|
|
5810
|
-
if (id.includes(normalizedDistDir))
|
|
5811
|
-
|
|
5812
|
-
}
|
|
5813
|
-
if (options.filter) {
|
|
5814
|
-
return options.filter(id);
|
|
5815
|
-
}
|
|
5829
|
+
if (id.includes(normalizedDistDir)) return false;
|
|
5830
|
+
if (options.filter) return options.filter(id);
|
|
5816
5831
|
return true;
|
|
5817
5832
|
},
|
|
5818
5833
|
codeFrameGenerator(node, id, code) {
|
|
@@ -5822,16 +5837,12 @@ function MocksPlugins(options = {}) {
|
|
|
5822
5837
|
}
|
|
5823
5838
|
|
|
5824
5839
|
function generateCssFilenameHash(filepath) {
|
|
5825
|
-
return hash("
|
|
5840
|
+
return hash("sha1", filepath, "hex").slice(0, 6);
|
|
5826
5841
|
}
|
|
5827
5842
|
function generateScopedClassName(strategy, name, filename) {
|
|
5828
5843
|
// should be configured by Vite defaults
|
|
5829
|
-
if (strategy === "scoped")
|
|
5830
|
-
|
|
5831
|
-
}
|
|
5832
|
-
if (strategy === "non-scoped") {
|
|
5833
|
-
return name;
|
|
5834
|
-
}
|
|
5844
|
+
if (strategy === "scoped") return null;
|
|
5845
|
+
if (strategy === "non-scoped") return name;
|
|
5835
5846
|
const hash = generateCssFilenameHash(filename);
|
|
5836
5847
|
return `_${name}_${hash}`;
|
|
5837
5848
|
}
|
|
@@ -5854,7 +5865,7 @@ let sameCount = 0;
|
|
|
5854
5865
|
// reuse it across all loggers
|
|
5855
5866
|
let timeFormatter;
|
|
5856
5867
|
function getTimeFormatter() {
|
|
5857
|
-
timeFormatter ??= new Intl.DateTimeFormat(
|
|
5868
|
+
timeFormatter ??= new Intl.DateTimeFormat(void 0, {
|
|
5858
5869
|
hour: "numeric",
|
|
5859
5870
|
minute: "numeric",
|
|
5860
5871
|
second: "numeric"
|
|
@@ -5866,7 +5877,7 @@ function getTimeFormatter() {
|
|
|
5866
5877
|
// When Vitest supports only Vite 6 and above, we can use Vite's `createLogger({ console })`
|
|
5867
5878
|
// https://github.com/vitejs/vite/pull/18379
|
|
5868
5879
|
function createViteLogger(console, level = "info", options = {}) {
|
|
5869
|
-
const loggedErrors = new WeakSet();
|
|
5880
|
+
const loggedErrors = /* @__PURE__ */ new WeakSet();
|
|
5870
5881
|
const { prefix = "[vite]", allowClearScreen = true } = options;
|
|
5871
5882
|
const thresh = LogLevels[level];
|
|
5872
5883
|
const canClearScreen = allowClearScreen && process.stdout.isTTY && !process.env.CI;
|
|
@@ -5874,45 +5885,32 @@ function createViteLogger(console, level = "info", options = {}) {
|
|
|
5874
5885
|
function format(type, msg, options = {}) {
|
|
5875
5886
|
if (options.timestamp) {
|
|
5876
5887
|
let tag = "";
|
|
5877
|
-
if (type === "info")
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
tag = c.yellow(c.bold(prefix));
|
|
5881
|
-
} else {
|
|
5882
|
-
tag = c.red(c.bold(prefix));
|
|
5883
|
-
}
|
|
5888
|
+
if (type === "info") tag = c.cyan(c.bold(prefix));
|
|
5889
|
+
else if (type === "warn") tag = c.yellow(c.bold(prefix));
|
|
5890
|
+
else tag = c.red(c.bold(prefix));
|
|
5884
5891
|
const environment = options.environment ? `${options.environment} ` : "";
|
|
5885
|
-
return `${c.dim(getTimeFormatter().format(new Date()))} ${tag} ${environment}${msg}`;
|
|
5886
|
-
} else
|
|
5887
|
-
return msg;
|
|
5888
|
-
}
|
|
5892
|
+
return `${c.dim(getTimeFormatter().format(/* @__PURE__ */ new Date()))} ${tag} ${environment}${msg}`;
|
|
5893
|
+
} else return msg;
|
|
5889
5894
|
}
|
|
5890
5895
|
function output(type, msg, options = {}) {
|
|
5891
5896
|
if (thresh >= LogLevels[type]) {
|
|
5892
5897
|
const method = type === "info" ? "log" : type;
|
|
5893
|
-
if (options.error)
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
sameCount++;
|
|
5899
|
-
clear(console);
|
|
5900
|
-
console[method](format(type, msg, options), c.yellow(`(x${sameCount + 1})`));
|
|
5901
|
-
} else {
|
|
5902
|
-
sameCount = 0;
|
|
5903
|
-
lastMsg = msg;
|
|
5904
|
-
lastType = type;
|
|
5905
|
-
if (options.clear) {
|
|
5906
|
-
clear(console);
|
|
5907
|
-
}
|
|
5908
|
-
console[method](format(type, msg, options));
|
|
5909
|
-
}
|
|
5898
|
+
if (options.error) loggedErrors.add(options.error);
|
|
5899
|
+
if (canClearScreen) if (type === lastType && msg === lastMsg) {
|
|
5900
|
+
sameCount++;
|
|
5901
|
+
clear(console);
|
|
5902
|
+
console[method](format(type, msg, options), c.yellow(`(x${sameCount + 1})`));
|
|
5910
5903
|
} else {
|
|
5904
|
+
sameCount = 0;
|
|
5905
|
+
lastMsg = msg;
|
|
5906
|
+
lastType = type;
|
|
5907
|
+
if (options.clear) clear(console);
|
|
5911
5908
|
console[method](format(type, msg, options));
|
|
5912
5909
|
}
|
|
5910
|
+
else console[method](format(type, msg, options));
|
|
5913
5911
|
}
|
|
5914
5912
|
}
|
|
5915
|
-
const warnedMessages = new Set();
|
|
5913
|
+
const warnedMessages = /* @__PURE__ */ new Set();
|
|
5916
5914
|
const logger = {
|
|
5917
5915
|
hasWarned: false,
|
|
5918
5916
|
info(msg, opts) {
|
|
@@ -5923,9 +5921,7 @@ function createViteLogger(console, level = "info", options = {}) {
|
|
|
5923
5921
|
output("warn", msg, opts);
|
|
5924
5922
|
},
|
|
5925
5923
|
warnOnce(msg, opts) {
|
|
5926
|
-
if (warnedMessages.has(msg))
|
|
5927
|
-
return;
|
|
5928
|
-
}
|
|
5924
|
+
if (warnedMessages.has(msg)) return;
|
|
5929
5925
|
logger.hasWarned = true;
|
|
5930
5926
|
output("warn", msg, opts);
|
|
5931
5927
|
warnedMessages.add(msg);
|
|
@@ -5935,9 +5931,7 @@ function createViteLogger(console, level = "info", options = {}) {
|
|
|
5935
5931
|
output("error", msg, opts);
|
|
5936
5932
|
},
|
|
5937
5933
|
clearScreen(type) {
|
|
5938
|
-
if (thresh >= LogLevels[type])
|
|
5939
|
-
clear(console);
|
|
5940
|
-
}
|
|
5934
|
+
if (thresh >= LogLevels[type]) clear(console);
|
|
5941
5935
|
},
|
|
5942
5936
|
hasErrorLogged(error) {
|
|
5943
5937
|
return loggedErrors.has(error);
|
|
@@ -5950,9 +5944,7 @@ function silenceImportViteIgnoreWarning(logger) {
|
|
|
5950
5944
|
return {
|
|
5951
5945
|
...logger,
|
|
5952
5946
|
warn(msg, options) {
|
|
5953
|
-
if (msg.includes("The above dynamic import cannot be analyzed by Vite"))
|
|
5954
|
-
return;
|
|
5955
|
-
}
|
|
5947
|
+
if (msg.includes("The above dynamic import cannot be analyzed by Vite")) return;
|
|
5956
5948
|
logger.warn(msg, options);
|
|
5957
5949
|
}
|
|
5958
5950
|
};
|
|
@@ -5974,46 +5966,32 @@ function isInline(id) {
|
|
|
5974
5966
|
return cssInlineRE.test(id);
|
|
5975
5967
|
}
|
|
5976
5968
|
function getCSSModuleProxyReturn(strategy, filename) {
|
|
5977
|
-
if (strategy === "non-scoped")
|
|
5978
|
-
return "style";
|
|
5979
|
-
}
|
|
5969
|
+
if (strategy === "non-scoped") return "style";
|
|
5980
5970
|
const hash = generateCssFilenameHash(filename);
|
|
5981
5971
|
return `\`_\${style}_${hash}\``;
|
|
5982
5972
|
}
|
|
5983
5973
|
function CSSEnablerPlugin(ctx) {
|
|
5984
5974
|
const shouldProcessCSS = (id) => {
|
|
5985
5975
|
const { css } = ctx.config;
|
|
5986
|
-
if (typeof css === "boolean")
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
if (toArray(css.exclude).some((re) => re.test(id))) {
|
|
5990
|
-
return false;
|
|
5991
|
-
}
|
|
5992
|
-
if (toArray(css.include).some((re) => re.test(id))) {
|
|
5993
|
-
return true;
|
|
5994
|
-
}
|
|
5976
|
+
if (typeof css === "boolean") return css;
|
|
5977
|
+
if (toArray(css.exclude).some((re) => re.test(id))) return false;
|
|
5978
|
+
if (toArray(css.include).some((re) => re.test(id))) return true;
|
|
5995
5979
|
return false;
|
|
5996
5980
|
};
|
|
5997
5981
|
return [{
|
|
5998
5982
|
name: "vitest:css-disable",
|
|
5999
5983
|
enforce: "pre",
|
|
6000
5984
|
transform(code, id) {
|
|
6001
|
-
if (!isCSS(id))
|
|
6002
|
-
return;
|
|
6003
|
-
}
|
|
5985
|
+
if (!isCSS(id)) return;
|
|
6004
5986
|
// css plugin inside Vite won't do anything if the code is empty
|
|
6005
5987
|
// but it will put __vite__updateStyle anyway
|
|
6006
|
-
if (!shouldProcessCSS(id)) {
|
|
6007
|
-
return { code: "" };
|
|
6008
|
-
}
|
|
5988
|
+
if (!shouldProcessCSS(id)) return { code: "" };
|
|
6009
5989
|
}
|
|
6010
5990
|
}, {
|
|
6011
5991
|
name: "vitest:css-empty-post",
|
|
6012
5992
|
enforce: "post",
|
|
6013
5993
|
transform(_, id) {
|
|
6014
|
-
if (!isCSS(id) || shouldProcessCSS(id))
|
|
6015
|
-
return;
|
|
6016
|
-
}
|
|
5994
|
+
if (!isCSS(id) || shouldProcessCSS(id)) return;
|
|
6017
5995
|
if (isCSSModule(id) && !isInline(id)) {
|
|
6018
5996
|
// return proxy for css modules, so that imported module has names:
|
|
6019
5997
|
// styles.foo returns a "foo" instead of "undefined"
|
|
@@ -6516,7 +6494,7 @@ function stripLiteralDetailed(code, options) {
|
|
|
6516
6494
|
return stripLiteralJsTokens(code);
|
|
6517
6495
|
}
|
|
6518
6496
|
|
|
6519
|
-
const metaUrlLength =
|
|
6497
|
+
const metaUrlLength = 15;
|
|
6520
6498
|
const locationString = "self.location".padEnd(metaUrlLength, " ");
|
|
6521
6499
|
// Vite transforms new URL('./path', import.meta.url) to new URL('/path.js', import.meta.url)
|
|
6522
6500
|
// This makes "href" equal to "http://localhost:3000/path.js" in the browser, but if we keep it like this,
|
|
@@ -6528,9 +6506,7 @@ function NormalizeURLPlugin() {
|
|
|
6528
6506
|
enforce: "post",
|
|
6529
6507
|
transform(code, id, options) {
|
|
6530
6508
|
const ssr = options?.ssr === true;
|
|
6531
|
-
if (ssr || !code.includes("new URL") || !code.includes("import.meta.url"))
|
|
6532
|
-
return;
|
|
6533
|
-
}
|
|
6509
|
+
if (ssr || !code.includes("new URL") || !code.includes("import.meta.url")) return;
|
|
6534
6510
|
const cleanString = stripLiteral(code);
|
|
6535
6511
|
const assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*(?:'[^']+'|"[^"]+"|`[^`]+`)\s*,\s*(?:'' \+ )?import\.meta\.url\s*(?:,\s*)?\)/g;
|
|
6536
6512
|
let updatedCode = code;
|
|
@@ -6549,24 +6525,20 @@ function NormalizeURLPlugin() {
|
|
|
6549
6525
|
};
|
|
6550
6526
|
}
|
|
6551
6527
|
|
|
6552
|
-
function resolveOptimizerConfig(_testOptions, viteOptions
|
|
6528
|
+
function resolveOptimizerConfig(_testOptions, viteOptions) {
|
|
6553
6529
|
const testOptions = _testOptions || {};
|
|
6554
6530
|
const newConfig = {};
|
|
6555
6531
|
const [major, minor, fix] = version.split(".").map(Number);
|
|
6556
6532
|
const allowed = major >= 5 || major === 4 && minor >= 4 || major === 4 && minor === 3 && fix >= 2;
|
|
6557
|
-
if (!allowed && testOptions?.enabled === true) {
|
|
6558
|
-
|
|
6559
|
-
} else {
|
|
6560
|
-
testOptions.enabled ??= false;
|
|
6561
|
-
}
|
|
6533
|
+
if (!allowed && testOptions?.enabled === true) console.warn(`Vitest: "deps.optimizer" is only available in Vite >= 4.3.2, current Vite version: ${version}`);
|
|
6534
|
+
else testOptions.enabled ??= false;
|
|
6562
6535
|
if (!allowed || testOptions?.enabled !== true) {
|
|
6563
|
-
newConfig.cacheDir =
|
|
6536
|
+
newConfig.cacheDir = void 0;
|
|
6564
6537
|
newConfig.optimizeDeps = {
|
|
6565
6538
|
disabled: true,
|
|
6566
6539
|
entries: []
|
|
6567
6540
|
};
|
|
6568
6541
|
} else {
|
|
6569
|
-
const root = testConfig.root ?? process.cwd();
|
|
6570
6542
|
const currentInclude = testOptions.include || viteOptions?.include || [];
|
|
6571
6543
|
const exclude = [
|
|
6572
6544
|
"vitest",
|
|
@@ -6577,8 +6549,6 @@ function resolveOptimizerConfig(_testOptions, viteOptions, testConfig, viteCache
|
|
|
6577
6549
|
const runtime = currentInclude.filter((n) => n.endsWith("jsx-dev-runtime") || n.endsWith("jsx-runtime"));
|
|
6578
6550
|
exclude.push(...runtime);
|
|
6579
6551
|
const include = (testOptions.include || viteOptions?.include || []).filter((n) => !exclude.includes(n));
|
|
6580
|
-
const projectName = typeof testConfig.name === "string" ? testConfig.name : testConfig.name?.label;
|
|
6581
|
-
newConfig.cacheDir = testConfig.cache !== false && testConfig.cache?.dir || VitestCache.resolveCacheDir(root, viteCacheDir, projectName);
|
|
6582
6552
|
newConfig.optimizeDeps = {
|
|
6583
6553
|
...viteOptions,
|
|
6584
6554
|
...testOptions,
|
|
@@ -6619,11 +6589,11 @@ function deleteDefineConfig(viteConfig) {
|
|
|
6619
6589
|
continue;
|
|
6620
6590
|
}
|
|
6621
6591
|
if (key.startsWith("import.meta.env.")) {
|
|
6622
|
-
const envKey = key.slice(
|
|
6592
|
+
const envKey = key.slice(16);
|
|
6623
6593
|
process.env[envKey] = replacement;
|
|
6624
6594
|
delete viteConfig.define[key];
|
|
6625
6595
|
} else if (key.startsWith("process.env.")) {
|
|
6626
|
-
const envKey = key.slice(
|
|
6596
|
+
const envKey = key.slice(12);
|
|
6627
6597
|
process.env[envKey] = replacement;
|
|
6628
6598
|
delete viteConfig.define[key];
|
|
6629
6599
|
} else if (!key.includes(".")) {
|
|
@@ -6634,9 +6604,7 @@ function deleteDefineConfig(viteConfig) {
|
|
|
6634
6604
|
return defines;
|
|
6635
6605
|
}
|
|
6636
6606
|
function resolveFsAllow(projectRoot, rootConfigFile) {
|
|
6637
|
-
if (!rootConfigFile)
|
|
6638
|
-
return [searchForWorkspaceRoot(projectRoot), rootDir];
|
|
6639
|
-
}
|
|
6607
|
+
if (!rootConfigFile) return [searchForWorkspaceRoot(projectRoot), rootDir];
|
|
6640
6608
|
return [
|
|
6641
6609
|
dirname(rootConfigFile),
|
|
6642
6610
|
searchForWorkspaceRoot(projectRoot),
|
|
@@ -6665,9 +6633,12 @@ function VitestOptimizer() {
|
|
|
6665
6633
|
order: "post",
|
|
6666
6634
|
handler(viteConfig) {
|
|
6667
6635
|
const testConfig = viteConfig.test || {};
|
|
6668
|
-
const webOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.web, viteConfig.optimizeDeps
|
|
6669
|
-
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.ssr, viteConfig.ssr?.optimizeDeps
|
|
6670
|
-
|
|
6636
|
+
const webOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.web, viteConfig.optimizeDeps);
|
|
6637
|
+
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.ssr, viteConfig.ssr?.optimizeDeps);
|
|
6638
|
+
const root = resolve(viteConfig.root || process.cwd());
|
|
6639
|
+
const name = viteConfig.test?.name;
|
|
6640
|
+
const label = typeof name === "string" ? name : name?.label || "";
|
|
6641
|
+
viteConfig.cacheDir = VitestCache.resolveCacheDir(resolve(root || process.cwd()), testConfig.cache != null && testConfig.cache !== false ? testConfig.cache.dir : viteConfig.cacheDir, label);
|
|
6671
6642
|
viteConfig.optimizeDeps = webOptimizer.optimizeDeps;
|
|
6672
6643
|
viteConfig.ssr ??= {};
|
|
6673
6644
|
viteConfig.ssr.optimizeDeps = ssrOptimizer.optimizeDeps;
|
|
@@ -6683,9 +6654,7 @@ function SsrReplacerPlugin() {
|
|
|
6683
6654
|
name: "vitest:ssr-replacer",
|
|
6684
6655
|
enforce: "pre",
|
|
6685
6656
|
transform(code, id) {
|
|
6686
|
-
if (!/\bimport\.meta\.env\b/.test(code))
|
|
6687
|
-
return null;
|
|
6688
|
-
}
|
|
6657
|
+
if (!/\bimport\.meta\.env\b/.test(code)) return null;
|
|
6689
6658
|
let s = null;
|
|
6690
6659
|
const cleanCode = stripLiteral(code);
|
|
6691
6660
|
const envs = cleanCode.matchAll(/\bimport\.meta\.env\b/g);
|
|
@@ -6695,15 +6664,13 @@ function SsrReplacerPlugin() {
|
|
|
6695
6664
|
const endIndex = startIndex + env[0].length;
|
|
6696
6665
|
s.overwrite(startIndex, endIndex, "__vite_ssr_import_meta__.env");
|
|
6697
6666
|
}
|
|
6698
|
-
if (s) {
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
};
|
|
6706
|
-
}
|
|
6667
|
+
if (s) return {
|
|
6668
|
+
code: s.toString(),
|
|
6669
|
+
map: s.generateMap({
|
|
6670
|
+
hires: "boundary",
|
|
6671
|
+
source: cleanUrl(id)
|
|
6672
|
+
})
|
|
6673
|
+
};
|
|
6707
6674
|
}
|
|
6708
6675
|
};
|
|
6709
6676
|
}
|
|
@@ -6716,7 +6683,7 @@ function VitestProjectResolver(ctx) {
|
|
|
6716
6683
|
if (id === "vitest" || id.startsWith("@vitest/") || id.startsWith("vitest/")) {
|
|
6717
6684
|
// always redirect the request to the root vitest plugin since
|
|
6718
6685
|
// it will be the one used to run Vitest
|
|
6719
|
-
const resolved = await ctx.server.pluginContainer.resolveId(id,
|
|
6686
|
+
const resolved = await ctx.server.pluginContainer.resolveId(id, void 0, {
|
|
6720
6687
|
skip: new Set([plugin]),
|
|
6721
6688
|
ssr
|
|
6722
6689
|
});
|
|
@@ -6731,13 +6698,10 @@ function VitestCoreResolver(ctx) {
|
|
|
6731
6698
|
name: "vitest:resolve-core",
|
|
6732
6699
|
enforce: "pre",
|
|
6733
6700
|
async resolveId(id) {
|
|
6734
|
-
if (id === "vitest")
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
// ignore actual importer, we want it to be resolved relative to the root
|
|
6739
|
-
return this.resolve(id, join(ctx.config.root, "index.html"), { skipSelf: true });
|
|
6740
|
-
}
|
|
6701
|
+
if (id === "vitest") return resolve(distDir, "index.js");
|
|
6702
|
+
if (id.startsWith("@vitest/") || id.startsWith("vitest/"))
|
|
6703
|
+
// ignore actual importer, we want it to be resolved relative to the root
|
|
6704
|
+
return this.resolve(id, join(ctx.config.root, "index.html"), { skipSelf: true });
|
|
6741
6705
|
}
|
|
6742
6706
|
};
|
|
6743
6707
|
}
|
|
@@ -6746,7 +6710,7 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6746
6710
|
return [
|
|
6747
6711
|
{
|
|
6748
6712
|
name: "vitest:project",
|
|
6749
|
-
enforce: "
|
|
6713
|
+
enforce: "post",
|
|
6750
6714
|
options() {
|
|
6751
6715
|
this.meta.watchMode = false;
|
|
6752
6716
|
},
|
|
@@ -6758,21 +6722,13 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6758
6722
|
label: "",
|
|
6759
6723
|
...testConfig.name
|
|
6760
6724
|
};
|
|
6761
|
-
if (!name) {
|
|
6762
|
-
if
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
}
|
|
6769
|
-
if (typeof name !== "string" || !name) {
|
|
6770
|
-
name = basename(dir);
|
|
6771
|
-
}
|
|
6772
|
-
} else {
|
|
6773
|
-
name = options.workspacePath.toString();
|
|
6774
|
-
}
|
|
6775
|
-
}
|
|
6725
|
+
if (!name) if (typeof options.workspacePath === "string") {
|
|
6726
|
+
// if there is a package.json, read the name from it
|
|
6727
|
+
const dir = options.workspacePath.endsWith("/") ? options.workspacePath.slice(0, -1) : dirname(options.workspacePath);
|
|
6728
|
+
const pkgJsonPath = resolve(dir, "package.json");
|
|
6729
|
+
if (existsSync(pkgJsonPath)) name = JSON.parse(readFileSync(pkgJsonPath, "utf-8")).name;
|
|
6730
|
+
if (typeof name !== "string" || !name) name = basename(dir);
|
|
6731
|
+
} else name = options.workspacePath.toString();
|
|
6776
6732
|
const resolveOptions = getDefaultResolveOptions();
|
|
6777
6733
|
const config = {
|
|
6778
6734
|
root,
|
|
@@ -6807,16 +6763,13 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6807
6763
|
// keep project names to potentially filter it out
|
|
6808
6764
|
const workspaceNames = [name];
|
|
6809
6765
|
const browser = viteConfig.test.browser || {};
|
|
6810
|
-
if (isBrowserEnabled && browser.name && !browser.instances?.length)
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
}
|
|
6766
|
+
if (isBrowserEnabled && browser.name && !browser.instances?.length)
|
|
6767
|
+
// vitest injects `instances` in this case later on
|
|
6768
|
+
workspaceNames.push(name ? `${name} (${browser.name})` : browser.name);
|
|
6814
6769
|
viteConfig.test?.browser?.instances?.forEach((instance) => {
|
|
6815
6770
|
// every instance is a potential project
|
|
6816
6771
|
instance.name ??= name ? `${name} (${instance.browser})` : instance.browser;
|
|
6817
|
-
if (isBrowserEnabled)
|
|
6818
|
-
workspaceNames.push(instance.name);
|
|
6819
|
-
}
|
|
6772
|
+
if (isBrowserEnabled) workspaceNames.push(instance.name);
|
|
6820
6773
|
});
|
|
6821
6774
|
const filters = project.vitest.config.project;
|
|
6822
6775
|
// if there is `--project=...` filter, check if any of the potential projects match
|
|
@@ -6826,20 +6779,16 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6826
6779
|
const hasProject = workspaceNames.some((name) => {
|
|
6827
6780
|
return project.vitest.matchesProjectFilter(name);
|
|
6828
6781
|
});
|
|
6829
|
-
if (!hasProject)
|
|
6830
|
-
throw new VitestFilteredOutProjectError();
|
|
6831
|
-
}
|
|
6782
|
+
if (!hasProject) throw new VitestFilteredOutProjectError();
|
|
6832
6783
|
}
|
|
6833
6784
|
const classNameStrategy = typeof testConfig.css !== "boolean" && testConfig.css?.modules?.classNameStrategy || "stable";
|
|
6834
6785
|
if (classNameStrategy !== "scoped") {
|
|
6835
6786
|
config.css ??= {};
|
|
6836
6787
|
config.css.modules ??= {};
|
|
6837
|
-
if (config.css.modules) {
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
};
|
|
6842
|
-
}
|
|
6788
|
+
if (config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
|
|
6789
|
+
const root = project.config.root;
|
|
6790
|
+
return generateScopedClassName(classNameStrategy, name, relative(root, filename));
|
|
6791
|
+
};
|
|
6843
6792
|
}
|
|
6844
6793
|
config.customLogger = createViteLogger(project.vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false });
|
|
6845
6794
|
config.customLogger = silenceImportViteIgnoreWarning(config.customLogger);
|
|
@@ -6853,9 +6802,9 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
6853
6802
|
},
|
|
6854
6803
|
SsrReplacerPlugin(),
|
|
6855
6804
|
...CSSEnablerPlugin(project),
|
|
6856
|
-
CoverageTransform(project.
|
|
6805
|
+
CoverageTransform(project.vitest),
|
|
6857
6806
|
...MocksPlugins(),
|
|
6858
|
-
VitestProjectResolver(project.
|
|
6807
|
+
VitestProjectResolver(project.vitest),
|
|
6859
6808
|
VitestOptimizer(),
|
|
6860
6809
|
NormalizeURLPlugin()
|
|
6861
6810
|
];
|
|
@@ -6912,9 +6861,7 @@ class TestSpecification {
|
|
|
6912
6861
|
*/
|
|
6913
6862
|
get testModule() {
|
|
6914
6863
|
const task = this.project.vitest.state.idMap.get(this.taskId);
|
|
6915
|
-
if (!task)
|
|
6916
|
-
return undefined;
|
|
6917
|
-
}
|
|
6864
|
+
if (!task) return void 0;
|
|
6918
6865
|
return this.project.vitest.state.getReportedEntity(task);
|
|
6919
6866
|
}
|
|
6920
6867
|
toJSON() {
|
|
@@ -6946,9 +6893,7 @@ async function createViteServer(inlineConfig) {
|
|
|
6946
6893
|
// But Vitest works correctly either way
|
|
6947
6894
|
const error = console.error;
|
|
6948
6895
|
console.error = (...args) => {
|
|
6949
|
-
if (typeof args[0] === "string" && args[0].includes("WebSocket server error:"))
|
|
6950
|
-
return;
|
|
6951
|
-
}
|
|
6896
|
+
if (typeof args[0] === "string" && args[0].includes("WebSocket server error:")) return;
|
|
6952
6897
|
error(...args);
|
|
6953
6898
|
};
|
|
6954
6899
|
const server = await createServer(inlineConfig);
|
|
@@ -7000,9 +6945,7 @@ class TestProject {
|
|
|
7000
6945
|
* It is based on the root of the project (not consistent between OS) and its name.
|
|
7001
6946
|
*/
|
|
7002
6947
|
get hash() {
|
|
7003
|
-
if (!this._hash)
|
|
7004
|
-
throw new Error("The server was not set. It means that `project.hash` was called before the Vite server was established.");
|
|
7005
|
-
}
|
|
6948
|
+
if (!this._hash) throw new Error("The server was not set. It means that `project.hash` was called before the Vite server was established.");
|
|
7006
6949
|
return this._hash;
|
|
7007
6950
|
}
|
|
7008
6951
|
// "provide" is a property, not a method to keep the context when destructed in the global setup,
|
|
@@ -7023,9 +6966,7 @@ class TestProject {
|
|
|
7023
6966
|
* Get the provided context. The project context is merged with the global context.
|
|
7024
6967
|
*/
|
|
7025
6968
|
getProvidedContext() {
|
|
7026
|
-
if (this.isRootProject())
|
|
7027
|
-
return this._provided;
|
|
7028
|
-
}
|
|
6969
|
+
if (this.isRootProject()) return this._provided;
|
|
7029
6970
|
// globalSetup can run even if core workspace is not part of the test run
|
|
7030
6971
|
// so we need to inherit its provided context
|
|
7031
6972
|
return {
|
|
@@ -7051,9 +6992,7 @@ class TestProject {
|
|
|
7051
6992
|
* Vite's dev server instance. Every workspace project has its own server.
|
|
7052
6993
|
*/
|
|
7053
6994
|
get vite() {
|
|
7054
|
-
if (!this._vite)
|
|
7055
|
-
throw new Error("The server was not set. It means that `project.vite` was called before the Vite server was established.");
|
|
7056
|
-
}
|
|
6995
|
+
if (!this._vite) throw new Error("The server was not set. It means that `project.vite` was called before the Vite server was established.");
|
|
7057
6996
|
// checking it once should be enough
|
|
7058
6997
|
Object.defineProperty(this, "vite", {
|
|
7059
6998
|
configurable: true,
|
|
@@ -7066,9 +7005,7 @@ class TestProject {
|
|
|
7066
7005
|
* Resolved project configuration.
|
|
7067
7006
|
*/
|
|
7068
7007
|
get config() {
|
|
7069
|
-
if (!this._config)
|
|
7070
|
-
throw new Error("The config was not set. It means that `project.config` was called before the Vite server was established.");
|
|
7071
|
-
}
|
|
7008
|
+
if (!this._config) throw new Error("The config was not set. It means that `project.config` was called before the Vite server was established.");
|
|
7072
7009
|
// checking it once should be enough
|
|
7073
7010
|
// Object.defineProperty(this, 'config', {
|
|
7074
7011
|
// configurable: true,
|
|
@@ -7119,18 +7056,12 @@ class TestProject {
|
|
|
7119
7056
|
}
|
|
7120
7057
|
/** @internal */
|
|
7121
7058
|
async _initializeGlobalSetup() {
|
|
7122
|
-
if (this._globalSetups)
|
|
7123
|
-
return;
|
|
7124
|
-
}
|
|
7059
|
+
if (this._globalSetups) return;
|
|
7125
7060
|
this._globalSetups = await loadGlobalSetupFiles(this.runner, this.config.globalSetup);
|
|
7126
7061
|
for (const globalSetupFile of this._globalSetups) {
|
|
7127
7062
|
const teardown = await globalSetupFile.setup?.(this);
|
|
7128
|
-
if (teardown == null || !!globalSetupFile.teardown)
|
|
7129
|
-
|
|
7130
|
-
}
|
|
7131
|
-
if (typeof teardown !== "function") {
|
|
7132
|
-
throw new TypeError(`invalid return value in globalSetup file ${globalSetupFile.file}. Must return a function`);
|
|
7133
|
-
}
|
|
7063
|
+
if (teardown == null || !!globalSetupFile.teardown) continue;
|
|
7064
|
+
if (typeof teardown !== "function") throw new TypeError(`invalid return value in globalSetup file ${globalSetupFile.file}. Must return a function`);
|
|
7134
7065
|
globalSetupFile.teardown = teardown;
|
|
7135
7066
|
}
|
|
7136
7067
|
}
|
|
@@ -7143,12 +7074,8 @@ class TestProject {
|
|
|
7143
7074
|
}
|
|
7144
7075
|
/** @internal */
|
|
7145
7076
|
async _teardownGlobalSetup() {
|
|
7146
|
-
if (!this._globalSetups)
|
|
7147
|
-
|
|
7148
|
-
}
|
|
7149
|
-
for (const globalSetupFile of [...this._globalSetups].reverse()) {
|
|
7150
|
-
await globalSetupFile.teardown?.();
|
|
7151
|
-
}
|
|
7077
|
+
if (!this._globalSetups) return;
|
|
7078
|
+
for (const globalSetupFile of [...this._globalSetups].reverse()) await globalSetupFile.teardown?.();
|
|
7152
7079
|
}
|
|
7153
7080
|
/** @deprecated use `vitest.logger` instead */
|
|
7154
7081
|
get logger() {
|
|
@@ -7158,7 +7085,7 @@ class TestProject {
|
|
|
7158
7085
|
/** @deprecated use `.vite` or `.browser.vite` directly */
|
|
7159
7086
|
getModulesByFilepath(file) {
|
|
7160
7087
|
const set = this.server.moduleGraph.getModulesByFile(file) || this.browser?.vite.moduleGraph.getModulesByFile(file);
|
|
7161
|
-
return set || new Set();
|
|
7088
|
+
return set || /* @__PURE__ */ new Set();
|
|
7162
7089
|
}
|
|
7163
7090
|
/** @deprecated use `.vite` or `.browser.vite` directly */
|
|
7164
7091
|
getModuleById(id) {
|
|
@@ -7189,18 +7116,14 @@ class TestProject {
|
|
|
7189
7116
|
};
|
|
7190
7117
|
}
|
|
7191
7118
|
async globAllTestFiles(include, exclude, includeSource, cwd) {
|
|
7192
|
-
if (this.testFilesList)
|
|
7193
|
-
return this.testFilesList;
|
|
7194
|
-
}
|
|
7119
|
+
if (this.testFilesList) return this.testFilesList;
|
|
7195
7120
|
const testFiles = await this.globFiles(include, exclude, cwd);
|
|
7196
7121
|
if (includeSource?.length) {
|
|
7197
7122
|
const files = await this.globFiles(includeSource, exclude, cwd);
|
|
7198
7123
|
await Promise.all(files.map(async (file) => {
|
|
7199
7124
|
try {
|
|
7200
7125
|
const code = await promises.readFile(file, "utf-8");
|
|
7201
|
-
if (this.isInSourceTestCode(code))
|
|
7202
|
-
testFiles.push(file);
|
|
7203
|
-
}
|
|
7126
|
+
if (this.isInSourceTestCode(code)) testFiles.push(file);
|
|
7204
7127
|
} catch {
|
|
7205
7128
|
return null;
|
|
7206
7129
|
}
|
|
@@ -7217,9 +7140,7 @@ class TestProject {
|
|
|
7217
7140
|
}
|
|
7218
7141
|
/** @internal */
|
|
7219
7142
|
_removeCachedTestFile(testPath) {
|
|
7220
|
-
if (this.testFilesList)
|
|
7221
|
-
this.testFilesList = this.testFilesList.filter((file) => file !== testPath);
|
|
7222
|
-
}
|
|
7143
|
+
if (this.testFilesList) this.testFilesList = this.testFilesList.filter((file) => file !== testPath);
|
|
7223
7144
|
}
|
|
7224
7145
|
/**
|
|
7225
7146
|
* Returns if the file is a test file. Requires `.globTestFiles()` to be called first.
|
|
@@ -7257,13 +7178,9 @@ class TestProject {
|
|
|
7257
7178
|
* Test if a file matches the test globs. This does the actual glob matching if the test is not cached, unlike `isCachedTestFile`.
|
|
7258
7179
|
*/
|
|
7259
7180
|
matchesTestGlob(moduleId, source) {
|
|
7260
|
-
if (this._isCachedTestFile(moduleId))
|
|
7261
|
-
return true;
|
|
7262
|
-
}
|
|
7181
|
+
if (this._isCachedTestFile(moduleId)) return true;
|
|
7263
7182
|
const relativeId = relative(this.config.dir || this.config.root, moduleId);
|
|
7264
|
-
if (pm.isMatch(relativeId, this.config.exclude))
|
|
7265
|
-
return false;
|
|
7266
|
-
}
|
|
7183
|
+
if (pm.isMatch(relativeId, this.config.exclude)) return false;
|
|
7267
7184
|
if (pm.isMatch(relativeId, this.config.include)) {
|
|
7268
7185
|
this.markTestFile(moduleId);
|
|
7269
7186
|
return true;
|
|
@@ -7279,28 +7196,22 @@ class TestProject {
|
|
|
7279
7196
|
}
|
|
7280
7197
|
/** @deprecated use `matchesTestGlob` instead */
|
|
7281
7198
|
async isTargetFile(id, source) {
|
|
7282
|
-
return this.matchesTestGlob(id, source ? () => source :
|
|
7199
|
+
return this.matchesTestGlob(id, source ? () => source : void 0);
|
|
7283
7200
|
}
|
|
7284
7201
|
isInSourceTestCode(code) {
|
|
7285
7202
|
return code.includes("import.meta.vitest");
|
|
7286
7203
|
}
|
|
7287
7204
|
filterFiles(testFiles, filters, dir) {
|
|
7288
|
-
if (filters.length && process.platform === "win32")
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
if (isAbsolute(f) && t.startsWith(f)) {
|
|
7297
|
-
return true;
|
|
7298
|
-
}
|
|
7299
|
-
const relativePath = f.endsWith("/") ? join(relative(dir, f), "/") : relative(dir, f);
|
|
7300
|
-
return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase());
|
|
7301
|
-
});
|
|
7205
|
+
if (filters.length && process.platform === "win32") filters = filters.map((f) => slash(f));
|
|
7206
|
+
if (filters.length) return testFiles.filter((t) => {
|
|
7207
|
+
const testFile = relative(dir, t).toLocaleLowerCase();
|
|
7208
|
+
return filters.some((f) => {
|
|
7209
|
+
// if filter is a full file path, we should include it if it's in the same folder
|
|
7210
|
+
if (isAbsolute(f) && t.startsWith(f)) return true;
|
|
7211
|
+
const relativePath = f.endsWith("/") ? join(relative(dir, f), "/") : relative(dir, f);
|
|
7212
|
+
return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase());
|
|
7302
7213
|
});
|
|
7303
|
-
}
|
|
7214
|
+
});
|
|
7304
7215
|
return testFiles;
|
|
7305
7216
|
}
|
|
7306
7217
|
_parentBrowser;
|
|
@@ -7308,9 +7219,7 @@ class TestProject {
|
|
|
7308
7219
|
_parent;
|
|
7309
7220
|
/** @internal */
|
|
7310
7221
|
_initParentBrowser = deduped(async () => {
|
|
7311
|
-
if (!this.isBrowserEnabled() || this._parentBrowser)
|
|
7312
|
-
return;
|
|
7313
|
-
}
|
|
7222
|
+
if (!this.isBrowserEnabled() || this._parentBrowser) return;
|
|
7314
7223
|
await this.vitest.packageInstaller.ensureInstalled("@vitest/browser", this.config.root, this.vitest.version);
|
|
7315
7224
|
const { createBrowserServer, distRoot } = await import('@vitest/browser');
|
|
7316
7225
|
let cacheDir;
|
|
@@ -7320,15 +7229,11 @@ class TestProject {
|
|
|
7320
7229
|
cacheDir = config.cacheDir;
|
|
7321
7230
|
}
|
|
7322
7231
|
}, ...MocksPlugins({ filter(id) {
|
|
7323
|
-
if (id.includes(distRoot) || id.includes(cacheDir))
|
|
7324
|
-
return false;
|
|
7325
|
-
}
|
|
7232
|
+
if (id.includes(distRoot) || id.includes(cacheDir)) return false;
|
|
7326
7233
|
return true;
|
|
7327
7234
|
} })], [CoverageTransform(this.vitest)]);
|
|
7328
7235
|
this._parentBrowser = browser;
|
|
7329
|
-
if (this.config.browser.ui)
|
|
7330
|
-
setup(this.vitest, browser.vite);
|
|
7331
|
-
}
|
|
7236
|
+
if (this.config.browser.ui) setup(this.vitest, browser.vite);
|
|
7332
7237
|
});
|
|
7333
7238
|
/** @internal */
|
|
7334
7239
|
_initBrowserServer = deduped(async () => {
|
|
@@ -7343,17 +7248,15 @@ class TestProject {
|
|
|
7343
7248
|
* If the resources are needed again, create a new project.
|
|
7344
7249
|
*/
|
|
7345
7250
|
close() {
|
|
7346
|
-
if (!this.closingPromise)
|
|
7347
|
-
this.
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
});
|
|
7356
|
-
}
|
|
7251
|
+
if (!this.closingPromise) this.closingPromise = Promise.all([
|
|
7252
|
+
this.vite?.close(),
|
|
7253
|
+
this.typechecker?.stop(),
|
|
7254
|
+
this.browser?.close(),
|
|
7255
|
+
this.clearTmpDir()
|
|
7256
|
+
].filter(Boolean)).then(() => {
|
|
7257
|
+
this._provided = {};
|
|
7258
|
+
this._vite = void 0;
|
|
7259
|
+
});
|
|
7357
7260
|
return this.closingPromise;
|
|
7358
7261
|
}
|
|
7359
7262
|
/**
|
|
@@ -7386,7 +7289,7 @@ class TestProject {
|
|
|
7386
7289
|
// type is very strict here, so we cast it to any
|
|
7387
7290
|
this.provide(providedKey, this.config.provide[providedKey]);
|
|
7388
7291
|
}
|
|
7389
|
-
this.closingPromise =
|
|
7292
|
+
this.closingPromise = void 0;
|
|
7390
7293
|
this._vite = server;
|
|
7391
7294
|
this.vitenode = new ViteNodeServer(server, this.config.server);
|
|
7392
7295
|
const node = this.vitenode;
|
|
@@ -7404,9 +7307,7 @@ class TestProject {
|
|
|
7404
7307
|
_serializeOverriddenConfig() {
|
|
7405
7308
|
// TODO: serialize the config _once_ or when needed
|
|
7406
7309
|
const config = serializeConfig(this.config, this.vitest.config, this.vite.config);
|
|
7407
|
-
if (!this.vitest.configOverride)
|
|
7408
|
-
return config;
|
|
7409
|
-
}
|
|
7310
|
+
if (!this.vitest.configOverride) return config;
|
|
7410
7311
|
return deepMerge(config, this.vitest.configOverride);
|
|
7411
7312
|
}
|
|
7412
7313
|
async clearTmpDir() {
|
|
@@ -7420,12 +7321,8 @@ class TestProject {
|
|
|
7420
7321
|
}
|
|
7421
7322
|
/** @internal */
|
|
7422
7323
|
_initBrowserProvider = deduped(async () => {
|
|
7423
|
-
if (!this.isBrowserEnabled() || this.browser?.provider)
|
|
7424
|
-
|
|
7425
|
-
}
|
|
7426
|
-
if (!this.browser) {
|
|
7427
|
-
await this._initBrowserServer();
|
|
7428
|
-
}
|
|
7324
|
+
if (!this.isBrowserEnabled() || this.browser?.provider) return;
|
|
7325
|
+
if (!this.browser) await this._initBrowserServer();
|
|
7429
7326
|
await this.browser?.initBrowserProvider(this);
|
|
7430
7327
|
});
|
|
7431
7328
|
/** @internal */
|
|
@@ -7463,11 +7360,9 @@ class TestProject {
|
|
|
7463
7360
|
function deduped(cb) {
|
|
7464
7361
|
let _promise;
|
|
7465
7362
|
return (...args) => {
|
|
7466
|
-
if (!_promise) {
|
|
7467
|
-
_promise =
|
|
7468
|
-
|
|
7469
|
-
});
|
|
7470
|
-
}
|
|
7363
|
+
if (!_promise) _promise = cb(...args).finally(() => {
|
|
7364
|
+
_promise = void 0;
|
|
7365
|
+
});
|
|
7471
7366
|
return _promise;
|
|
7472
7367
|
};
|
|
7473
7368
|
}
|
|
@@ -7489,9 +7384,7 @@ async function initializeProject(workspacePath, ctx, options) {
|
|
|
7489
7384
|
}
|
|
7490
7385
|
function generateHash(str) {
|
|
7491
7386
|
let hash = 0;
|
|
7492
|
-
if (str.length === 0) {
|
|
7493
|
-
return `${hash}`;
|
|
7494
|
-
}
|
|
7387
|
+
if (str.length === 0) return `${hash}`;
|
|
7495
7388
|
for (let i = 0; i < str.length; i++) {
|
|
7496
7389
|
const char = str.charCodeAt(i);
|
|
7497
7390
|
hash = (hash << 5) - hash + char;
|
|
@@ -7525,9 +7418,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7525
7418
|
"fileParallelism"
|
|
7526
7419
|
];
|
|
7527
7420
|
const cliOverrides = overridesOptions.reduce((acc, name) => {
|
|
7528
|
-
if (name in cliOptions)
|
|
7529
|
-
acc[name] = cliOptions[name];
|
|
7530
|
-
}
|
|
7421
|
+
if (name in cliOptions) acc[name] = cliOptions[name];
|
|
7531
7422
|
return acc;
|
|
7532
7423
|
}, {});
|
|
7533
7424
|
const projectPromises = [];
|
|
@@ -7554,9 +7445,7 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7554
7445
|
// if file leads to the root config, then we can just reuse it because we already initialized it
|
|
7555
7446
|
if (vitest.vite.config.configFile === path) {
|
|
7556
7447
|
const project = getDefaultTestProject(vitest);
|
|
7557
|
-
if (project)
|
|
7558
|
-
projectPromises.push(Promise.resolve(project));
|
|
7559
|
-
}
|
|
7448
|
+
if (project) projectPromises.push(Promise.resolve(project));
|
|
7560
7449
|
continue;
|
|
7561
7450
|
}
|
|
7562
7451
|
const configFile = path.endsWith("/") ? false : path;
|
|
@@ -7568,30 +7457,21 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7568
7457
|
})));
|
|
7569
7458
|
}
|
|
7570
7459
|
// pretty rare case - the glob didn't match anything and there are no inline configs
|
|
7571
|
-
if (!projectPromises.length)
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
].join(""));
|
|
7577
|
-
}
|
|
7460
|
+
if (!projectPromises.length) throw new Error([
|
|
7461
|
+
"No projects were found. Make sure your configuration is correct. ",
|
|
7462
|
+
vitest.config.project.length ? `The filter matched no projects: ${vitest.config.project.join(", ")}. ` : "",
|
|
7463
|
+
`The projects definition: ${JSON.stringify(projectsDefinition, null, 4)}.`
|
|
7464
|
+
].join(""));
|
|
7578
7465
|
const resolvedProjectsPromises = await Promise.allSettled(projectPromises);
|
|
7579
7466
|
const errors = [];
|
|
7580
7467
|
const resolvedProjects = [];
|
|
7581
|
-
for (const result of resolvedProjectsPromises) {
|
|
7582
|
-
if (result.
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
} else {
|
|
7589
|
-
resolvedProjects.push(result.value);
|
|
7590
|
-
}
|
|
7591
|
-
}
|
|
7592
|
-
if (errors.length) {
|
|
7593
|
-
throw new AggregateError(errors, "Failed to initialize projects. There were errors during projects setup. See below for more details.");
|
|
7594
|
-
}
|
|
7468
|
+
for (const result of resolvedProjectsPromises) if (result.status === "rejected") {
|
|
7469
|
+
if (result.reason instanceof VitestFilteredOutProjectError)
|
|
7470
|
+
// filter out filtered out projects
|
|
7471
|
+
continue;
|
|
7472
|
+
errors.push(result.reason);
|
|
7473
|
+
} else resolvedProjects.push(result.value);
|
|
7474
|
+
if (errors.length) throw new AggregateError(errors, "Failed to initialize projects. There were errors during projects setup. See below for more details.");
|
|
7595
7475
|
// project names are guaranteed to be unique
|
|
7596
7476
|
for (const project of resolvedProjects) {
|
|
7597
7477
|
const name = project.name;
|
|
@@ -7616,11 +7496,9 @@ async function resolveProjects(vitest, cliOptions, workspaceConfigPath, projects
|
|
|
7616
7496
|
return resolveBrowserProjects(vitest, names, resolvedProjects);
|
|
7617
7497
|
}
|
|
7618
7498
|
async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
7619
|
-
const removeProjects = new Set();
|
|
7499
|
+
const removeProjects = /* @__PURE__ */ new Set();
|
|
7620
7500
|
resolvedProjects.forEach((project) => {
|
|
7621
|
-
if (!project.config.browser.enabled)
|
|
7622
|
-
return;
|
|
7623
|
-
}
|
|
7501
|
+
if (!project.config.browser.enabled) return;
|
|
7624
7502
|
const instances = project.config.browser.instances || [];
|
|
7625
7503
|
const browser = project.config.browser.name;
|
|
7626
7504
|
if (instances.length === 0 && browser) {
|
|
@@ -7647,9 +7525,7 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7647
7525
|
removeProjects.add(project);
|
|
7648
7526
|
return;
|
|
7649
7527
|
}
|
|
7650
|
-
if (project.config.browser.providerOptions) {
|
|
7651
|
-
vitest.logger.warn(withLabel("yellow", "Vitest", `"providerOptions"${originalName ? ` in "${originalName}" project` : ""} is ignored because it's overridden by the configs. To hide this warning, remove the "providerOptions" property from the browser configuration.`));
|
|
7652
|
-
}
|
|
7528
|
+
if (project.config.browser.providerOptions) vitest.logger.warn(withLabel("yellow", "Vitest", `"providerOptions"${originalName ? ` in "${originalName}" project` : ""} is ignored because it's overridden by the configs. To hide this warning, remove the "providerOptions" property from the browser configuration.`));
|
|
7653
7529
|
filteredInstances.forEach((config, index) => {
|
|
7654
7530
|
const browser = config.browser;
|
|
7655
7531
|
if (!browser) {
|
|
@@ -7658,16 +7534,12 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7658
7534
|
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.`);
|
|
7659
7535
|
}
|
|
7660
7536
|
const name = config.name;
|
|
7661
|
-
if (name == null)
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
"If you have multiple instances for the same browser, make sure to define a custom \"name\". ",
|
|
7668
|
-
"All projects should have unique names. Make sure your configuration is correct."
|
|
7669
|
-
].join(""));
|
|
7670
|
-
}
|
|
7537
|
+
if (name == null) throw new Error(`The browser configuration must have a "name" property. This is a bug in Vitest. Please, open a new issue with reproduction`);
|
|
7538
|
+
if (names.has(name)) throw new Error([
|
|
7539
|
+
`Cannot define a nested project for a ${browser} browser. The project name "${name}" was already defined. `,
|
|
7540
|
+
"If you have multiple instances for the same browser, make sure to define a custom \"name\". ",
|
|
7541
|
+
"All projects should have unique names. Make sure your configuration is correct."
|
|
7542
|
+
].join(""));
|
|
7671
7543
|
names.add(name);
|
|
7672
7544
|
const clonedConfig = cloneConfig(project, config);
|
|
7673
7545
|
clonedConfig.name = name;
|
|
@@ -7682,9 +7554,7 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7682
7554
|
});
|
|
7683
7555
|
if (headedBrowserProjects.length > 1) {
|
|
7684
7556
|
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("");
|
|
7685
|
-
if (!isTTY) {
|
|
7686
|
-
throw new Error(`${message} Please, filter projects with --browser=name or --project=name flag or run tests with "headless: true" option.`);
|
|
7687
|
-
}
|
|
7557
|
+
if (!isTTY) throw new Error(`${message} Please, filter projects with --browser=name or --project=name flag or run tests with "headless: true" option.`);
|
|
7688
7558
|
const prompts = await import('./index.X0nbfr6-.js').then(function (n) { return n.i; });
|
|
7689
7559
|
const { projectName } = await prompts.default({
|
|
7690
7560
|
type: "select",
|
|
@@ -7695,9 +7565,7 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
|
|
|
7695
7565
|
})),
|
|
7696
7566
|
message: `${message} Select a single project to run or cancel and run tests with "headless: true" option. Note that you can also start tests with --browser=name or --project=name flag.`
|
|
7697
7567
|
});
|
|
7698
|
-
if (!projectName)
|
|
7699
|
-
throw new Error("The test run was aborted.");
|
|
7700
|
-
}
|
|
7568
|
+
if (!projectName) throw new Error("The test run was aborted.");
|
|
7701
7569
|
return resolvedProjects.filter((project) => project.name === projectName);
|
|
7702
7570
|
}
|
|
7703
7571
|
return resolvedProjects;
|
|
@@ -7717,7 +7585,7 @@ function cloneConfig(project, { browser,...config }) {
|
|
|
7717
7585
|
headless: headless ?? currentConfig.headless,
|
|
7718
7586
|
name: browser,
|
|
7719
7587
|
providerOptions: config,
|
|
7720
|
-
instances:
|
|
7588
|
+
instances: void 0
|
|
7721
7589
|
}
|
|
7722
7590
|
}, overrideConfig);
|
|
7723
7591
|
}
|
|
@@ -7730,48 +7598,38 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDe
|
|
|
7730
7598
|
const projectsGlobMatches = [];
|
|
7731
7599
|
// directories that don't have a config file inside, but should be treated as projects
|
|
7732
7600
|
const nonConfigProjectDirectories = [];
|
|
7733
|
-
for (const definition of projectsDefinition) {
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
throw new Error(`${note} references a non-existing file or a directory: ${file}`);
|
|
7744
|
-
}
|
|
7745
|
-
const stats = await promises.stat(file);
|
|
7746
|
-
// user can specify a config file directly
|
|
7747
|
-
if (stats.isFile()) {
|
|
7748
|
-
projectsConfigFiles.push(file);
|
|
7749
|
-
} else if (stats.isDirectory()) {
|
|
7750
|
-
const configFile = await resolveDirectoryConfig(file);
|
|
7751
|
-
if (configFile) {
|
|
7752
|
-
projectsConfigFiles.push(configFile);
|
|
7753
|
-
} else {
|
|
7754
|
-
const directory = file[file.length - 1] === "/" ? file : `${file}/`;
|
|
7755
|
-
nonConfigProjectDirectories.push(directory);
|
|
7756
|
-
}
|
|
7757
|
-
} else {
|
|
7758
|
-
// should never happen
|
|
7759
|
-
throw new TypeError(`Unexpected file type: ${file}`);
|
|
7760
|
-
}
|
|
7761
|
-
} else {
|
|
7762
|
-
projectsGlobMatches.push(stringOption);
|
|
7601
|
+
for (const definition of projectsDefinition) if (typeof definition === "string") {
|
|
7602
|
+
const stringOption = definition.replace("<rootDir>", vitest.config.root);
|
|
7603
|
+
// if the string doesn't contain a glob, we can resolve it directly
|
|
7604
|
+
// ['./vitest.config.js']
|
|
7605
|
+
if (!isDynamicPattern(stringOption)) {
|
|
7606
|
+
const file = resolve(vitest.config.root, stringOption);
|
|
7607
|
+
if (!existsSync(file)) {
|
|
7608
|
+
const relativeWorkspaceConfigPath = workspaceConfigPath ? relative(vitest.config.root, workspaceConfigPath) : void 0;
|
|
7609
|
+
const note = workspaceConfigPath ? `Workspace config file "${relativeWorkspaceConfigPath}"` : "Projects definition";
|
|
7610
|
+
throw new Error(`${note} references a non-existing file or a directory: ${file}`);
|
|
7763
7611
|
}
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7612
|
+
const stats = await promises.stat(file);
|
|
7613
|
+
// user can specify a config file directly
|
|
7614
|
+
if (stats.isFile()) projectsConfigFiles.push(file);
|
|
7615
|
+
else if (stats.isDirectory()) {
|
|
7616
|
+
const configFile = await resolveDirectoryConfig(file);
|
|
7617
|
+
if (configFile) projectsConfigFiles.push(configFile);
|
|
7618
|
+
else {
|
|
7619
|
+
const directory = file[file.length - 1] === "/" ? file : `${file}/`;
|
|
7620
|
+
nonConfigProjectDirectories.push(directory);
|
|
7621
|
+
}
|
|
7622
|
+
} else
|
|
7623
|
+
// should never happen
|
|
7624
|
+
throw new TypeError(`Unexpected file type: ${file}`);
|
|
7625
|
+
} else projectsGlobMatches.push(stringOption);
|
|
7626
|
+
} else if (typeof definition === "function") projectsOptions.push(await definition({
|
|
7627
|
+
command: vitest.vite.config.command,
|
|
7628
|
+
mode: vitest.vite.config.mode,
|
|
7629
|
+
isPreview: false,
|
|
7630
|
+
isSsrBuild: false
|
|
7631
|
+
}));
|
|
7632
|
+
else projectsOptions.push(await definition);
|
|
7775
7633
|
if (projectsGlobMatches.length) {
|
|
7776
7634
|
const globOptions = {
|
|
7777
7635
|
absolute: true,
|
|
@@ -7791,14 +7649,9 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, projectsDe
|
|
|
7791
7649
|
// in this case every directory is treated as a project
|
|
7792
7650
|
if (path.endsWith("/")) {
|
|
7793
7651
|
const configFile = await resolveDirectoryConfig(path);
|
|
7794
|
-
if (configFile)
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
nonConfigProjectDirectories.push(path);
|
|
7798
|
-
}
|
|
7799
|
-
} else {
|
|
7800
|
-
projectsConfigFiles.push(path);
|
|
7801
|
-
}
|
|
7652
|
+
if (configFile) projectsConfigFiles.push(configFile);
|
|
7653
|
+
else nonConfigProjectDirectories.push(path);
|
|
7654
|
+
} else projectsConfigFiles.push(path);
|
|
7802
7655
|
}));
|
|
7803
7656
|
}
|
|
7804
7657
|
const projectConfigFiles = Array.from(new Set(projectsConfigFiles));
|
|
@@ -7813,31 +7666,22 @@ async function resolveDirectoryConfig(directory) {
|
|
|
7813
7666
|
// default resolution looks for vitest.config.* or vite.config.* files
|
|
7814
7667
|
// this simulates how `findUp` works in packages/vitest/src/node/create.ts:29
|
|
7815
7668
|
const configFile = configFiles.find((file) => files.has(file));
|
|
7816
|
-
if (configFile)
|
|
7817
|
-
return resolve(directory, configFile);
|
|
7818
|
-
}
|
|
7669
|
+
if (configFile) return resolve(directory, configFile);
|
|
7819
7670
|
return null;
|
|
7820
7671
|
}
|
|
7821
7672
|
function getDefaultTestProject(vitest) {
|
|
7822
7673
|
const filter = vitest.config.project;
|
|
7823
7674
|
const project = vitest._ensureRootProject();
|
|
7824
|
-
if (!filter.length)
|
|
7825
|
-
return project;
|
|
7826
|
-
}
|
|
7675
|
+
if (!filter.length) return project;
|
|
7827
7676
|
// check for the project name and browser names
|
|
7828
7677
|
const hasProjects = getPotentialProjectNames(project).some((p) => vitest.matchesProjectFilter(p));
|
|
7829
|
-
if (hasProjects)
|
|
7830
|
-
return project;
|
|
7831
|
-
}
|
|
7678
|
+
if (hasProjects) return project;
|
|
7832
7679
|
return null;
|
|
7833
7680
|
}
|
|
7834
7681
|
function getPotentialProjectNames(project) {
|
|
7835
7682
|
const names = [project.name];
|
|
7836
|
-
if (project.config.browser.instances)
|
|
7837
|
-
|
|
7838
|
-
} else if (project.config.browser.name) {
|
|
7839
|
-
names.push(project.config.browser.name);
|
|
7840
|
-
}
|
|
7683
|
+
if (project.config.browser.instances) names.push(...project.config.browser.instances.map((i) => i.name));
|
|
7684
|
+
else if (project.config.browser.name) names.push(project.config.browser.name);
|
|
7841
7685
|
return names;
|
|
7842
7686
|
}
|
|
7843
7687
|
|
|
@@ -7848,9 +7692,7 @@ async function loadCustomReporterModule(path, runner) {
|
|
|
7848
7692
|
} catch (customReporterModuleError) {
|
|
7849
7693
|
throw new Error(`Failed to load custom Reporter from ${path}`, { cause: customReporterModuleError });
|
|
7850
7694
|
}
|
|
7851
|
-
if (customReporterModule.default === null || customReporterModule.default ===
|
|
7852
|
-
throw new Error(`Custom reporter loaded from ${path} was not the default export`);
|
|
7853
|
-
}
|
|
7695
|
+
if (customReporterModule.default === null || customReporterModule.default === void 0) throw new Error(`Custom reporter loaded from ${path} was not the default export`);
|
|
7854
7696
|
return customReporterModule.default;
|
|
7855
7697
|
}
|
|
7856
7698
|
function createReporters(reporterReferences, ctx) {
|
|
@@ -7876,14 +7718,12 @@ function createReporters(reporterReferences, ctx) {
|
|
|
7876
7718
|
}
|
|
7877
7719
|
function createBenchmarkReporters(reporterReferences, runner) {
|
|
7878
7720
|
const promisedReporters = reporterReferences.map(async (referenceOrInstance) => {
|
|
7879
|
-
if (typeof referenceOrInstance === "string") {
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
return new CustomReporter();
|
|
7886
|
-
}
|
|
7721
|
+
if (typeof referenceOrInstance === "string") if (referenceOrInstance in BenchmarkReportsMap) {
|
|
7722
|
+
const BuiltinReporter = BenchmarkReportsMap[referenceOrInstance];
|
|
7723
|
+
return new BuiltinReporter();
|
|
7724
|
+
} else {
|
|
7725
|
+
const CustomReporter = await loadCustomReporterModule(referenceOrInstance, runner);
|
|
7726
|
+
return new CustomReporter();
|
|
7887
7727
|
}
|
|
7888
7728
|
return referenceOrInstance;
|
|
7889
7729
|
});
|
|
@@ -7892,49 +7732,37 @@ function createBenchmarkReporters(reporterReferences, runner) {
|
|
|
7892
7732
|
|
|
7893
7733
|
function parseFilter(filter) {
|
|
7894
7734
|
const colonIndex = filter.lastIndexOf(":");
|
|
7895
|
-
if (colonIndex === -1) {
|
|
7896
|
-
return { filename: filter };
|
|
7897
|
-
}
|
|
7735
|
+
if (colonIndex === -1) return { filename: filter };
|
|
7898
7736
|
const [parsedFilename, lineNumber] = [filter.substring(0, colonIndex), filter.substring(colonIndex + 1)];
|
|
7899
|
-
if (lineNumber.match(/^\d+$/)) {
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
throw new RangeLocationFilterProvidedError(filter);
|
|
7906
|
-
} else {
|
|
7907
|
-
return { filename: filter };
|
|
7908
|
-
}
|
|
7737
|
+
if (lineNumber.match(/^\d+$/)) return {
|
|
7738
|
+
filename: parsedFilename,
|
|
7739
|
+
lineNumber: Number.parseInt(lineNumber)
|
|
7740
|
+
};
|
|
7741
|
+
else if (lineNumber.match(/^\d+-\d+$/)) throw new RangeLocationFilterProvidedError(filter);
|
|
7742
|
+
else return { filename: filter };
|
|
7909
7743
|
}
|
|
7910
7744
|
function groupFilters(filters) {
|
|
7911
7745
|
const groupedFilters_ = groupBy(filters, (f) => f.filename);
|
|
7912
7746
|
const groupedFilters = Object.fromEntries(Object.entries(groupedFilters_).map((entry) => {
|
|
7913
7747
|
const [filename, filters] = entry;
|
|
7914
7748
|
const testLocations = filters.map((f) => f.lineNumber);
|
|
7915
|
-
return [filename, testLocations.filter((l) => l !==
|
|
7749
|
+
return [filename, testLocations.filter((l) => l !== void 0)];
|
|
7916
7750
|
}));
|
|
7917
7751
|
return groupedFilters;
|
|
7918
7752
|
}
|
|
7919
7753
|
|
|
7920
7754
|
class VitestSpecifications {
|
|
7921
|
-
_cachedSpecs = new Map();
|
|
7755
|
+
_cachedSpecs = /* @__PURE__ */ new Map();
|
|
7922
7756
|
constructor(vitest) {
|
|
7923
7757
|
this.vitest = vitest;
|
|
7924
7758
|
}
|
|
7925
7759
|
getModuleSpecifications(moduleId) {
|
|
7926
7760
|
const _cached = this.getCachedSpecifications(moduleId);
|
|
7927
|
-
if (_cached)
|
|
7928
|
-
return _cached;
|
|
7929
|
-
}
|
|
7761
|
+
if (_cached) return _cached;
|
|
7930
7762
|
const specs = [];
|
|
7931
7763
|
for (const project of this.vitest.projects) {
|
|
7932
|
-
if (project._isCachedTestFile(moduleId))
|
|
7933
|
-
|
|
7934
|
-
}
|
|
7935
|
-
if (project._isCachedTypecheckFile(moduleId)) {
|
|
7936
|
-
specs.push(project.createSpecification(moduleId, [], "typescript"));
|
|
7937
|
-
}
|
|
7764
|
+
if (project._isCachedTestFile(moduleId)) specs.push(project.createSpecification(moduleId));
|
|
7765
|
+
if (project._isCachedTypecheckFile(moduleId)) specs.push(project.createSpecification(moduleId, [], "typescript"));
|
|
7938
7766
|
}
|
|
7939
7767
|
specs.forEach((spec) => this.ensureSpecificationCached(spec));
|
|
7940
7768
|
return specs;
|
|
@@ -7947,9 +7775,7 @@ class VitestSpecifications {
|
|
|
7947
7775
|
const dir = process.cwd();
|
|
7948
7776
|
const parsedFilters = filters.map((f) => parseFilter(f));
|
|
7949
7777
|
// Require includeTaskLocation when a location filter is passed
|
|
7950
|
-
if (!this.vitest.config.includeTaskLocation && parsedFilters.some((f) => f.lineNumber !==
|
|
7951
|
-
throw new IncludeTaskLocationDisabledError();
|
|
7952
|
-
}
|
|
7778
|
+
if (!this.vitest.config.includeTaskLocation && parsedFilters.some((f) => f.lineNumber !== void 0)) throw new IncludeTaskLocationDisabledError();
|
|
7953
7779
|
const testLines = groupFilters(parsedFilters.map((f) => ({
|
|
7954
7780
|
...f,
|
|
7955
7781
|
filename: resolve(dir, f.filename)
|
|
@@ -7974,18 +7800,13 @@ class VitestSpecifications {
|
|
|
7974
7800
|
});
|
|
7975
7801
|
}));
|
|
7976
7802
|
Object.entries(testLines).forEach(([filepath, loc]) => {
|
|
7977
|
-
if (loc.length !== 0 && !testLocHasMatch[filepath])
|
|
7978
|
-
throw new LocationFilterFileNotFoundError(relative(dir, filepath));
|
|
7979
|
-
}
|
|
7803
|
+
if (loc.length !== 0 && !testLocHasMatch[filepath]) throw new LocationFilterFileNotFoundError(relative(dir, filepath));
|
|
7980
7804
|
});
|
|
7981
7805
|
return files;
|
|
7982
7806
|
}
|
|
7983
7807
|
clearCache(moduleId) {
|
|
7984
|
-
if (moduleId)
|
|
7985
|
-
|
|
7986
|
-
} else {
|
|
7987
|
-
this._cachedSpecs.clear();
|
|
7988
|
-
}
|
|
7808
|
+
if (moduleId) this._cachedSpecs.delete(moduleId);
|
|
7809
|
+
else this._cachedSpecs.clear();
|
|
7989
7810
|
}
|
|
7990
7811
|
getCachedSpecifications(moduleId) {
|
|
7991
7812
|
return this._cachedSpecs.get(moduleId);
|
|
@@ -7997,14 +7818,12 @@ class VitestSpecifications {
|
|
|
7997
7818
|
if (index === -1) {
|
|
7998
7819
|
specs.push(spec);
|
|
7999
7820
|
this._cachedSpecs.set(file, specs);
|
|
8000
|
-
} else
|
|
8001
|
-
specs.splice(index, 1, spec);
|
|
8002
|
-
}
|
|
7821
|
+
} else specs.splice(index, 1, spec);
|
|
8003
7822
|
return specs;
|
|
8004
7823
|
}
|
|
8005
7824
|
async filterTestsBySource(specs) {
|
|
8006
7825
|
if (this.vitest.config.changed && !this.vitest.config.related) {
|
|
8007
|
-
const { VitestGit } = await import('./git.
|
|
7826
|
+
const { VitestGit } = await import('./git.BVQ8w_Sw.js');
|
|
8008
7827
|
const vitestGit = new VitestGit(this.vitest.config.root);
|
|
8009
7828
|
const related = await vitestGit.findChangedFiles({ changedSince: this.vitest.config.changed });
|
|
8010
7829
|
if (!related) {
|
|
@@ -8014,49 +7833,34 @@ class VitestSpecifications {
|
|
|
8014
7833
|
this.vitest.config.related = Array.from(new Set(related));
|
|
8015
7834
|
}
|
|
8016
7835
|
const related = this.vitest.config.related;
|
|
8017
|
-
if (!related)
|
|
8018
|
-
return specs;
|
|
8019
|
-
}
|
|
7836
|
+
if (!related) return specs;
|
|
8020
7837
|
const forceRerunTriggers = this.vitest.config.forceRerunTriggers;
|
|
8021
|
-
const matcher = forceRerunTriggers.length ? pm(forceRerunTriggers) :
|
|
8022
|
-
if (matcher && related.some((file) => matcher(file)))
|
|
8023
|
-
return specs;
|
|
8024
|
-
}
|
|
7838
|
+
const matcher = forceRerunTriggers.length ? pm(forceRerunTriggers) : void 0;
|
|
7839
|
+
if (matcher && related.some((file) => matcher(file))) return specs;
|
|
8025
7840
|
// don't run anything if no related sources are found
|
|
8026
7841
|
// if we are in watch mode, we want to process all tests
|
|
8027
|
-
if (!this.vitest.config.watch && !related.length)
|
|
8028
|
-
return [];
|
|
8029
|
-
}
|
|
7842
|
+
if (!this.vitest.config.watch && !related.length) return [];
|
|
8030
7843
|
const testGraphs = await Promise.all(specs.map(async (spec) => {
|
|
8031
7844
|
const deps = await this.getTestDependencies(spec);
|
|
8032
7845
|
return [spec, deps];
|
|
8033
7846
|
}));
|
|
8034
7847
|
const runningTests = [];
|
|
8035
|
-
for (const [specification, deps] of testGraphs)
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
runningTests.push(specification);
|
|
8039
|
-
}
|
|
8040
|
-
}
|
|
7848
|
+
for (const [specification, deps] of testGraphs)
|
|
7849
|
+
// if deps or the test itself were changed
|
|
7850
|
+
if (related.some((path) => path === specification.moduleId || deps.has(path))) runningTests.push(specification);
|
|
8041
7851
|
return runningTests;
|
|
8042
7852
|
}
|
|
8043
|
-
async getTestDependencies(spec, deps = new Set()) {
|
|
7853
|
+
async getTestDependencies(spec, deps = /* @__PURE__ */ new Set()) {
|
|
8044
7854
|
const addImports = async (project, filepath) => {
|
|
8045
|
-
if (deps.has(filepath))
|
|
8046
|
-
return;
|
|
8047
|
-
}
|
|
7855
|
+
if (deps.has(filepath)) return;
|
|
8048
7856
|
deps.add(filepath);
|
|
8049
7857
|
const mod = project.vite.moduleGraph.getModuleById(filepath);
|
|
8050
7858
|
const transformed = mod?.ssrTransformResult || await project.vitenode.transformRequest(filepath);
|
|
8051
|
-
if (!transformed)
|
|
8052
|
-
return;
|
|
8053
|
-
}
|
|
7859
|
+
if (!transformed) return;
|
|
8054
7860
|
const dependencies = [...transformed.deps || [], ...transformed.dynamicDeps || []];
|
|
8055
7861
|
await Promise.all(dependencies.map(async (dep) => {
|
|
8056
7862
|
const fsPath = dep.startsWith("/@fs/") ? dep.slice(isWindows ? 5 : 4) : join(project.config.root, dep);
|
|
8057
|
-
if (!fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath))
|
|
8058
|
-
await addImports(project, fsPath);
|
|
8059
|
-
}
|
|
7863
|
+
if (!fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath)) await addImports(project, fsPath);
|
|
8060
7864
|
}));
|
|
8061
7865
|
};
|
|
8062
7866
|
await addImports(spec.project, spec.moduleId);
|
|
@@ -8141,24 +7945,16 @@ class TestCase extends ReportedTaskImplementation {
|
|
|
8141
7945
|
this.name = task.name;
|
|
8142
7946
|
this.module = getReportedTask(project, task.file);
|
|
8143
7947
|
const suite = this.task.suite;
|
|
8144
|
-
if (suite)
|
|
8145
|
-
|
|
8146
|
-
} else {
|
|
8147
|
-
this.parent = this.module;
|
|
8148
|
-
}
|
|
7948
|
+
if (suite) this.parent = getReportedTask(project, suite);
|
|
7949
|
+
else this.parent = this.module;
|
|
8149
7950
|
this.options = buildOptions(task);
|
|
8150
7951
|
}
|
|
8151
7952
|
/**
|
|
8152
7953
|
* Full name of the test including all parent suites separated with `>`.
|
|
8153
7954
|
*/
|
|
8154
7955
|
get fullName() {
|
|
8155
|
-
if (this.#fullName ===
|
|
8156
|
-
|
|
8157
|
-
this.#fullName = `${this.parent.fullName} > ${this.name}`;
|
|
8158
|
-
} else {
|
|
8159
|
-
this.#fullName = this.name;
|
|
8160
|
-
}
|
|
8161
|
-
}
|
|
7956
|
+
if (this.#fullName === void 0) if (this.parent.type !== "module") this.#fullName = `${this.parent.fullName} > ${this.name}`;
|
|
7957
|
+
else this.#fullName = this.name;
|
|
8162
7958
|
return this.#fullName;
|
|
8163
7959
|
}
|
|
8164
7960
|
/**
|
|
@@ -8171,48 +7967,44 @@ class TestCase extends ReportedTaskImplementation {
|
|
|
8171
7967
|
result() {
|
|
8172
7968
|
const result = this.task.result;
|
|
8173
7969
|
const mode = result?.state || this.task.mode;
|
|
8174
|
-
if (!result && (mode === "skip" || mode === "todo")) {
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
state: "pending",
|
|
8184
|
-
errors: undefined
|
|
8185
|
-
};
|
|
8186
|
-
}
|
|
7970
|
+
if (!result && (mode === "skip" || mode === "todo")) return {
|
|
7971
|
+
state: "skipped",
|
|
7972
|
+
note: void 0,
|
|
7973
|
+
errors: void 0
|
|
7974
|
+
};
|
|
7975
|
+
if (!result || result.state === "run" || result.state === "queued") return {
|
|
7976
|
+
state: "pending",
|
|
7977
|
+
errors: void 0
|
|
7978
|
+
};
|
|
8187
7979
|
const state = result.state === "fail" ? "failed" : result.state === "pass" ? "passed" : "skipped";
|
|
8188
|
-
if (state === "skipped") {
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
state,
|
|
8198
|
-
errors: result.errors
|
|
8199
|
-
};
|
|
8200
|
-
}
|
|
7980
|
+
if (state === "skipped") return {
|
|
7981
|
+
state,
|
|
7982
|
+
note: result.note,
|
|
7983
|
+
errors: void 0
|
|
7984
|
+
};
|
|
7985
|
+
if (state === "passed") return {
|
|
7986
|
+
state,
|
|
7987
|
+
errors: result.errors
|
|
7988
|
+
};
|
|
8201
7989
|
return {
|
|
8202
7990
|
state,
|
|
8203
7991
|
errors: result.errors || []
|
|
8204
7992
|
};
|
|
8205
7993
|
}
|
|
8206
7994
|
/**
|
|
7995
|
+
* Test annotations added via the `task.annotate` API during the test execution.
|
|
7996
|
+
*/
|
|
7997
|
+
annotations() {
|
|
7998
|
+
return [...this.task.annotations];
|
|
7999
|
+
}
|
|
8000
|
+
/**
|
|
8207
8001
|
* Useful information about the test like duration, memory usage, etc.
|
|
8208
8002
|
* Diagnostic is only available after the test has finished.
|
|
8209
8003
|
*/
|
|
8210
8004
|
diagnostic() {
|
|
8211
8005
|
const result = this.task.result;
|
|
8212
8006
|
// startTime should always be available if the test has properly finished
|
|
8213
|
-
if (!result || !result.startTime)
|
|
8214
|
-
return undefined;
|
|
8215
|
-
}
|
|
8007
|
+
if (!result || !result.startTime) return void 0;
|
|
8216
8008
|
const duration = result.duration || 0;
|
|
8217
8009
|
const slow = duration > this.project.globalConfig.slowTestThreshold;
|
|
8218
8010
|
return {
|
|
@@ -8237,9 +8029,7 @@ class TestCollection {
|
|
|
8237
8029
|
* Returns the test or suite at a specific index.
|
|
8238
8030
|
*/
|
|
8239
8031
|
at(index) {
|
|
8240
|
-
if (index < 0)
|
|
8241
|
-
index = this.size + index;
|
|
8242
|
-
}
|
|
8032
|
+
if (index < 0) index = this.size + index;
|
|
8243
8033
|
return getReportedTask(this.#project, this.#task.tasks[index]);
|
|
8244
8034
|
}
|
|
8245
8035
|
/**
|
|
@@ -8258,62 +8048,41 @@ class TestCollection {
|
|
|
8258
8048
|
* Filters all tests that are part of this collection and its children.
|
|
8259
8049
|
*/
|
|
8260
8050
|
*allTests(state) {
|
|
8261
|
-
for (const child of this)
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
if (state === testState) {
|
|
8267
|
-
yield child;
|
|
8268
|
-
}
|
|
8269
|
-
} else {
|
|
8270
|
-
yield child;
|
|
8271
|
-
}
|
|
8272
|
-
}
|
|
8051
|
+
for (const child of this) if (child.type === "suite") yield* child.children.allTests(state);
|
|
8052
|
+
else if (state) {
|
|
8053
|
+
const testState = child.result().state;
|
|
8054
|
+
if (state === testState) yield child;
|
|
8055
|
+
} else yield child;
|
|
8273
8056
|
}
|
|
8274
8057
|
/**
|
|
8275
8058
|
* Filters only the tests that are part of this collection.
|
|
8276
8059
|
*/
|
|
8277
8060
|
*tests(state) {
|
|
8278
8061
|
for (const child of this) {
|
|
8279
|
-
if (child.type !== "test")
|
|
8280
|
-
continue;
|
|
8281
|
-
}
|
|
8062
|
+
if (child.type !== "test") continue;
|
|
8282
8063
|
if (state) {
|
|
8283
8064
|
const testState = child.result().state;
|
|
8284
|
-
if (state === testState)
|
|
8285
|
-
|
|
8286
|
-
}
|
|
8287
|
-
} else {
|
|
8288
|
-
yield child;
|
|
8289
|
-
}
|
|
8065
|
+
if (state === testState) yield child;
|
|
8066
|
+
} else yield child;
|
|
8290
8067
|
}
|
|
8291
8068
|
}
|
|
8292
8069
|
/**
|
|
8293
8070
|
* Filters only the suites that are part of this collection.
|
|
8294
8071
|
*/
|
|
8295
8072
|
*suites() {
|
|
8296
|
-
for (const child of this)
|
|
8297
|
-
if (child.type === "suite") {
|
|
8298
|
-
yield child;
|
|
8299
|
-
}
|
|
8300
|
-
}
|
|
8073
|
+
for (const child of this) if (child.type === "suite") yield child;
|
|
8301
8074
|
}
|
|
8302
8075
|
/**
|
|
8303
8076
|
* Filters all suites that are part of this collection and its children.
|
|
8304
8077
|
*/
|
|
8305
8078
|
*allSuites() {
|
|
8306
|
-
for (const child of this) {
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
yield* child.children.allSuites();
|
|
8310
|
-
}
|
|
8079
|
+
for (const child of this) if (child.type === "suite") {
|
|
8080
|
+
yield child;
|
|
8081
|
+
yield* child.children.allSuites();
|
|
8311
8082
|
}
|
|
8312
8083
|
}
|
|
8313
8084
|
*[Symbol.iterator]() {
|
|
8314
|
-
for (const task of this.#task.tasks)
|
|
8315
|
-
yield getReportedTask(this.#project, task);
|
|
8316
|
-
}
|
|
8085
|
+
for (const task of this.#task.tasks) yield getReportedTask(this.#project, task);
|
|
8317
8086
|
}
|
|
8318
8087
|
}
|
|
8319
8088
|
class SuiteImplementation extends ReportedTaskImplementation {
|
|
@@ -8358,11 +8127,8 @@ class TestSuite extends SuiteImplementation {
|
|
|
8358
8127
|
this.name = task.name;
|
|
8359
8128
|
this.module = getReportedTask(project, task.file);
|
|
8360
8129
|
const suite = this.task.suite;
|
|
8361
|
-
if (suite)
|
|
8362
|
-
|
|
8363
|
-
} else {
|
|
8364
|
-
this.parent = this.module;
|
|
8365
|
-
}
|
|
8130
|
+
if (suite) this.parent = getReportedTask(project, suite);
|
|
8131
|
+
else this.parent = this.module;
|
|
8366
8132
|
this.options = buildOptions(task);
|
|
8367
8133
|
}
|
|
8368
8134
|
/**
|
|
@@ -8375,13 +8141,8 @@ class TestSuite extends SuiteImplementation {
|
|
|
8375
8141
|
* Full name of the suite including all parent suites separated with `>`.
|
|
8376
8142
|
*/
|
|
8377
8143
|
get fullName() {
|
|
8378
|
-
if (this.#fullName ===
|
|
8379
|
-
|
|
8380
|
-
this.#fullName = `${this.parent.fullName} > ${this.name}`;
|
|
8381
|
-
} else {
|
|
8382
|
-
this.#fullName = this.name;
|
|
8383
|
-
}
|
|
8384
|
-
}
|
|
8144
|
+
if (this.#fullName === void 0) if (this.parent.type !== "module") this.#fullName = `${this.parent.fullName} > ${this.name}`;
|
|
8145
|
+
else this.#fullName = this.name;
|
|
8385
8146
|
return this.#fullName;
|
|
8386
8147
|
}
|
|
8387
8148
|
}
|
|
@@ -8403,9 +8164,7 @@ class TestModule extends SuiteImplementation {
|
|
|
8403
8164
|
*/
|
|
8404
8165
|
state() {
|
|
8405
8166
|
const state = this.task.result?.state;
|
|
8406
|
-
if (state === "queued")
|
|
8407
|
-
return "queued";
|
|
8408
|
-
}
|
|
8167
|
+
if (state === "queued") return "queued";
|
|
8409
8168
|
return getSuiteState(this.task);
|
|
8410
8169
|
}
|
|
8411
8170
|
/**
|
|
@@ -8419,13 +8178,15 @@ class TestModule extends SuiteImplementation {
|
|
|
8419
8178
|
const environmentSetupDuration = this.task.environmentLoad || 0;
|
|
8420
8179
|
const duration = this.task.result?.duration || 0;
|
|
8421
8180
|
const heap = this.task.result?.heap;
|
|
8181
|
+
const importDurations = this.task.importDurations ?? {};
|
|
8422
8182
|
return {
|
|
8423
8183
|
environmentSetupDuration,
|
|
8424
8184
|
prepareDuration,
|
|
8425
8185
|
collectDuration,
|
|
8426
8186
|
setupDuration,
|
|
8427
8187
|
duration,
|
|
8428
|
-
heap
|
|
8188
|
+
heap,
|
|
8189
|
+
importDurations
|
|
8429
8190
|
};
|
|
8430
8191
|
}
|
|
8431
8192
|
}
|
|
@@ -8445,56 +8206,39 @@ function storeTask(project, runnerTask, reportedTask) {
|
|
|
8445
8206
|
}
|
|
8446
8207
|
function getReportedTask(project, runnerTask) {
|
|
8447
8208
|
const reportedTask = project.vitest.state.getReportedEntity(runnerTask);
|
|
8448
|
-
if (!reportedTask) {
|
|
8449
|
-
throw new Error(`Task instance was not found for ${runnerTask.type} "${runnerTask.name}"`);
|
|
8450
|
-
}
|
|
8209
|
+
if (!reportedTask) throw new Error(`Task instance was not found for ${runnerTask.type} "${runnerTask.name}"`);
|
|
8451
8210
|
return reportedTask;
|
|
8452
8211
|
}
|
|
8453
8212
|
function getSuiteState(task) {
|
|
8454
8213
|
const mode = task.mode;
|
|
8455
8214
|
const state = task.result?.state;
|
|
8456
|
-
if (mode === "skip" || mode === "todo" || state === "skip" || state === "todo")
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
if (state
|
|
8460
|
-
return "pending";
|
|
8461
|
-
}
|
|
8462
|
-
if (state === "fail") {
|
|
8463
|
-
return "failed";
|
|
8464
|
-
}
|
|
8465
|
-
if (state === "pass") {
|
|
8466
|
-
return "passed";
|
|
8467
|
-
}
|
|
8215
|
+
if (mode === "skip" || mode === "todo" || state === "skip" || state === "todo") return "skipped";
|
|
8216
|
+
if (state == null || state === "run" || state === "only") return "pending";
|
|
8217
|
+
if (state === "fail") return "failed";
|
|
8218
|
+
if (state === "pass") return "passed";
|
|
8468
8219
|
throw new Error(`Unknown suite state: ${state}`);
|
|
8469
8220
|
}
|
|
8470
8221
|
|
|
8471
8222
|
function isAggregateError(err) {
|
|
8472
|
-
if (typeof AggregateError !== "undefined" && err instanceof AggregateError)
|
|
8473
|
-
return true;
|
|
8474
|
-
}
|
|
8223
|
+
if (typeof AggregateError !== "undefined" && err instanceof AggregateError) return true;
|
|
8475
8224
|
return err instanceof Error && "errors" in err;
|
|
8476
8225
|
}
|
|
8477
8226
|
class StateManager {
|
|
8478
|
-
filesMap = new Map();
|
|
8479
|
-
pathsSet = new Set();
|
|
8480
|
-
idMap = new Map();
|
|
8481
|
-
taskFileMap = new WeakMap();
|
|
8482
|
-
errorsSet = new Set();
|
|
8483
|
-
processTimeoutCauses = new Set();
|
|
8484
|
-
reportedTasksMap = new WeakMap();
|
|
8227
|
+
filesMap = /* @__PURE__ */ new Map();
|
|
8228
|
+
pathsSet = /* @__PURE__ */ new Set();
|
|
8229
|
+
idMap = /* @__PURE__ */ new Map();
|
|
8230
|
+
taskFileMap = /* @__PURE__ */ new WeakMap();
|
|
8231
|
+
errorsSet = /* @__PURE__ */ new Set();
|
|
8232
|
+
processTimeoutCauses = /* @__PURE__ */ new Set();
|
|
8233
|
+
reportedTasksMap = /* @__PURE__ */ new WeakMap();
|
|
8485
8234
|
blobs;
|
|
8486
8235
|
catchError(err, type) {
|
|
8487
|
-
if (isAggregateError(err))
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
err
|
|
8492
|
-
}
|
|
8493
|
-
err = {
|
|
8494
|
-
type,
|
|
8495
|
-
message: err
|
|
8496
|
-
};
|
|
8497
|
-
}
|
|
8236
|
+
if (isAggregateError(err)) return err.errors.forEach((error) => this.catchError(error, type));
|
|
8237
|
+
if (err === Object(err)) err.type = type;
|
|
8238
|
+
else err = {
|
|
8239
|
+
type,
|
|
8240
|
+
message: err
|
|
8241
|
+
};
|
|
8498
8242
|
const _err = err;
|
|
8499
8243
|
if (_err && typeof _err === "object" && _err.code === "VITEST_PENDING") {
|
|
8500
8244
|
const task = this.idMap.get(_err.taskId);
|
|
@@ -8527,17 +8271,11 @@ class StateManager {
|
|
|
8527
8271
|
* Return files that were running or collected.
|
|
8528
8272
|
*/
|
|
8529
8273
|
getFiles(keys) {
|
|
8530
|
-
if (keys)
|
|
8531
|
-
return keys.map((key) => this.filesMap.get(key)).flat().filter((file) => file && !file.local);
|
|
8532
|
-
}
|
|
8274
|
+
if (keys) return keys.map((key) => this.filesMap.get(key)).flat().filter((file) => file && !file.local);
|
|
8533
8275
|
return Array.from(this.filesMap.values()).flat().filter((file) => !file.local).sort((f1, f2) => {
|
|
8534
8276
|
// print typecheck files first
|
|
8535
|
-
if (f1.meta?.typecheck && f2.meta?.typecheck)
|
|
8536
|
-
|
|
8537
|
-
}
|
|
8538
|
-
if (f1.meta?.typecheck) {
|
|
8539
|
-
return -1;
|
|
8540
|
-
}
|
|
8277
|
+
if (f1.meta?.typecheck && f2.meta?.typecheck) return 0;
|
|
8278
|
+
if (f1.meta?.typecheck) return -1;
|
|
8541
8279
|
return 1;
|
|
8542
8280
|
});
|
|
8543
8281
|
}
|
|
@@ -8562,9 +8300,7 @@ class StateManager {
|
|
|
8562
8300
|
const currentFile = existing.find((i) => i.projectName === file.projectName);
|
|
8563
8301
|
// keep logs for the previous file because it should always be initiated before the collections phase
|
|
8564
8302
|
// which means that all logs are collected during the collection and not inside tests
|
|
8565
|
-
if (currentFile)
|
|
8566
|
-
file.logs = currentFile.logs;
|
|
8567
|
-
}
|
|
8303
|
+
if (currentFile) file.logs = currentFile.logs;
|
|
8568
8304
|
otherFiles.push(file);
|
|
8569
8305
|
this.filesMap.set(file.filepath, otherFiles);
|
|
8570
8306
|
this.updateId(file, project);
|
|
@@ -8583,30 +8319,19 @@ class StateManager {
|
|
|
8583
8319
|
}
|
|
8584
8320
|
const filtered = files.filter((file) => file.projectName !== project.config.name);
|
|
8585
8321
|
// always keep a File task, so we can associate logs with it
|
|
8586
|
-
if (!filtered.length)
|
|
8587
|
-
|
|
8588
|
-
} else {
|
|
8589
|
-
this.filesMap.set(path, [...filtered, fileTask]);
|
|
8590
|
-
}
|
|
8322
|
+
if (!filtered.length) this.filesMap.set(path, [fileTask]);
|
|
8323
|
+
else this.filesMap.set(path, [...filtered, fileTask]);
|
|
8591
8324
|
});
|
|
8592
8325
|
}
|
|
8593
8326
|
updateId(task, project) {
|
|
8594
|
-
if (this.idMap.get(task.id) === task)
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
TestModule.register(task, project);
|
|
8599
|
-
} else if (task.type === "suite") {
|
|
8600
|
-
TestSuite.register(task, project);
|
|
8601
|
-
} else {
|
|
8602
|
-
TestCase.register(task, project);
|
|
8603
|
-
}
|
|
8327
|
+
if (this.idMap.get(task.id) === task) return;
|
|
8328
|
+
if (task.type === "suite" && "filepath" in task) TestModule.register(task, project);
|
|
8329
|
+
else if (task.type === "suite") TestSuite.register(task, project);
|
|
8330
|
+
else TestCase.register(task, project);
|
|
8604
8331
|
this.idMap.set(task.id, task);
|
|
8605
|
-
if (task.type === "suite") {
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
});
|
|
8609
|
-
}
|
|
8332
|
+
if (task.type === "suite") task.tasks.forEach((task) => {
|
|
8333
|
+
this.updateId(task, project);
|
|
8334
|
+
});
|
|
8610
8335
|
}
|
|
8611
8336
|
getReportedEntity(task) {
|
|
8612
8337
|
return this.reportedTasksMap.get(task);
|
|
@@ -8618,18 +8343,14 @@ class StateManager {
|
|
|
8618
8343
|
task.result = result;
|
|
8619
8344
|
task.meta = meta;
|
|
8620
8345
|
// skipped with new PendingError
|
|
8621
|
-
if (result?.state === "skip")
|
|
8622
|
-
task.mode = "skip";
|
|
8623
|
-
}
|
|
8346
|
+
if (result?.state === "skip") task.mode = "skip";
|
|
8624
8347
|
}
|
|
8625
8348
|
}
|
|
8626
8349
|
}
|
|
8627
8350
|
updateUserLog(log) {
|
|
8628
8351
|
const task = log.taskId && this.idMap.get(log.taskId);
|
|
8629
8352
|
if (task) {
|
|
8630
|
-
if (!task.logs)
|
|
8631
|
-
task.logs = [];
|
|
8632
|
-
}
|
|
8353
|
+
if (!task.logs) task.logs = [];
|
|
8633
8354
|
task.logs.push(log);
|
|
8634
8355
|
}
|
|
8635
8356
|
}
|
|
@@ -8641,6 +8362,458 @@ class StateManager {
|
|
|
8641
8362
|
}
|
|
8642
8363
|
}
|
|
8643
8364
|
|
|
8365
|
+
const types = {
|
|
8366
|
+
'application/andrew-inset': ['ez'],
|
|
8367
|
+
'application/appinstaller': ['appinstaller'],
|
|
8368
|
+
'application/applixware': ['aw'],
|
|
8369
|
+
'application/appx': ['appx'],
|
|
8370
|
+
'application/appxbundle': ['appxbundle'],
|
|
8371
|
+
'application/atom+xml': ['atom'],
|
|
8372
|
+
'application/atomcat+xml': ['atomcat'],
|
|
8373
|
+
'application/atomdeleted+xml': ['atomdeleted'],
|
|
8374
|
+
'application/atomsvc+xml': ['atomsvc'],
|
|
8375
|
+
'application/atsc-dwd+xml': ['dwd'],
|
|
8376
|
+
'application/atsc-held+xml': ['held'],
|
|
8377
|
+
'application/atsc-rsat+xml': ['rsat'],
|
|
8378
|
+
'application/automationml-aml+xml': ['aml'],
|
|
8379
|
+
'application/automationml-amlx+zip': ['amlx'],
|
|
8380
|
+
'application/bdoc': ['bdoc'],
|
|
8381
|
+
'application/calendar+xml': ['xcs'],
|
|
8382
|
+
'application/ccxml+xml': ['ccxml'],
|
|
8383
|
+
'application/cdfx+xml': ['cdfx'],
|
|
8384
|
+
'application/cdmi-capability': ['cdmia'],
|
|
8385
|
+
'application/cdmi-container': ['cdmic'],
|
|
8386
|
+
'application/cdmi-domain': ['cdmid'],
|
|
8387
|
+
'application/cdmi-object': ['cdmio'],
|
|
8388
|
+
'application/cdmi-queue': ['cdmiq'],
|
|
8389
|
+
'application/cpl+xml': ['cpl'],
|
|
8390
|
+
'application/cu-seeme': ['cu'],
|
|
8391
|
+
'application/cwl': ['cwl'],
|
|
8392
|
+
'application/dash+xml': ['mpd'],
|
|
8393
|
+
'application/dash-patch+xml': ['mpp'],
|
|
8394
|
+
'application/davmount+xml': ['davmount'],
|
|
8395
|
+
'application/dicom': ['dcm'],
|
|
8396
|
+
'application/docbook+xml': ['dbk'],
|
|
8397
|
+
'application/dssc+der': ['dssc'],
|
|
8398
|
+
'application/dssc+xml': ['xdssc'],
|
|
8399
|
+
'application/ecmascript': ['ecma'],
|
|
8400
|
+
'application/emma+xml': ['emma'],
|
|
8401
|
+
'application/emotionml+xml': ['emotionml'],
|
|
8402
|
+
'application/epub+zip': ['epub'],
|
|
8403
|
+
'application/exi': ['exi'],
|
|
8404
|
+
'application/express': ['exp'],
|
|
8405
|
+
'application/fdf': ['fdf'],
|
|
8406
|
+
'application/fdt+xml': ['fdt'],
|
|
8407
|
+
'application/font-tdpfr': ['pfr'],
|
|
8408
|
+
'application/geo+json': ['geojson'],
|
|
8409
|
+
'application/gml+xml': ['gml'],
|
|
8410
|
+
'application/gpx+xml': ['gpx'],
|
|
8411
|
+
'application/gxf': ['gxf'],
|
|
8412
|
+
'application/gzip': ['gz'],
|
|
8413
|
+
'application/hjson': ['hjson'],
|
|
8414
|
+
'application/hyperstudio': ['stk'],
|
|
8415
|
+
'application/inkml+xml': ['ink', 'inkml'],
|
|
8416
|
+
'application/ipfix': ['ipfix'],
|
|
8417
|
+
'application/its+xml': ['its'],
|
|
8418
|
+
'application/java-archive': ['jar', 'war', 'ear'],
|
|
8419
|
+
'application/java-serialized-object': ['ser'],
|
|
8420
|
+
'application/java-vm': ['class'],
|
|
8421
|
+
'application/javascript': ['*js'],
|
|
8422
|
+
'application/json': ['json', 'map'],
|
|
8423
|
+
'application/json5': ['json5'],
|
|
8424
|
+
'application/jsonml+json': ['jsonml'],
|
|
8425
|
+
'application/ld+json': ['jsonld'],
|
|
8426
|
+
'application/lgr+xml': ['lgr'],
|
|
8427
|
+
'application/lost+xml': ['lostxml'],
|
|
8428
|
+
'application/mac-binhex40': ['hqx'],
|
|
8429
|
+
'application/mac-compactpro': ['cpt'],
|
|
8430
|
+
'application/mads+xml': ['mads'],
|
|
8431
|
+
'application/manifest+json': ['webmanifest'],
|
|
8432
|
+
'application/marc': ['mrc'],
|
|
8433
|
+
'application/marcxml+xml': ['mrcx'],
|
|
8434
|
+
'application/mathematica': ['ma', 'nb', 'mb'],
|
|
8435
|
+
'application/mathml+xml': ['mathml'],
|
|
8436
|
+
'application/mbox': ['mbox'],
|
|
8437
|
+
'application/media-policy-dataset+xml': ['mpf'],
|
|
8438
|
+
'application/mediaservercontrol+xml': ['mscml'],
|
|
8439
|
+
'application/metalink+xml': ['metalink'],
|
|
8440
|
+
'application/metalink4+xml': ['meta4'],
|
|
8441
|
+
'application/mets+xml': ['mets'],
|
|
8442
|
+
'application/mmt-aei+xml': ['maei'],
|
|
8443
|
+
'application/mmt-usd+xml': ['musd'],
|
|
8444
|
+
'application/mods+xml': ['mods'],
|
|
8445
|
+
'application/mp21': ['m21', 'mp21'],
|
|
8446
|
+
'application/mp4': ['*mp4', '*mpg4', 'mp4s', 'm4p'],
|
|
8447
|
+
'application/msix': ['msix'],
|
|
8448
|
+
'application/msixbundle': ['msixbundle'],
|
|
8449
|
+
'application/msword': ['doc', 'dot'],
|
|
8450
|
+
'application/mxf': ['mxf'],
|
|
8451
|
+
'application/n-quads': ['nq'],
|
|
8452
|
+
'application/n-triples': ['nt'],
|
|
8453
|
+
'application/node': ['cjs'],
|
|
8454
|
+
'application/octet-stream': [
|
|
8455
|
+
'bin',
|
|
8456
|
+
'dms',
|
|
8457
|
+
'lrf',
|
|
8458
|
+
'mar',
|
|
8459
|
+
'so',
|
|
8460
|
+
'dist',
|
|
8461
|
+
'distz',
|
|
8462
|
+
'pkg',
|
|
8463
|
+
'bpk',
|
|
8464
|
+
'dump',
|
|
8465
|
+
'elc',
|
|
8466
|
+
'deploy',
|
|
8467
|
+
'exe',
|
|
8468
|
+
'dll',
|
|
8469
|
+
'deb',
|
|
8470
|
+
'dmg',
|
|
8471
|
+
'iso',
|
|
8472
|
+
'img',
|
|
8473
|
+
'msi',
|
|
8474
|
+
'msp',
|
|
8475
|
+
'msm',
|
|
8476
|
+
'buffer',
|
|
8477
|
+
],
|
|
8478
|
+
'application/oda': ['oda'],
|
|
8479
|
+
'application/oebps-package+xml': ['opf'],
|
|
8480
|
+
'application/ogg': ['ogx'],
|
|
8481
|
+
'application/omdoc+xml': ['omdoc'],
|
|
8482
|
+
'application/onenote': [
|
|
8483
|
+
'onetoc',
|
|
8484
|
+
'onetoc2',
|
|
8485
|
+
'onetmp',
|
|
8486
|
+
'onepkg',
|
|
8487
|
+
'one',
|
|
8488
|
+
'onea',
|
|
8489
|
+
],
|
|
8490
|
+
'application/oxps': ['oxps'],
|
|
8491
|
+
'application/p2p-overlay+xml': ['relo'],
|
|
8492
|
+
'application/patch-ops-error+xml': ['xer'],
|
|
8493
|
+
'application/pdf': ['pdf'],
|
|
8494
|
+
'application/pgp-encrypted': ['pgp'],
|
|
8495
|
+
'application/pgp-keys': ['asc'],
|
|
8496
|
+
'application/pgp-signature': ['sig', '*asc'],
|
|
8497
|
+
'application/pics-rules': ['prf'],
|
|
8498
|
+
'application/pkcs10': ['p10'],
|
|
8499
|
+
'application/pkcs7-mime': ['p7m', 'p7c'],
|
|
8500
|
+
'application/pkcs7-signature': ['p7s'],
|
|
8501
|
+
'application/pkcs8': ['p8'],
|
|
8502
|
+
'application/pkix-attr-cert': ['ac'],
|
|
8503
|
+
'application/pkix-cert': ['cer'],
|
|
8504
|
+
'application/pkix-crl': ['crl'],
|
|
8505
|
+
'application/pkix-pkipath': ['pkipath'],
|
|
8506
|
+
'application/pkixcmp': ['pki'],
|
|
8507
|
+
'application/pls+xml': ['pls'],
|
|
8508
|
+
'application/postscript': ['ai', 'eps', 'ps'],
|
|
8509
|
+
'application/provenance+xml': ['provx'],
|
|
8510
|
+
'application/pskc+xml': ['pskcxml'],
|
|
8511
|
+
'application/raml+yaml': ['raml'],
|
|
8512
|
+
'application/rdf+xml': ['rdf', 'owl'],
|
|
8513
|
+
'application/reginfo+xml': ['rif'],
|
|
8514
|
+
'application/relax-ng-compact-syntax': ['rnc'],
|
|
8515
|
+
'application/resource-lists+xml': ['rl'],
|
|
8516
|
+
'application/resource-lists-diff+xml': ['rld'],
|
|
8517
|
+
'application/rls-services+xml': ['rs'],
|
|
8518
|
+
'application/route-apd+xml': ['rapd'],
|
|
8519
|
+
'application/route-s-tsid+xml': ['sls'],
|
|
8520
|
+
'application/route-usd+xml': ['rusd'],
|
|
8521
|
+
'application/rpki-ghostbusters': ['gbr'],
|
|
8522
|
+
'application/rpki-manifest': ['mft'],
|
|
8523
|
+
'application/rpki-roa': ['roa'],
|
|
8524
|
+
'application/rsd+xml': ['rsd'],
|
|
8525
|
+
'application/rss+xml': ['rss'],
|
|
8526
|
+
'application/rtf': ['rtf'],
|
|
8527
|
+
'application/sbml+xml': ['sbml'],
|
|
8528
|
+
'application/scvp-cv-request': ['scq'],
|
|
8529
|
+
'application/scvp-cv-response': ['scs'],
|
|
8530
|
+
'application/scvp-vp-request': ['spq'],
|
|
8531
|
+
'application/scvp-vp-response': ['spp'],
|
|
8532
|
+
'application/sdp': ['sdp'],
|
|
8533
|
+
'application/senml+xml': ['senmlx'],
|
|
8534
|
+
'application/sensml+xml': ['sensmlx'],
|
|
8535
|
+
'application/set-payment-initiation': ['setpay'],
|
|
8536
|
+
'application/set-registration-initiation': ['setreg'],
|
|
8537
|
+
'application/shf+xml': ['shf'],
|
|
8538
|
+
'application/sieve': ['siv', 'sieve'],
|
|
8539
|
+
'application/smil+xml': ['smi', 'smil'],
|
|
8540
|
+
'application/sparql-query': ['rq'],
|
|
8541
|
+
'application/sparql-results+xml': ['srx'],
|
|
8542
|
+
'application/sql': ['sql'],
|
|
8543
|
+
'application/srgs': ['gram'],
|
|
8544
|
+
'application/srgs+xml': ['grxml'],
|
|
8545
|
+
'application/sru+xml': ['sru'],
|
|
8546
|
+
'application/ssdl+xml': ['ssdl'],
|
|
8547
|
+
'application/ssml+xml': ['ssml'],
|
|
8548
|
+
'application/swid+xml': ['swidtag'],
|
|
8549
|
+
'application/tei+xml': ['tei', 'teicorpus'],
|
|
8550
|
+
'application/thraud+xml': ['tfi'],
|
|
8551
|
+
'application/timestamped-data': ['tsd'],
|
|
8552
|
+
'application/toml': ['toml'],
|
|
8553
|
+
'application/trig': ['trig'],
|
|
8554
|
+
'application/ttml+xml': ['ttml'],
|
|
8555
|
+
'application/ubjson': ['ubj'],
|
|
8556
|
+
'application/urc-ressheet+xml': ['rsheet'],
|
|
8557
|
+
'application/urc-targetdesc+xml': ['td'],
|
|
8558
|
+
'application/voicexml+xml': ['vxml'],
|
|
8559
|
+
'application/wasm': ['wasm'],
|
|
8560
|
+
'application/watcherinfo+xml': ['wif'],
|
|
8561
|
+
'application/widget': ['wgt'],
|
|
8562
|
+
'application/winhlp': ['hlp'],
|
|
8563
|
+
'application/wsdl+xml': ['wsdl'],
|
|
8564
|
+
'application/wspolicy+xml': ['wspolicy'],
|
|
8565
|
+
'application/xaml+xml': ['xaml'],
|
|
8566
|
+
'application/xcap-att+xml': ['xav'],
|
|
8567
|
+
'application/xcap-caps+xml': ['xca'],
|
|
8568
|
+
'application/xcap-diff+xml': ['xdf'],
|
|
8569
|
+
'application/xcap-el+xml': ['xel'],
|
|
8570
|
+
'application/xcap-ns+xml': ['xns'],
|
|
8571
|
+
'application/xenc+xml': ['xenc'],
|
|
8572
|
+
'application/xfdf': ['xfdf'],
|
|
8573
|
+
'application/xhtml+xml': ['xhtml', 'xht'],
|
|
8574
|
+
'application/xliff+xml': ['xlf'],
|
|
8575
|
+
'application/xml': ['xml', 'xsl', 'xsd', 'rng'],
|
|
8576
|
+
'application/xml-dtd': ['dtd'],
|
|
8577
|
+
'application/xop+xml': ['xop'],
|
|
8578
|
+
'application/xproc+xml': ['xpl'],
|
|
8579
|
+
'application/xslt+xml': ['*xsl', 'xslt'],
|
|
8580
|
+
'application/xspf+xml': ['xspf'],
|
|
8581
|
+
'application/xv+xml': ['mxml', 'xhvml', 'xvml', 'xvm'],
|
|
8582
|
+
'application/yang': ['yang'],
|
|
8583
|
+
'application/yin+xml': ['yin'],
|
|
8584
|
+
'application/zip': ['zip'],
|
|
8585
|
+
'application/zip+dotlottie': ['lottie'],
|
|
8586
|
+
'audio/3gpp': ['*3gpp'],
|
|
8587
|
+
'audio/aac': ['adts', 'aac'],
|
|
8588
|
+
'audio/adpcm': ['adp'],
|
|
8589
|
+
'audio/amr': ['amr'],
|
|
8590
|
+
'audio/basic': ['au', 'snd'],
|
|
8591
|
+
'audio/midi': ['mid', 'midi', 'kar', 'rmi'],
|
|
8592
|
+
'audio/mobile-xmf': ['mxmf'],
|
|
8593
|
+
'audio/mp3': ['*mp3'],
|
|
8594
|
+
'audio/mp4': ['m4a', 'mp4a', 'm4b'],
|
|
8595
|
+
'audio/mpeg': ['mpga', 'mp2', 'mp2a', 'mp3', 'm2a', 'm3a'],
|
|
8596
|
+
'audio/ogg': ['oga', 'ogg', 'spx', 'opus'],
|
|
8597
|
+
'audio/s3m': ['s3m'],
|
|
8598
|
+
'audio/silk': ['sil'],
|
|
8599
|
+
'audio/wav': ['wav'],
|
|
8600
|
+
'audio/wave': ['*wav'],
|
|
8601
|
+
'audio/webm': ['weba'],
|
|
8602
|
+
'audio/xm': ['xm'],
|
|
8603
|
+
'font/collection': ['ttc'],
|
|
8604
|
+
'font/otf': ['otf'],
|
|
8605
|
+
'font/ttf': ['ttf'],
|
|
8606
|
+
'font/woff': ['woff'],
|
|
8607
|
+
'font/woff2': ['woff2'],
|
|
8608
|
+
'image/aces': ['exr'],
|
|
8609
|
+
'image/apng': ['apng'],
|
|
8610
|
+
'image/avci': ['avci'],
|
|
8611
|
+
'image/avcs': ['avcs'],
|
|
8612
|
+
'image/avif': ['avif'],
|
|
8613
|
+
'image/bmp': ['bmp', 'dib'],
|
|
8614
|
+
'image/cgm': ['cgm'],
|
|
8615
|
+
'image/dicom-rle': ['drle'],
|
|
8616
|
+
'image/dpx': ['dpx'],
|
|
8617
|
+
'image/emf': ['emf'],
|
|
8618
|
+
'image/fits': ['fits'],
|
|
8619
|
+
'image/g3fax': ['g3'],
|
|
8620
|
+
'image/gif': ['gif'],
|
|
8621
|
+
'image/heic': ['heic'],
|
|
8622
|
+
'image/heic-sequence': ['heics'],
|
|
8623
|
+
'image/heif': ['heif'],
|
|
8624
|
+
'image/heif-sequence': ['heifs'],
|
|
8625
|
+
'image/hej2k': ['hej2'],
|
|
8626
|
+
'image/ief': ['ief'],
|
|
8627
|
+
'image/jaii': ['jaii'],
|
|
8628
|
+
'image/jais': ['jais'],
|
|
8629
|
+
'image/jls': ['jls'],
|
|
8630
|
+
'image/jp2': ['jp2', 'jpg2'],
|
|
8631
|
+
'image/jpeg': ['jpg', 'jpeg', 'jpe'],
|
|
8632
|
+
'image/jph': ['jph'],
|
|
8633
|
+
'image/jphc': ['jhc'],
|
|
8634
|
+
'image/jpm': ['jpm', 'jpgm'],
|
|
8635
|
+
'image/jpx': ['jpx', 'jpf'],
|
|
8636
|
+
'image/jxl': ['jxl'],
|
|
8637
|
+
'image/jxr': ['jxr'],
|
|
8638
|
+
'image/jxra': ['jxra'],
|
|
8639
|
+
'image/jxrs': ['jxrs'],
|
|
8640
|
+
'image/jxs': ['jxs'],
|
|
8641
|
+
'image/jxsc': ['jxsc'],
|
|
8642
|
+
'image/jxsi': ['jxsi'],
|
|
8643
|
+
'image/jxss': ['jxss'],
|
|
8644
|
+
'image/ktx': ['ktx'],
|
|
8645
|
+
'image/ktx2': ['ktx2'],
|
|
8646
|
+
'image/pjpeg': ['jfif'],
|
|
8647
|
+
'image/png': ['png'],
|
|
8648
|
+
'image/sgi': ['sgi'],
|
|
8649
|
+
'image/svg+xml': ['svg', 'svgz'],
|
|
8650
|
+
'image/t38': ['t38'],
|
|
8651
|
+
'image/tiff': ['tif', 'tiff'],
|
|
8652
|
+
'image/tiff-fx': ['tfx'],
|
|
8653
|
+
'image/webp': ['webp'],
|
|
8654
|
+
'image/wmf': ['wmf'],
|
|
8655
|
+
'message/disposition-notification': ['disposition-notification'],
|
|
8656
|
+
'message/global': ['u8msg'],
|
|
8657
|
+
'message/global-delivery-status': ['u8dsn'],
|
|
8658
|
+
'message/global-disposition-notification': ['u8mdn'],
|
|
8659
|
+
'message/global-headers': ['u8hdr'],
|
|
8660
|
+
'message/rfc822': ['eml', 'mime', 'mht', 'mhtml'],
|
|
8661
|
+
'model/3mf': ['3mf'],
|
|
8662
|
+
'model/gltf+json': ['gltf'],
|
|
8663
|
+
'model/gltf-binary': ['glb'],
|
|
8664
|
+
'model/iges': ['igs', 'iges'],
|
|
8665
|
+
'model/jt': ['jt'],
|
|
8666
|
+
'model/mesh': ['msh', 'mesh', 'silo'],
|
|
8667
|
+
'model/mtl': ['mtl'],
|
|
8668
|
+
'model/obj': ['obj'],
|
|
8669
|
+
'model/prc': ['prc'],
|
|
8670
|
+
'model/step': ['step', 'stp', 'stpnc', 'p21', '210'],
|
|
8671
|
+
'model/step+xml': ['stpx'],
|
|
8672
|
+
'model/step+zip': ['stpz'],
|
|
8673
|
+
'model/step-xml+zip': ['stpxz'],
|
|
8674
|
+
'model/stl': ['stl'],
|
|
8675
|
+
'model/u3d': ['u3d'],
|
|
8676
|
+
'model/vrml': ['wrl', 'vrml'],
|
|
8677
|
+
'model/x3d+binary': ['*x3db', 'x3dbz'],
|
|
8678
|
+
'model/x3d+fastinfoset': ['x3db'],
|
|
8679
|
+
'model/x3d+vrml': ['*x3dv', 'x3dvz'],
|
|
8680
|
+
'model/x3d+xml': ['x3d', 'x3dz'],
|
|
8681
|
+
'model/x3d-vrml': ['x3dv'],
|
|
8682
|
+
'text/cache-manifest': ['appcache', 'manifest'],
|
|
8683
|
+
'text/calendar': ['ics', 'ifb'],
|
|
8684
|
+
'text/coffeescript': ['coffee', 'litcoffee'],
|
|
8685
|
+
'text/css': ['css'],
|
|
8686
|
+
'text/csv': ['csv'],
|
|
8687
|
+
'text/html': ['html', 'htm', 'shtml'],
|
|
8688
|
+
'text/jade': ['jade'],
|
|
8689
|
+
'text/javascript': ['js', 'mjs'],
|
|
8690
|
+
'text/jsx': ['jsx'],
|
|
8691
|
+
'text/less': ['less'],
|
|
8692
|
+
'text/markdown': ['md', 'markdown'],
|
|
8693
|
+
'text/mathml': ['mml'],
|
|
8694
|
+
'text/mdx': ['mdx'],
|
|
8695
|
+
'text/n3': ['n3'],
|
|
8696
|
+
'text/plain': ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini'],
|
|
8697
|
+
'text/richtext': ['rtx'],
|
|
8698
|
+
'text/rtf': ['*rtf'],
|
|
8699
|
+
'text/sgml': ['sgml', 'sgm'],
|
|
8700
|
+
'text/shex': ['shex'],
|
|
8701
|
+
'text/slim': ['slim', 'slm'],
|
|
8702
|
+
'text/spdx': ['spdx'],
|
|
8703
|
+
'text/stylus': ['stylus', 'styl'],
|
|
8704
|
+
'text/tab-separated-values': ['tsv'],
|
|
8705
|
+
'text/troff': ['t', 'tr', 'roff', 'man', 'me', 'ms'],
|
|
8706
|
+
'text/turtle': ['ttl'],
|
|
8707
|
+
'text/uri-list': ['uri', 'uris', 'urls'],
|
|
8708
|
+
'text/vcard': ['vcard'],
|
|
8709
|
+
'text/vtt': ['vtt'],
|
|
8710
|
+
'text/wgsl': ['wgsl'],
|
|
8711
|
+
'text/xml': ['*xml'],
|
|
8712
|
+
'text/yaml': ['yaml', 'yml'],
|
|
8713
|
+
'video/3gpp': ['3gp', '3gpp'],
|
|
8714
|
+
'video/3gpp2': ['3g2'],
|
|
8715
|
+
'video/h261': ['h261'],
|
|
8716
|
+
'video/h263': ['h263'],
|
|
8717
|
+
'video/h264': ['h264'],
|
|
8718
|
+
'video/iso.segment': ['m4s'],
|
|
8719
|
+
'video/jpeg': ['jpgv'],
|
|
8720
|
+
'video/jpm': ['*jpm', '*jpgm'],
|
|
8721
|
+
'video/mj2': ['mj2', 'mjp2'],
|
|
8722
|
+
'video/mp2t': ['ts', 'm2t', 'm2ts', 'mts'],
|
|
8723
|
+
'video/mp4': ['mp4', 'mp4v', 'mpg4'],
|
|
8724
|
+
'video/mpeg': ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'],
|
|
8725
|
+
'video/ogg': ['ogv'],
|
|
8726
|
+
'video/quicktime': ['qt', 'mov'],
|
|
8727
|
+
'video/webm': ['webm'],
|
|
8728
|
+
};
|
|
8729
|
+
Object.freeze(types);
|
|
8730
|
+
|
|
8731
|
+
var __classPrivateFieldGet = ({} && {}.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8732
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
8733
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
8734
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
8735
|
+
};
|
|
8736
|
+
var _Mime_extensionToType, _Mime_typeToExtension, _Mime_typeToExtensions;
|
|
8737
|
+
class Mime {
|
|
8738
|
+
constructor(...args) {
|
|
8739
|
+
_Mime_extensionToType.set(this, new Map());
|
|
8740
|
+
_Mime_typeToExtension.set(this, new Map());
|
|
8741
|
+
_Mime_typeToExtensions.set(this, new Map());
|
|
8742
|
+
for (const arg of args) {
|
|
8743
|
+
this.define(arg);
|
|
8744
|
+
}
|
|
8745
|
+
}
|
|
8746
|
+
define(typeMap, force = false) {
|
|
8747
|
+
for (let [type, extensions] of Object.entries(typeMap)) {
|
|
8748
|
+
type = type.toLowerCase();
|
|
8749
|
+
extensions = extensions.map((ext) => ext.toLowerCase());
|
|
8750
|
+
if (!__classPrivateFieldGet(this, _Mime_typeToExtensions, "f").has(type)) {
|
|
8751
|
+
__classPrivateFieldGet(this, _Mime_typeToExtensions, "f").set(type, new Set());
|
|
8752
|
+
}
|
|
8753
|
+
const allExtensions = __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").get(type);
|
|
8754
|
+
let first = true;
|
|
8755
|
+
for (let extension of extensions) {
|
|
8756
|
+
const starred = extension.startsWith('*');
|
|
8757
|
+
extension = starred ? extension.slice(1) : extension;
|
|
8758
|
+
allExtensions?.add(extension);
|
|
8759
|
+
if (first) {
|
|
8760
|
+
__classPrivateFieldGet(this, _Mime_typeToExtension, "f").set(type, extension);
|
|
8761
|
+
}
|
|
8762
|
+
first = false;
|
|
8763
|
+
if (starred)
|
|
8764
|
+
continue;
|
|
8765
|
+
const currentType = __classPrivateFieldGet(this, _Mime_extensionToType, "f").get(extension);
|
|
8766
|
+
if (currentType && currentType != type && !force) {
|
|
8767
|
+
throw new Error(`"${type} -> ${extension}" conflicts with "${currentType} -> ${extension}". Pass \`force=true\` to override this definition.`);
|
|
8768
|
+
}
|
|
8769
|
+
__classPrivateFieldGet(this, _Mime_extensionToType, "f").set(extension, type);
|
|
8770
|
+
}
|
|
8771
|
+
}
|
|
8772
|
+
return this;
|
|
8773
|
+
}
|
|
8774
|
+
getType(path) {
|
|
8775
|
+
if (typeof path !== 'string')
|
|
8776
|
+
return null;
|
|
8777
|
+
const last = path.replace(/^.*[/\\]/s, '').toLowerCase();
|
|
8778
|
+
const ext = last.replace(/^.*\./s, '').toLowerCase();
|
|
8779
|
+
const hasPath = last.length < path.length;
|
|
8780
|
+
const hasDot = ext.length < last.length - 1;
|
|
8781
|
+
if (!hasDot && hasPath)
|
|
8782
|
+
return null;
|
|
8783
|
+
return __classPrivateFieldGet(this, _Mime_extensionToType, "f").get(ext) ?? null;
|
|
8784
|
+
}
|
|
8785
|
+
getExtension(type) {
|
|
8786
|
+
if (typeof type !== 'string')
|
|
8787
|
+
return null;
|
|
8788
|
+
type = type?.split?.(';')[0];
|
|
8789
|
+
return ((type && __classPrivateFieldGet(this, _Mime_typeToExtension, "f").get(type.trim().toLowerCase())) ?? null);
|
|
8790
|
+
}
|
|
8791
|
+
getAllExtensions(type) {
|
|
8792
|
+
if (typeof type !== 'string')
|
|
8793
|
+
return null;
|
|
8794
|
+
return __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").get(type.toLowerCase()) ?? null;
|
|
8795
|
+
}
|
|
8796
|
+
_freeze() {
|
|
8797
|
+
this.define = () => {
|
|
8798
|
+
throw new Error('define() not allowed for built-in Mime objects. See https://github.com/broofa/mime/blob/main/README.md#custom-mime-instances');
|
|
8799
|
+
};
|
|
8800
|
+
Object.freeze(this);
|
|
8801
|
+
for (const extensions of __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").values()) {
|
|
8802
|
+
Object.freeze(extensions);
|
|
8803
|
+
}
|
|
8804
|
+
return this;
|
|
8805
|
+
}
|
|
8806
|
+
_getTestState() {
|
|
8807
|
+
return {
|
|
8808
|
+
types: __classPrivateFieldGet(this, _Mime_extensionToType, "f"),
|
|
8809
|
+
extensions: __classPrivateFieldGet(this, _Mime_typeToExtension, "f"),
|
|
8810
|
+
};
|
|
8811
|
+
}
|
|
8812
|
+
}
|
|
8813
|
+
_Mime_extensionToType = new WeakMap(), _Mime_typeToExtension = new WeakMap(), _Mime_typeToExtensions = new WeakMap();
|
|
8814
|
+
|
|
8815
|
+
var mime = new Mime(types)._freeze();
|
|
8816
|
+
|
|
8644
8817
|
class TestRun {
|
|
8645
8818
|
constructor(vitest) {
|
|
8646
8819
|
this.vitest = vitest;
|
|
@@ -8668,62 +8841,61 @@ class TestRun {
|
|
|
8668
8841
|
this.vitest.state.updateUserLog(log);
|
|
8669
8842
|
await this.vitest.report("onUserConsoleLog", log);
|
|
8670
8843
|
}
|
|
8844
|
+
async annotate(testId, annotation) {
|
|
8845
|
+
const task = this.vitest.state.idMap.get(testId);
|
|
8846
|
+
const entity = task && this.vitest.state.getReportedEntity(task);
|
|
8847
|
+
assert$1(task && entity, `Entity must be found for task ${task?.name || testId}`);
|
|
8848
|
+
assert$1(entity.type === "test", `Annotation can only be added to a test, instead got ${entity.type}`);
|
|
8849
|
+
await this.resolveTestAttachment(entity, annotation);
|
|
8850
|
+
entity.task.annotations.push(annotation);
|
|
8851
|
+
await this.vitest.report("onTestCaseAnnotate", entity, annotation);
|
|
8852
|
+
return annotation;
|
|
8853
|
+
}
|
|
8671
8854
|
async updated(update, events) {
|
|
8672
8855
|
this.vitest.state.updateTasks(update);
|
|
8856
|
+
for (const [id, event, data] of events) await this.reportEvent(id, event, data).catch((error) => {
|
|
8857
|
+
this.vitest.state.catchError(serializeError(error), "Unhandled Reporter Error");
|
|
8858
|
+
});
|
|
8673
8859
|
// TODO: what is the order or reports here?
|
|
8674
8860
|
// "onTaskUpdate" in parallel with others or before all or after all?
|
|
8675
8861
|
// TODO: error handling - what happens if custom reporter throws an error?
|
|
8676
|
-
await this.vitest.report("onTaskUpdate", update);
|
|
8677
|
-
for (const [id, event] of events) {
|
|
8678
|
-
await this.reportEvent(id, event).catch((error) => {
|
|
8679
|
-
this.vitest.state.catchError(serializeError(error), "Unhandled Reporter Error");
|
|
8680
|
-
});
|
|
8681
|
-
}
|
|
8862
|
+
await this.vitest.report("onTaskUpdate", update, events);
|
|
8682
8863
|
}
|
|
8683
8864
|
async end(specifications, errors, coverage) {
|
|
8684
8865
|
// specification won't have the File task if they were filtered by the --shard command
|
|
8685
8866
|
const modules = specifications.map((spec) => spec.testModule).filter((s) => s != null);
|
|
8686
8867
|
const files = modules.map((m) => m.task);
|
|
8687
|
-
const state = this.vitest.isCancelling ? "interrupted" :
|
|
8868
|
+
const state = this.vitest.isCancelling ? "interrupted" : this.hasFailed(modules) ? "failed" : "passed";
|
|
8869
|
+
if (state !== "passed") process.exitCode = 1;
|
|
8688
8870
|
try {
|
|
8689
8871
|
await Promise.all([this.vitest.report("onTestRunEnd", modules, [...errors], state), this.vitest.report("onFinished", files, errors, coverage)]);
|
|
8690
8872
|
} finally {
|
|
8691
|
-
if (coverage)
|
|
8692
|
-
await this.vitest.report("onCoverage", coverage);
|
|
8693
|
-
}
|
|
8873
|
+
if (coverage) await this.vitest.report("onCoverage", coverage);
|
|
8694
8874
|
}
|
|
8695
8875
|
}
|
|
8696
|
-
|
|
8876
|
+
hasFailed(modules) {
|
|
8877
|
+
if (!modules.length) return !this.vitest.config.passWithNoTests;
|
|
8878
|
+
return modules.some((m) => !m.ok());
|
|
8879
|
+
}
|
|
8880
|
+
async reportEvent(id, event, data) {
|
|
8697
8881
|
const task = this.vitest.state.idMap.get(id);
|
|
8698
8882
|
const entity = task && this.vitest.state.getReportedEntity(task);
|
|
8699
8883
|
assert$1(task && entity, `Entity must be found for task ${task?.name || id}`);
|
|
8700
|
-
if (event === "suite-prepare" && entity.type === "suite")
|
|
8701
|
-
|
|
8702
|
-
}
|
|
8703
|
-
if (event === "suite-prepare" && entity.type === "module") {
|
|
8704
|
-
return await this.vitest.report("onTestModuleStart", entity);
|
|
8705
|
-
}
|
|
8884
|
+
if (event === "suite-prepare" && entity.type === "suite") return await this.vitest.report("onTestSuiteReady", entity);
|
|
8885
|
+
if (event === "suite-prepare" && entity.type === "module") return await this.vitest.report("onTestModuleStart", entity);
|
|
8706
8886
|
if (event === "suite-finished") {
|
|
8707
8887
|
assert$1(entity.type === "suite" || entity.type === "module", "Entity type must be suite or module");
|
|
8708
|
-
if (entity.state() === "skipped")
|
|
8709
|
-
|
|
8710
|
-
|
|
8711
|
-
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
await this.vitest.report("onTestModuleEnd", entity);
|
|
8716
|
-
} else {
|
|
8717
|
-
await this.vitest.report("onTestSuiteResult", entity);
|
|
8718
|
-
}
|
|
8888
|
+
if (entity.state() === "skipped")
|
|
8889
|
+
// everything inside suite or a module is skipped,
|
|
8890
|
+
// so we won't get any children events
|
|
8891
|
+
// we need to report everything manually
|
|
8892
|
+
await this.reportChildren(entity.children);
|
|
8893
|
+
if (entity.type === "module") await this.vitest.report("onTestModuleEnd", entity);
|
|
8894
|
+
else await this.vitest.report("onTestSuiteResult", entity);
|
|
8719
8895
|
return;
|
|
8720
8896
|
}
|
|
8721
|
-
if (event === "test-prepare" && entity.type === "test")
|
|
8722
|
-
|
|
8723
|
-
}
|
|
8724
|
-
if (event === "test-finished" && entity.type === "test") {
|
|
8725
|
-
return await this.vitest.report("onTestCaseResult", entity);
|
|
8726
|
-
}
|
|
8897
|
+
if (event === "test-prepare" && entity.type === "test") return await this.vitest.report("onTestCaseReady", entity);
|
|
8898
|
+
if (event === "test-finished" && entity.type === "test") return await this.vitest.report("onTestCaseResult", entity);
|
|
8727
8899
|
if (event.startsWith("before-hook") || event.startsWith("after-hook")) {
|
|
8728
8900
|
const isBefore = event.startsWith("before-hook");
|
|
8729
8901
|
const hook = entity.type === "test" ? {
|
|
@@ -8733,36 +8905,58 @@ class TestRun {
|
|
|
8733
8905
|
name: isBefore ? "beforeAll" : "afterAll",
|
|
8734
8906
|
entity
|
|
8735
8907
|
};
|
|
8736
|
-
if (event.endsWith("-start"))
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8908
|
+
if (event.endsWith("-start")) await this.vitest.report("onHookStart", hook);
|
|
8909
|
+
else await this.vitest.report("onHookEnd", hook);
|
|
8910
|
+
// this can only happen in --merge-reports, and annotation is already resolved
|
|
8911
|
+
if (event === "test-annotation") {
|
|
8912
|
+
const annotation = data?.annotation;
|
|
8913
|
+
assert$1(annotation && entity.type === "test");
|
|
8914
|
+
await this.vitest.report("onTestCaseAnnotate", entity, annotation);
|
|
8740
8915
|
}
|
|
8741
8916
|
}
|
|
8742
8917
|
}
|
|
8918
|
+
async resolveTestAttachment(test, annotation) {
|
|
8919
|
+
const project = test.project;
|
|
8920
|
+
const attachment = annotation.attachment;
|
|
8921
|
+
if (!attachment) return attachment;
|
|
8922
|
+
const path = attachment.path;
|
|
8923
|
+
if (path && !path.startsWith("http://") && !path.startsWith("https://")) {
|
|
8924
|
+
const currentPath = resolve(project.config.root, path);
|
|
8925
|
+
const hash = createHash("sha1").update(currentPath).digest("hex");
|
|
8926
|
+
const newPath = resolve(project.config.attachmentsDir, `${sanitizeFilePath(annotation.message)}-${hash}${extname(currentPath)}`);
|
|
8927
|
+
await mkdir(dirname(newPath), { recursive: true });
|
|
8928
|
+
await copyFile(currentPath, newPath);
|
|
8929
|
+
attachment.path = newPath;
|
|
8930
|
+
const contentType = attachment.contentType ?? mime.getType(basename(currentPath));
|
|
8931
|
+
attachment.contentType = contentType || void 0;
|
|
8932
|
+
}
|
|
8933
|
+
return attachment;
|
|
8934
|
+
}
|
|
8743
8935
|
async reportChildren(children) {
|
|
8744
|
-
for (const child of children) {
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
await this.vitest.report("onTestSuiteResult", child);
|
|
8752
|
-
}
|
|
8936
|
+
for (const child of children) if (child.type === "test") {
|
|
8937
|
+
await this.vitest.report("onTestCaseReady", child);
|
|
8938
|
+
await this.vitest.report("onTestCaseResult", child);
|
|
8939
|
+
} else {
|
|
8940
|
+
await this.vitest.report("onTestSuiteReady", child);
|
|
8941
|
+
await this.reportChildren(child.children);
|
|
8942
|
+
await this.vitest.report("onTestSuiteResult", child);
|
|
8753
8943
|
}
|
|
8754
8944
|
}
|
|
8755
8945
|
}
|
|
8946
|
+
function sanitizeFilePath(s) {
|
|
8947
|
+
// eslint-disable-next-line no-control-regex
|
|
8948
|
+
return s.replace(/[\x00-\x2C\x2E\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, "-");
|
|
8949
|
+
}
|
|
8756
8950
|
|
|
8757
8951
|
class VitestWatcher {
|
|
8758
8952
|
/**
|
|
8759
8953
|
* Modules that will be invalidated on the next run.
|
|
8760
8954
|
*/
|
|
8761
|
-
invalidates = new Set();
|
|
8955
|
+
invalidates = /* @__PURE__ */ new Set();
|
|
8762
8956
|
/**
|
|
8763
8957
|
* Test files that have changed and need to be rerun.
|
|
8764
8958
|
*/
|
|
8765
|
-
changedTests = new Set();
|
|
8959
|
+
changedTests = /* @__PURE__ */ new Set();
|
|
8766
8960
|
_onRerun = [];
|
|
8767
8961
|
constructor(vitest) {
|
|
8768
8962
|
this.vitest = vitest;
|
|
@@ -8780,9 +8974,7 @@ class VitestWatcher {
|
|
|
8780
8974
|
unregisterWatcher = noop;
|
|
8781
8975
|
registerWatcher() {
|
|
8782
8976
|
const watcher = this.vitest.vite.watcher;
|
|
8783
|
-
if (this.vitest.config.forceRerunTriggers.length)
|
|
8784
|
-
watcher.add(this.vitest.config.forceRerunTriggers);
|
|
8785
|
-
}
|
|
8977
|
+
if (this.vitest.config.forceRerunTriggers.length) watcher.add(this.vitest.config.forceRerunTriggers);
|
|
8786
8978
|
watcher.on("change", this.onChange);
|
|
8787
8979
|
watcher.on("unlink", this.onUnlink);
|
|
8788
8980
|
watcher.on("add", this.onAdd);
|
|
@@ -8798,9 +8990,7 @@ class VitestWatcher {
|
|
|
8798
8990
|
this._onRerun.forEach((cb) => cb(file));
|
|
8799
8991
|
}
|
|
8800
8992
|
getTestFilesFromWatcherTrigger(id) {
|
|
8801
|
-
if (!this.vitest.config.watchTriggerPatterns)
|
|
8802
|
-
return false;
|
|
8803
|
-
}
|
|
8993
|
+
if (!this.vitest.config.watchTriggerPatterns) return false;
|
|
8804
8994
|
let triggered = false;
|
|
8805
8995
|
this.vitest.config.watchTriggerPatterns.forEach((definition) => {
|
|
8806
8996
|
const exec = definition.pattern.exec(id);
|
|
@@ -8822,13 +9012,10 @@ class VitestWatcher {
|
|
|
8822
9012
|
this.vitest.logger.clearHighlightCache(id);
|
|
8823
9013
|
this.vitest.invalidateFile(id);
|
|
8824
9014
|
const testFiles = this.getTestFilesFromWatcherTrigger(id);
|
|
8825
|
-
if (testFiles)
|
|
8826
|
-
|
|
8827
|
-
} else {
|
|
9015
|
+
if (testFiles) this.scheduleRerun(id);
|
|
9016
|
+
else {
|
|
8828
9017
|
const needsRerun = this.handleFileChanged(id);
|
|
8829
|
-
if (needsRerun)
|
|
8830
|
-
this.scheduleRerun(id);
|
|
8831
|
-
}
|
|
9018
|
+
if (needsRerun) this.scheduleRerun(id);
|
|
8832
9019
|
}
|
|
8833
9020
|
};
|
|
8834
9021
|
onUnlink = (id) => {
|
|
@@ -8855,9 +9042,7 @@ class VitestWatcher {
|
|
|
8855
9042
|
let fileContent;
|
|
8856
9043
|
const matchingProjects = [];
|
|
8857
9044
|
this.vitest.projects.forEach((project) => {
|
|
8858
|
-
if (project.matchesTestGlob(id, () => fileContent ??= readFileSync(id, "utf-8")))
|
|
8859
|
-
matchingProjects.push(project);
|
|
8860
|
-
}
|
|
9045
|
+
if (project.matchesTestGlob(id, () => fileContent ??= readFileSync(id, "utf-8"))) matchingProjects.push(project);
|
|
8861
9046
|
});
|
|
8862
9047
|
if (matchingProjects.length > 0) {
|
|
8863
9048
|
this.changedTests.add(id);
|
|
@@ -8865,18 +9050,14 @@ class VitestWatcher {
|
|
|
8865
9050
|
} else {
|
|
8866
9051
|
// it's possible that file was already there but watcher triggered "add" event instead
|
|
8867
9052
|
const needsRerun = this.handleFileChanged(id);
|
|
8868
|
-
if (needsRerun)
|
|
8869
|
-
this.scheduleRerun(id);
|
|
8870
|
-
}
|
|
9053
|
+
if (needsRerun) this.scheduleRerun(id);
|
|
8871
9054
|
}
|
|
8872
9055
|
};
|
|
8873
9056
|
/**
|
|
8874
9057
|
* @returns A value indicating whether rerun is needed (changedTests was mutated)
|
|
8875
9058
|
*/
|
|
8876
9059
|
handleFileChanged(filepath) {
|
|
8877
|
-
if (this.changedTests.has(filepath) || this.invalidates.has(filepath))
|
|
8878
|
-
return false;
|
|
8879
|
-
}
|
|
9060
|
+
if (this.changedTests.has(filepath) || this.invalidates.has(filepath)) return false;
|
|
8880
9061
|
if (pm.isMatch(filepath, this.vitest.config.forceRerunTriggers)) {
|
|
8881
9062
|
this.vitest.state.getFilepaths().forEach((file) => this.changedTests.add(file));
|
|
8882
9063
|
return true;
|
|
@@ -8897,9 +9078,7 @@ class VitestWatcher {
|
|
|
8897
9078
|
const files = [];
|
|
8898
9079
|
for (const project of projects) {
|
|
8899
9080
|
const mods = project.browser?.vite.moduleGraph.getModulesByFile(filepath) || project.vite.moduleGraph.getModulesByFile(filepath);
|
|
8900
|
-
if (!mods || !mods.size)
|
|
8901
|
-
continue;
|
|
8902
|
-
}
|
|
9081
|
+
if (!mods || !mods.size) continue;
|
|
8903
9082
|
this.invalidates.add(filepath);
|
|
8904
9083
|
// one of test files that we already run, or one of test files that we can run
|
|
8905
9084
|
if (this.vitest.state.filesMap.has(filepath) || project._isCachedTestFile(filepath)) {
|
|
@@ -8908,20 +9087,12 @@ class VitestWatcher {
|
|
|
8908
9087
|
continue;
|
|
8909
9088
|
}
|
|
8910
9089
|
let rerun = false;
|
|
8911
|
-
for (const mod of mods) {
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
if (needsRerun) {
|
|
8918
|
-
rerun = true;
|
|
8919
|
-
}
|
|
8920
|
-
});
|
|
8921
|
-
}
|
|
8922
|
-
if (rerun) {
|
|
8923
|
-
files.push(filepath);
|
|
8924
|
-
}
|
|
9090
|
+
for (const mod of mods) mod.importers.forEach((i) => {
|
|
9091
|
+
if (!i.file) return;
|
|
9092
|
+
const needsRerun = this.handleFileChanged(i.file);
|
|
9093
|
+
if (needsRerun) rerun = true;
|
|
9094
|
+
});
|
|
9095
|
+
if (rerun) files.push(filepath);
|
|
8925
9096
|
}
|
|
8926
9097
|
return !!files.length;
|
|
8927
9098
|
}
|
|
@@ -8975,9 +9146,9 @@ class Vitest {
|
|
|
8975
9146
|
/** @internal */ _browserSessions = new BrowserSessions();
|
|
8976
9147
|
/** @internal */ _cliOptions = {};
|
|
8977
9148
|
/** @internal */ reporters = [];
|
|
8978
|
-
/** @internal */ vitenode =
|
|
8979
|
-
/** @internal */ runner =
|
|
8980
|
-
/** @internal */ _testRun =
|
|
9149
|
+
/** @internal */ vitenode = void 0;
|
|
9150
|
+
/** @internal */ runner = void 0;
|
|
9151
|
+
/** @internal */ _testRun = void 0;
|
|
8981
9152
|
isFirstRun = true;
|
|
8982
9153
|
restartsCount = 0;
|
|
8983
9154
|
specifications;
|
|
@@ -9062,14 +9233,14 @@ class Vitest {
|
|
|
9062
9233
|
this.restartsCount += 1;
|
|
9063
9234
|
this._browserLastPort = defaultBrowserPort;
|
|
9064
9235
|
this.pool?.close?.();
|
|
9065
|
-
this.pool =
|
|
9066
|
-
this.closingPromise =
|
|
9236
|
+
this.pool = void 0;
|
|
9237
|
+
this.closingPromise = void 0;
|
|
9067
9238
|
this.projects = [];
|
|
9068
9239
|
this.resolvedProjects = [];
|
|
9069
|
-
this._workspaceConfigPath =
|
|
9070
|
-
this.coverageProvider =
|
|
9071
|
-
this.runningPromise =
|
|
9072
|
-
this.coreWorkspaceProject =
|
|
9240
|
+
this._workspaceConfigPath = void 0;
|
|
9241
|
+
this.coverageProvider = void 0;
|
|
9242
|
+
this.runningPromise = void 0;
|
|
9243
|
+
this.coreWorkspaceProject = void 0;
|
|
9073
9244
|
this.specifications.clearCache();
|
|
9074
9245
|
this._onUserTestsRerun = [];
|
|
9075
9246
|
this._vite = server;
|
|
@@ -9079,9 +9250,7 @@ class Vitest {
|
|
|
9079
9250
|
this._cache = new VitestCache(this.version);
|
|
9080
9251
|
this._snapshot = new SnapshotManager({ ...resolved.snapshotOptions });
|
|
9081
9252
|
this._testRun = new TestRun(this);
|
|
9082
|
-
if (this.config.watch)
|
|
9083
|
-
this.watcher.registerWatcher();
|
|
9084
|
-
}
|
|
9253
|
+
if (this.config.watch) this.watcher.registerWatcher();
|
|
9085
9254
|
this.vitenode = new ViteNodeServer(server, this.config.server);
|
|
9086
9255
|
const node = this.vitenode;
|
|
9087
9256
|
this.runner = new ViteNodeRunner({
|
|
@@ -9132,24 +9301,15 @@ class Vitest {
|
|
|
9132
9301
|
}));
|
|
9133
9302
|
if (this._cliOptions.browser?.enabled) {
|
|
9134
9303
|
const browserProjects = this.projects.filter((p) => p.config.browser.enabled);
|
|
9135
|
-
if (!browserProjects.length)
|
|
9136
|
-
throw new Error(`Vitest received --browser flag, but no project had a browser configuration.`);
|
|
9137
|
-
}
|
|
9304
|
+
if (!browserProjects.length) throw new Error(`Vitest received --browser flag, but no project had a browser configuration.`);
|
|
9138
9305
|
}
|
|
9139
9306
|
if (!this.projects.length) {
|
|
9140
9307
|
const filter = toArray(resolved.project).join("\", \"");
|
|
9141
|
-
if (filter) {
|
|
9142
|
-
|
|
9143
|
-
} else {
|
|
9144
|
-
throw new Error(`Vitest wasn't able to resolve any project.`);
|
|
9145
|
-
}
|
|
9146
|
-
}
|
|
9147
|
-
if (!this.coreWorkspaceProject) {
|
|
9148
|
-
this.coreWorkspaceProject = TestProject._createBasicProject(this);
|
|
9149
|
-
}
|
|
9150
|
-
if (this.config.testNamePattern) {
|
|
9151
|
-
this.configOverride.testNamePattern = this.config.testNamePattern;
|
|
9308
|
+
if (filter) throw new Error(`No projects matched the filter "${filter}".`);
|
|
9309
|
+
else throw new Error(`Vitest wasn't able to resolve any project.`);
|
|
9152
9310
|
}
|
|
9311
|
+
if (!this.coreWorkspaceProject) this.coreWorkspaceProject = TestProject._createBasicProject(this);
|
|
9312
|
+
if (this.config.testNamePattern) this.configOverride.testNamePattern = this.config.testNamePattern;
|
|
9153
9313
|
this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray(resolved.benchmark?.reporters), this.runner) : await createReporters(resolved.reporters, this);
|
|
9154
9314
|
await Promise.all(this._onSetServer.map((fn) => fn()));
|
|
9155
9315
|
}
|
|
@@ -9160,7 +9320,7 @@ class Vitest {
|
|
|
9160
9320
|
*/
|
|
9161
9321
|
injectTestProject = async (config) => {
|
|
9162
9322
|
const currentNames = new Set(this.projects.map((p) => p.name));
|
|
9163
|
-
const projects = await resolveProjects(this, this._cliOptions,
|
|
9323
|
+
const projects = await resolveProjects(this, this._cliOptions, void 0, Array.isArray(config) ? config : [config], currentNames);
|
|
9164
9324
|
this.projects.push(...projects);
|
|
9165
9325
|
return projects;
|
|
9166
9326
|
};
|
|
@@ -9178,9 +9338,7 @@ class Vitest {
|
|
|
9178
9338
|
}
|
|
9179
9339
|
/** @internal */
|
|
9180
9340
|
_ensureRootProject() {
|
|
9181
|
-
if (this.coreWorkspaceProject)
|
|
9182
|
-
return this.coreWorkspaceProject;
|
|
9183
|
-
}
|
|
9341
|
+
if (this.coreWorkspaceProject) return this.coreWorkspaceProject;
|
|
9184
9342
|
this.coreWorkspaceProject = TestProject._createBasicProject(this);
|
|
9185
9343
|
return this.coreWorkspaceProject;
|
|
9186
9344
|
}
|
|
@@ -9192,9 +9350,7 @@ class Vitest {
|
|
|
9192
9350
|
* Return project that has the root (or "global") config.
|
|
9193
9351
|
*/
|
|
9194
9352
|
getRootProject() {
|
|
9195
|
-
if (!this.coreWorkspaceProject)
|
|
9196
|
-
throw new Error(`Root project is not initialized. This means that the Vite server was not established yet and the the workspace config is not resolved.`);
|
|
9197
|
-
}
|
|
9353
|
+
if (!this.coreWorkspaceProject) throw new Error(`Root project is not initialized. This means that the Vite server was not established yet and the the workspace config is not resolved.`);
|
|
9198
9354
|
return this.coreWorkspaceProject;
|
|
9199
9355
|
}
|
|
9200
9356
|
/**
|
|
@@ -9207,9 +9363,7 @@ class Vitest {
|
|
|
9207
9363
|
}
|
|
9208
9364
|
getProjectByName(name) {
|
|
9209
9365
|
const project = this.projects.find((p) => p.name === name) || this.coreWorkspaceProject || this.projects[0];
|
|
9210
|
-
if (!project) {
|
|
9211
|
-
throw new Error(`Project "${name}" was not found.`);
|
|
9212
|
-
}
|
|
9366
|
+
if (!project) throw new Error(`Project "${name}" was not found.`);
|
|
9213
9367
|
return project;
|
|
9214
9368
|
}
|
|
9215
9369
|
/**
|
|
@@ -9220,30 +9374,24 @@ class Vitest {
|
|
|
9220
9374
|
return this.runner.executeId(moduleId);
|
|
9221
9375
|
}
|
|
9222
9376
|
async resolveWorkspaceConfigPath() {
|
|
9223
|
-
if (typeof this.config.workspace === "string")
|
|
9224
|
-
return this.config.workspace;
|
|
9225
|
-
}
|
|
9377
|
+
if (typeof this.config.workspace === "string") return this.config.workspace;
|
|
9226
9378
|
const configDir = this.vite.config.configFile ? dirname(this.vite.config.configFile) : this.config.root;
|
|
9227
9379
|
const rootFiles = await promises.readdir(configDir);
|
|
9228
9380
|
const workspaceConfigName = workspacesFiles.find((configFile) => {
|
|
9229
9381
|
return rootFiles.includes(configFile);
|
|
9230
9382
|
});
|
|
9231
|
-
if (!workspaceConfigName)
|
|
9232
|
-
return undefined;
|
|
9233
|
-
}
|
|
9383
|
+
if (!workspaceConfigName) return void 0;
|
|
9234
9384
|
return join(configDir, workspaceConfigName);
|
|
9235
9385
|
}
|
|
9236
9386
|
async resolveProjects(cliOptions) {
|
|
9237
|
-
const names = new Set();
|
|
9387
|
+
const names = /* @__PURE__ */ new Set();
|
|
9238
9388
|
if (this.config.projects) {
|
|
9239
|
-
if (typeof this.config.workspace !== "undefined")
|
|
9240
|
-
|
|
9241
|
-
}
|
|
9242
|
-
return resolveProjects(this, cliOptions, undefined, this.config.projects, names);
|
|
9389
|
+
if (typeof this.config.workspace !== "undefined") this.logger.warn("Both `config.projects` and `config.workspace` are defined. Ignoring the `workspace` option.");
|
|
9390
|
+
return resolveProjects(this, cliOptions, void 0, this.config.projects, names);
|
|
9243
9391
|
}
|
|
9244
9392
|
if (Array.isArray(this.config.workspace)) {
|
|
9245
9393
|
this.logger.deprecate("The `workspace` option is deprecated and will be removed in the next major. To hide this warning, rename `workspace` option to `projects`.");
|
|
9246
|
-
return resolveProjects(this, cliOptions,
|
|
9394
|
+
return resolveProjects(this, cliOptions, void 0, this.config.workspace, names);
|
|
9247
9395
|
}
|
|
9248
9396
|
const workspaceConfigPath = await this.resolveWorkspaceConfigPath();
|
|
9249
9397
|
this._workspaceConfigPath = workspaceConfigPath;
|
|
@@ -9252,17 +9400,13 @@ class Vitest {
|
|
|
9252
9400
|
// user can filter projects with --project flag, `getDefaultTestProject`
|
|
9253
9401
|
// returns the project only if it matches the filter
|
|
9254
9402
|
const project = getDefaultTestProject(this);
|
|
9255
|
-
if (!project)
|
|
9256
|
-
return [];
|
|
9257
|
-
}
|
|
9403
|
+
if (!project) return [];
|
|
9258
9404
|
return resolveBrowserProjects(this, new Set([project.name]), [project]);
|
|
9259
9405
|
}
|
|
9260
9406
|
const configFile = this.vite.config.configFile ? resolve(this.vite.config.root, this.vite.config.configFile) : "the root config file";
|
|
9261
9407
|
this.logger.deprecate(`The workspace file is deprecated and will be removed in the next major. Please, use the \`projects\` field in ${configFile} instead.`);
|
|
9262
9408
|
const workspaceModule = await this.import(workspaceConfigPath);
|
|
9263
|
-
if (!workspaceModule.default || !Array.isArray(workspaceModule.default)) {
|
|
9264
|
-
throw new TypeError(`Workspace config file "${workspaceConfigPath}" must export a default array of project paths.`);
|
|
9265
|
-
}
|
|
9409
|
+
if (!workspaceModule.default || !Array.isArray(workspaceModule.default)) throw new TypeError(`Workspace config file "${workspaceConfigPath}" must export a default array of project paths.`);
|
|
9266
9410
|
return resolveProjects(this, cliOptions, workspaceConfigPath, workspaceModule.default, names);
|
|
9267
9411
|
}
|
|
9268
9412
|
/**
|
|
@@ -9273,9 +9417,7 @@ class Vitest {
|
|
|
9273
9417
|
return this.specifications.globTestSpecifications(filters);
|
|
9274
9418
|
}
|
|
9275
9419
|
async initCoverageProvider() {
|
|
9276
|
-
if (this.coverageProvider !==
|
|
9277
|
-
return;
|
|
9278
|
-
}
|
|
9420
|
+
if (this.coverageProvider !== void 0) return;
|
|
9279
9421
|
this.coverageProvider = await getCoverageProvider(this.config.coverage, this.runner);
|
|
9280
9422
|
if (this.coverageProvider) {
|
|
9281
9423
|
await this.coverageProvider.initialize(this);
|
|
@@ -9287,9 +9429,7 @@ class Vitest {
|
|
|
9287
9429
|
* Merge reports from multiple runs located in the specified directory (value from `--merge-reports` if not specified).
|
|
9288
9430
|
*/
|
|
9289
9431
|
async mergeReports(directory) {
|
|
9290
|
-
if (this.reporters.some((r) => r instanceof BlobReporter))
|
|
9291
|
-
throw new Error("Cannot merge reports when `--reporter=blob` is used. Remove blob reporter from the config first.");
|
|
9292
|
-
}
|
|
9432
|
+
if (this.reporters.some((r) => r instanceof BlobReporter)) throw new Error("Cannot merge reports when `--reporter=blob` is used. Remove blob reporter from the config first.");
|
|
9293
9433
|
const { files, errors, coverages, executionTimes } = await readBlobs(this.version, directory || this.config.mergeReports, this.projects);
|
|
9294
9434
|
this.state.blobs = {
|
|
9295
9435
|
files,
|
|
@@ -9302,17 +9442,12 @@ class Vitest {
|
|
|
9302
9442
|
const specifications = [];
|
|
9303
9443
|
for (const file of files) {
|
|
9304
9444
|
const project = this.getProjectByName(file.projectName || "");
|
|
9305
|
-
const specification = project.createSpecification(file.filepath,
|
|
9445
|
+
const specification = project.createSpecification(file.filepath, void 0, file.pool);
|
|
9306
9446
|
specifications.push(specification);
|
|
9307
9447
|
}
|
|
9308
9448
|
await this.report("onSpecsCollected", specifications.map((spec) => spec.toJSON()));
|
|
9309
9449
|
await this._testRun.start(specifications).catch(noop);
|
|
9310
|
-
for (const file of files)
|
|
9311
|
-
await this._reportFileTask(file);
|
|
9312
|
-
}
|
|
9313
|
-
if (hasFailed(files)) {
|
|
9314
|
-
process.exitCode = 1;
|
|
9315
|
-
}
|
|
9450
|
+
for (const file of files) await this._reportFileTask(file);
|
|
9316
9451
|
this._checkUnhandledErrors(errors);
|
|
9317
9452
|
await this._testRun.end(specifications, errors).catch(noop);
|
|
9318
9453
|
await this.initCoverageProvider();
|
|
@@ -9329,25 +9464,19 @@ class Vitest {
|
|
|
9329
9464
|
await this._testRun.collected(project, [file]).catch(noop);
|
|
9330
9465
|
const logs = [];
|
|
9331
9466
|
const { packs, events } = convertTasksToEvents(file, (task) => {
|
|
9332
|
-
if (task.logs)
|
|
9333
|
-
logs.push(...task.logs);
|
|
9334
|
-
}
|
|
9467
|
+
if (task.logs) logs.push(...task.logs);
|
|
9335
9468
|
});
|
|
9336
9469
|
logs.sort((log1, log2) => log1.time - log2.time);
|
|
9337
|
-
for (const log of logs)
|
|
9338
|
-
await this._testRun.log(log).catch(noop);
|
|
9339
|
-
}
|
|
9470
|
+
for (const log of logs) await this._testRun.log(log).catch(noop);
|
|
9340
9471
|
await this._testRun.updated(packs, events).catch(noop);
|
|
9341
9472
|
}
|
|
9342
9473
|
async collect(filters) {
|
|
9343
9474
|
const files = await this.specifications.getRelevantTestSpecifications(filters);
|
|
9344
9475
|
// if run with --changed, don't exit if no tests are found
|
|
9345
|
-
if (!files.length) {
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
};
|
|
9350
|
-
}
|
|
9476
|
+
if (!files.length) return {
|
|
9477
|
+
testModules: [],
|
|
9478
|
+
unhandledErrors: []
|
|
9479
|
+
};
|
|
9351
9480
|
return this.collectTests(files);
|
|
9352
9481
|
}
|
|
9353
9482
|
/** @deprecated use `getRelevantTestSpecifications` instead */
|
|
@@ -9376,24 +9505,16 @@ class Vitest {
|
|
|
9376
9505
|
} finally {
|
|
9377
9506
|
await this.report("onInit", this);
|
|
9378
9507
|
}
|
|
9379
|
-
this.filenamePattern = filters && filters?.length > 0 ? filters :
|
|
9508
|
+
this.filenamePattern = filters && filters?.length > 0 ? filters : void 0;
|
|
9380
9509
|
const files = await this.specifications.getRelevantTestSpecifications(filters);
|
|
9381
9510
|
// if run with --changed, don't exit if no tests are found
|
|
9382
9511
|
if (!files.length) {
|
|
9383
|
-
const throwAnError = !this.config.watch || !(this.config.changed || this.config.related?.length);
|
|
9384
9512
|
await this._testRun.start([]);
|
|
9385
9513
|
const coverage = await this.coverageProvider?.generateCoverage?.({ allTestsRun: true });
|
|
9386
|
-
// set exit code before calling `onTestRunEnd` so the lifecycle is consistent
|
|
9387
|
-
if (throwAnError) {
|
|
9388
|
-
const exitCode = this.config.passWithNoTests ? 0 : 1;
|
|
9389
|
-
process.exitCode = exitCode;
|
|
9390
|
-
}
|
|
9391
9514
|
await this._testRun.end([], [], coverage);
|
|
9392
9515
|
// Report coverage for uncovered files
|
|
9393
9516
|
await this.reportCoverage(coverage, true);
|
|
9394
|
-
if (
|
|
9395
|
-
throw new FilesNotFoundError(this.mode);
|
|
9396
|
-
}
|
|
9517
|
+
if (!this.config.watch || !(this.config.changed || this.config.related?.length)) throw new FilesNotFoundError(this.mode);
|
|
9397
9518
|
}
|
|
9398
9519
|
let testModules = {
|
|
9399
9520
|
testModules: [],
|
|
@@ -9404,9 +9525,7 @@ class Vitest {
|
|
|
9404
9525
|
await this.cache.stats.populateStats(this.config.root, files);
|
|
9405
9526
|
testModules = await this.runFiles(files, true);
|
|
9406
9527
|
}
|
|
9407
|
-
if (this.config.watch)
|
|
9408
|
-
await this.report("onWatcherStart");
|
|
9409
|
-
}
|
|
9528
|
+
if (this.config.watch) await this.report("onWatcherStart");
|
|
9410
9529
|
return testModules;
|
|
9411
9530
|
}
|
|
9412
9531
|
/**
|
|
@@ -9422,9 +9541,7 @@ class Vitest {
|
|
|
9422
9541
|
}
|
|
9423
9542
|
// populate test files cache so watch mode can trigger a file rerun
|
|
9424
9543
|
await this.globTestSpecifications();
|
|
9425
|
-
if (this.config.watch)
|
|
9426
|
-
await this.report("onWatcherStart");
|
|
9427
|
-
}
|
|
9544
|
+
if (this.config.watch) await this.report("onWatcherStart");
|
|
9428
9545
|
}
|
|
9429
9546
|
/**
|
|
9430
9547
|
* @deprecated remove when vscode extension supports "getModuleSpecifications"
|
|
@@ -9466,7 +9583,7 @@ class Vitest {
|
|
|
9466
9583
|
* @param allTestsRun Indicates whether all tests were run. This only matters for coverage.
|
|
9467
9584
|
*/
|
|
9468
9585
|
async rerunTestSpecifications(specifications, allTestsRun = false) {
|
|
9469
|
-
this.configOverride.testNamePattern =
|
|
9586
|
+
this.configOverride.testNamePattern = void 0;
|
|
9470
9587
|
const files = specifications.map((spec) => spec.moduleId);
|
|
9471
9588
|
await Promise.all([this.report("onWatcherRerun", files, "rerun test"), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
|
|
9472
9589
|
const result = await this.runTestSpecifications(specifications, allTestsRun);
|
|
@@ -9482,16 +9599,12 @@ class Vitest {
|
|
|
9482
9599
|
// schedule the new run
|
|
9483
9600
|
this.runningPromise = (async () => {
|
|
9484
9601
|
try {
|
|
9485
|
-
if (!this.pool)
|
|
9486
|
-
this.pool = createPool(this);
|
|
9487
|
-
}
|
|
9602
|
+
if (!this.pool) this.pool = createPool(this);
|
|
9488
9603
|
const invalidates = Array.from(this.watcher.invalidates);
|
|
9489
9604
|
this.watcher.invalidates.clear();
|
|
9490
9605
|
this.snapshot.clear();
|
|
9491
9606
|
this.state.clearErrors();
|
|
9492
|
-
if (!this.isFirstRun && this.config.coverage.cleanOnRerun)
|
|
9493
|
-
await this.coverageProvider?.clean();
|
|
9494
|
-
}
|
|
9607
|
+
if (!this.isFirstRun && this.config.coverage.cleanOnRerun) await this.coverageProvider?.clean();
|
|
9495
9608
|
await this.initializeGlobalSetup(specs);
|
|
9496
9609
|
try {
|
|
9497
9610
|
await this.pool.runTests(specs, invalidates);
|
|
@@ -9499,9 +9612,6 @@ class Vitest {
|
|
|
9499
9612
|
this.state.catchError(err, "Unhandled Error");
|
|
9500
9613
|
}
|
|
9501
9614
|
const files = this.state.getFiles();
|
|
9502
|
-
if (hasFailed(files)) {
|
|
9503
|
-
process.exitCode = 1;
|
|
9504
|
-
}
|
|
9505
9615
|
this.cache.results.updateResults(files);
|
|
9506
9616
|
try {
|
|
9507
9617
|
await this.cache.results.writeToCache();
|
|
@@ -9519,11 +9629,11 @@ class Vitest {
|
|
|
9519
9629
|
await this.reportCoverage(coverage, allTestsRun);
|
|
9520
9630
|
}
|
|
9521
9631
|
})().finally(() => {
|
|
9522
|
-
this.runningPromise =
|
|
9632
|
+
this.runningPromise = void 0;
|
|
9523
9633
|
this.isFirstRun = false;
|
|
9524
9634
|
// all subsequent runs will treat this as a fresh run
|
|
9525
9635
|
this.config.changed = false;
|
|
9526
|
-
this.config.related =
|
|
9636
|
+
this.config.related = void 0;
|
|
9527
9637
|
});
|
|
9528
9638
|
return await this.runningPromise;
|
|
9529
9639
|
}
|
|
@@ -9540,9 +9650,7 @@ class Vitest {
|
|
|
9540
9650
|
this.isCancelling = false;
|
|
9541
9651
|
// schedule the new run
|
|
9542
9652
|
this.runningPromise = (async () => {
|
|
9543
|
-
if (!this.pool)
|
|
9544
|
-
this.pool = createPool(this);
|
|
9545
|
-
}
|
|
9653
|
+
if (!this.pool) this.pool = createPool(this);
|
|
9546
9654
|
const invalidates = Array.from(this.watcher.invalidates);
|
|
9547
9655
|
this.watcher.invalidates.clear();
|
|
9548
9656
|
this.snapshot.clear();
|
|
@@ -9556,18 +9664,16 @@ class Vitest {
|
|
|
9556
9664
|
const files = this.state.getFiles();
|
|
9557
9665
|
// can only happen if there was a syntax error in describe block
|
|
9558
9666
|
// or there was an error importing a file
|
|
9559
|
-
if (hasFailed(files))
|
|
9560
|
-
process.exitCode = 1;
|
|
9561
|
-
}
|
|
9667
|
+
if (hasFailed(files)) process.exitCode = 1;
|
|
9562
9668
|
return {
|
|
9563
9669
|
testModules: this.state.getTestModules(),
|
|
9564
9670
|
unhandledErrors: this.state.getUnhandledErrors()
|
|
9565
9671
|
};
|
|
9566
9672
|
})().finally(() => {
|
|
9567
|
-
this.runningPromise =
|
|
9673
|
+
this.runningPromise = void 0;
|
|
9568
9674
|
// all subsequent runs will treat this as a fresh run
|
|
9569
9675
|
this.config.changed = false;
|
|
9570
|
-
this.config.related =
|
|
9676
|
+
this.config.related = void 0;
|
|
9571
9677
|
});
|
|
9572
9678
|
return await this.runningPromise;
|
|
9573
9679
|
}
|
|
@@ -9586,18 +9692,12 @@ class Vitest {
|
|
|
9586
9692
|
async initializeGlobalSetup(paths) {
|
|
9587
9693
|
const projects = new Set(paths.map((spec) => spec.project));
|
|
9588
9694
|
const coreProject = this.getRootProject();
|
|
9589
|
-
if (!projects.has(coreProject))
|
|
9590
|
-
|
|
9591
|
-
}
|
|
9592
|
-
for (const project of projects) {
|
|
9593
|
-
await project._initializeGlobalSetup();
|
|
9594
|
-
}
|
|
9695
|
+
if (!projects.has(coreProject)) projects.add(coreProject);
|
|
9696
|
+
for (const project of projects) await project._initializeGlobalSetup();
|
|
9595
9697
|
}
|
|
9596
9698
|
/** @internal */
|
|
9597
9699
|
async rerunFiles(files = this.state.getFilepaths(), trigger, allTestsRun = true, resetTestNamePattern = false) {
|
|
9598
|
-
if (resetTestNamePattern)
|
|
9599
|
-
this.configOverride.testNamePattern = undefined;
|
|
9600
|
-
}
|
|
9700
|
+
if (resetTestNamePattern) this.configOverride.testNamePattern = void 0;
|
|
9601
9701
|
if (this.filenamePattern) {
|
|
9602
9702
|
const filteredFiles = await this.globTestSpecifications(this.filenamePattern);
|
|
9603
9703
|
files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file));
|
|
@@ -9611,39 +9711,30 @@ class Vitest {
|
|
|
9611
9711
|
/** @internal */
|
|
9612
9712
|
async rerunTask(id) {
|
|
9613
9713
|
const task = this.state.idMap.get(id);
|
|
9614
|
-
if (!task) {
|
|
9615
|
-
throw new Error(`Task ${id} was not found`);
|
|
9616
|
-
}
|
|
9714
|
+
if (!task) throw new Error(`Task ${id} was not found`);
|
|
9617
9715
|
const taskNamePattern = task.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9618
9716
|
await this.changeNamePattern(taskNamePattern, [task.file.filepath], "tasks" in task ? "rerun suite" : "rerun test");
|
|
9619
9717
|
}
|
|
9620
9718
|
/** @internal */
|
|
9621
9719
|
async changeProjectName(pattern) {
|
|
9622
|
-
if (pattern === "")
|
|
9623
|
-
|
|
9624
|
-
} else {
|
|
9625
|
-
this.configOverride.project = [pattern];
|
|
9626
|
-
}
|
|
9720
|
+
if (pattern === "") this.configOverride.project = void 0;
|
|
9721
|
+
else this.configOverride.project = [pattern];
|
|
9627
9722
|
await this.vite.restart();
|
|
9628
9723
|
}
|
|
9629
9724
|
/** @internal */
|
|
9630
9725
|
async changeNamePattern(pattern, files = this.state.getFilepaths(), trigger) {
|
|
9631
9726
|
// Empty test name pattern should reset filename pattern as well
|
|
9632
|
-
if (pattern === "")
|
|
9633
|
-
|
|
9634
|
-
}
|
|
9635
|
-
const testNamePattern = pattern ? new RegExp(pattern) : undefined;
|
|
9727
|
+
if (pattern === "") this.filenamePattern = void 0;
|
|
9728
|
+
const testNamePattern = pattern ? new RegExp(pattern) : void 0;
|
|
9636
9729
|
this.configOverride.testNamePattern = testNamePattern;
|
|
9637
9730
|
// filter only test files that have tests matching the pattern
|
|
9638
|
-
if (testNamePattern) {
|
|
9639
|
-
files =
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
return !tasks.length || tasks.some((task) => testNamePattern.test(task.name));
|
|
9644
|
-
});
|
|
9731
|
+
if (testNamePattern) files = files.filter((filepath) => {
|
|
9732
|
+
const files = this.state.getFiles([filepath]);
|
|
9733
|
+
return !files.length || files.some((file) => {
|
|
9734
|
+
const tasks = getTasks(file);
|
|
9735
|
+
return !tasks.length || tasks.some((task) => testNamePattern.test(task.name));
|
|
9645
9736
|
});
|
|
9646
|
-
}
|
|
9737
|
+
});
|
|
9647
9738
|
await this.rerunFiles(files, trigger, pattern === "");
|
|
9648
9739
|
}
|
|
9649
9740
|
/** @internal */
|
|
@@ -9696,17 +9787,14 @@ class Vitest {
|
|
|
9696
9787
|
* This method doesn't run any tests.
|
|
9697
9788
|
*/
|
|
9698
9789
|
setGlobalTestNamePattern(pattern) {
|
|
9699
|
-
if (pattern instanceof RegExp)
|
|
9700
|
-
|
|
9701
|
-
} else {
|
|
9702
|
-
this.configOverride.testNamePattern = pattern ? new RegExp(pattern) : undefined;
|
|
9703
|
-
}
|
|
9790
|
+
if (pattern instanceof RegExp) this.configOverride.testNamePattern = pattern;
|
|
9791
|
+
else this.configOverride.testNamePattern = pattern ? new RegExp(pattern) : void 0;
|
|
9704
9792
|
}
|
|
9705
9793
|
/**
|
|
9706
9794
|
* Resets the global test name pattern. This method doesn't run any tests.
|
|
9707
9795
|
*/
|
|
9708
9796
|
resetGlobalTestNamePattern() {
|
|
9709
|
-
this.configOverride.testNamePattern =
|
|
9797
|
+
this.configOverride.testNamePattern = void 0;
|
|
9710
9798
|
}
|
|
9711
9799
|
_rerunTimer;
|
|
9712
9800
|
// we can't use a single `triggerId` yet because vscode extension relies on this
|
|
@@ -9716,18 +9804,14 @@ class Vitest {
|
|
|
9716
9804
|
await this.runningPromise;
|
|
9717
9805
|
clearTimeout(this._rerunTimer);
|
|
9718
9806
|
// server restarted
|
|
9719
|
-
if (this.restartsCount !== currentCount)
|
|
9720
|
-
return;
|
|
9721
|
-
}
|
|
9807
|
+
if (this.restartsCount !== currentCount) return;
|
|
9722
9808
|
this._rerunTimer = setTimeout(async () => {
|
|
9723
9809
|
if (this.watcher.changedTests.size === 0) {
|
|
9724
9810
|
this.watcher.invalidates.clear();
|
|
9725
9811
|
return;
|
|
9726
9812
|
}
|
|
9727
9813
|
// server restarted
|
|
9728
|
-
if (this.restartsCount !== currentCount)
|
|
9729
|
-
return;
|
|
9730
|
-
}
|
|
9814
|
+
if (this.restartsCount !== currentCount) return;
|
|
9731
9815
|
this.isFirstRun = false;
|
|
9732
9816
|
this.snapshot.clear();
|
|
9733
9817
|
let files = Array.from(this.watcher.changedTests);
|
|
@@ -9735,18 +9819,14 @@ class Vitest {
|
|
|
9735
9819
|
const filteredFiles = await this.globTestSpecifications(this.filenamePattern);
|
|
9736
9820
|
files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file));
|
|
9737
9821
|
// A file that does not match the current filename pattern was changed
|
|
9738
|
-
if (files.length === 0)
|
|
9739
|
-
return;
|
|
9740
|
-
}
|
|
9822
|
+
if (files.length === 0) return;
|
|
9741
9823
|
}
|
|
9742
9824
|
this.watcher.changedTests.clear();
|
|
9743
9825
|
const triggerIds = new Set(triggerId.map((id) => relative(this.config.root, id)));
|
|
9744
9826
|
const triggerLabel = Array.from(triggerIds).join(", ");
|
|
9745
9827
|
// get file specifications and filter them if needed
|
|
9746
9828
|
const specifications = files.flatMap((file) => this.getModuleSpecifications(file)).filter((specification) => {
|
|
9747
|
-
if (this._onFilterWatchedSpecification.length === 0)
|
|
9748
|
-
return true;
|
|
9749
|
-
}
|
|
9829
|
+
if (this._onFilterWatchedSpecification.length === 0) return true;
|
|
9750
9830
|
return this._onFilterWatchedSpecification.every((fn) => fn(specification));
|
|
9751
9831
|
});
|
|
9752
9832
|
await Promise.all([this.report("onWatcherRerun", files, triggerLabel), ...this._onUserTestsRerun.map((fn) => fn(specifications))]);
|
|
@@ -9773,25 +9853,17 @@ class Vitest {
|
|
|
9773
9853
|
}
|
|
9774
9854
|
/** @internal */
|
|
9775
9855
|
_checkUnhandledErrors(errors) {
|
|
9776
|
-
if (errors.length && !this.config.dangerouslyIgnoreUnhandledErrors)
|
|
9777
|
-
process.exitCode = 1;
|
|
9778
|
-
}
|
|
9856
|
+
if (errors.length && !this.config.dangerouslyIgnoreUnhandledErrors) process.exitCode = 1;
|
|
9779
9857
|
}
|
|
9780
9858
|
async reportCoverage(coverage, allTestsRun) {
|
|
9781
9859
|
if (this.state.getCountOfFailedTests() > 0) {
|
|
9782
9860
|
await this.coverageProvider?.onTestFailure?.();
|
|
9783
|
-
if (!this.config.coverage.reportOnFailure)
|
|
9784
|
-
return;
|
|
9785
|
-
}
|
|
9861
|
+
if (!this.config.coverage.reportOnFailure) return;
|
|
9786
9862
|
}
|
|
9787
9863
|
if (this.coverageProvider) {
|
|
9788
9864
|
await this.coverageProvider.reportCoverage(coverage, { allTestsRun });
|
|
9789
9865
|
// notify coverage iframe reload
|
|
9790
|
-
for (const reporter of this.reporters)
|
|
9791
|
-
if (reporter instanceof WebSocketReporter) {
|
|
9792
|
-
reporter.onFinishedReportCoverage();
|
|
9793
|
-
}
|
|
9794
|
-
}
|
|
9866
|
+
for (const reporter of this.reporters) if (reporter instanceof WebSocketReporter) reporter.onFinishedReportCoverage();
|
|
9795
9867
|
}
|
|
9796
9868
|
}
|
|
9797
9869
|
/**
|
|
@@ -9799,38 +9871,26 @@ class Vitest {
|
|
|
9799
9871
|
* This can only be called once; the closing promise is cached until the server restarts.
|
|
9800
9872
|
*/
|
|
9801
9873
|
async close() {
|
|
9802
|
-
if (!this.closingPromise) {
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
closePromises.push((async () => {
|
|
9820
|
-
await this.pool?.close?.();
|
|
9821
|
-
this.pool = undefined;
|
|
9822
|
-
})());
|
|
9823
|
-
}
|
|
9824
|
-
closePromises.push(...this._onClose.map((fn) => fn()));
|
|
9825
|
-
return Promise.allSettled(closePromises).then((results) => {
|
|
9826
|
-
results.forEach((r) => {
|
|
9827
|
-
if (r.status === "rejected") {
|
|
9828
|
-
this.logger.error("error during close", r.reason);
|
|
9829
|
-
}
|
|
9830
|
-
});
|
|
9874
|
+
if (!this.closingPromise) this.closingPromise = (async () => {
|
|
9875
|
+
const teardownProjects = [...this.projects];
|
|
9876
|
+
if (this.coreWorkspaceProject && !teardownProjects.includes(this.coreWorkspaceProject)) teardownProjects.push(this.coreWorkspaceProject);
|
|
9877
|
+
// do teardown before closing the server
|
|
9878
|
+
for (const project of teardownProjects.reverse()) await project._teardownGlobalSetup();
|
|
9879
|
+
const closePromises = this.projects.map((w) => w.close());
|
|
9880
|
+
// close the core workspace server only once
|
|
9881
|
+
// it's possible that it's not initialized at all because it's not running any tests
|
|
9882
|
+
if (this.coreWorkspaceProject && !this.projects.includes(this.coreWorkspaceProject)) closePromises.push(this.coreWorkspaceProject.close().then(() => this._vite = void 0));
|
|
9883
|
+
if (this.pool) closePromises.push((async () => {
|
|
9884
|
+
await this.pool?.close?.();
|
|
9885
|
+
this.pool = void 0;
|
|
9886
|
+
})());
|
|
9887
|
+
closePromises.push(...this._onClose.map((fn) => fn()));
|
|
9888
|
+
return Promise.allSettled(closePromises).then((results) => {
|
|
9889
|
+
results.forEach((r) => {
|
|
9890
|
+
if (r.status === "rejected") this.logger.error("error during close", r.reason);
|
|
9831
9891
|
});
|
|
9832
|
-
})
|
|
9833
|
-
}
|
|
9892
|
+
});
|
|
9893
|
+
})();
|
|
9834
9894
|
return this.closingPromise;
|
|
9835
9895
|
}
|
|
9836
9896
|
/**
|
|
@@ -9844,24 +9904,16 @@ class Vitest {
|
|
|
9844
9904
|
this.state.getProcessTimeoutCauses().forEach((cause) => console.warn(cause));
|
|
9845
9905
|
if (!this.pool) {
|
|
9846
9906
|
const runningServers = [this._vite, ...this.projects.map((p) => p._vite)].filter(Boolean).length;
|
|
9847
|
-
if (runningServers === 1)
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
} else {
|
|
9852
|
-
console.warn("Tests closed successfully but something prevents the main process from exiting");
|
|
9853
|
-
}
|
|
9854
|
-
if (!this.reporters.some((r) => r instanceof HangingProcessReporter)) {
|
|
9855
|
-
console.warn("You can try to identify the cause by enabling \"hanging-process\" reporter. See https://vitest.dev/config/#reporters");
|
|
9856
|
-
}
|
|
9907
|
+
if (runningServers === 1) console.warn("Tests closed successfully but something prevents Vite server from exiting");
|
|
9908
|
+
else if (runningServers > 1) console.warn(`Tests closed successfully but something prevents ${runningServers} Vite servers from exiting`);
|
|
9909
|
+
else console.warn("Tests closed successfully but something prevents the main process from exiting");
|
|
9910
|
+
if (!this.reporters.some((r) => r instanceof HangingProcessReporter)) console.warn("You can try to identify the cause by enabling \"hanging-process\" reporter. See https://vitest.dev/config/#reporters");
|
|
9857
9911
|
}
|
|
9858
9912
|
process.exit();
|
|
9859
9913
|
});
|
|
9860
9914
|
}, this.config.teardownTimeout).unref();
|
|
9861
9915
|
await this.close();
|
|
9862
|
-
if (force)
|
|
9863
|
-
process.exit();
|
|
9864
|
-
}
|
|
9916
|
+
if (force) process.exit();
|
|
9865
9917
|
}
|
|
9866
9918
|
/** @internal */
|
|
9867
9919
|
async report(name, ...args) {
|
|
@@ -9944,9 +9996,7 @@ class Vitest {
|
|
|
9944
9996
|
matchesProjectFilter(name) {
|
|
9945
9997
|
const projects = this._config?.project || this._cliOptions?.project;
|
|
9946
9998
|
// no filters applied, any project can be included
|
|
9947
|
-
if (!projects || !projects.length)
|
|
9948
|
-
return true;
|
|
9949
|
-
}
|
|
9999
|
+
if (!projects || !projects.length) return true;
|
|
9950
10000
|
return toArray(projects).some((project) => {
|
|
9951
10001
|
const regexp = wildcardPatternToRegExp(project);
|
|
9952
10002
|
return regexp.test(name);
|
|
@@ -9954,9 +10004,7 @@ class Vitest {
|
|
|
9954
10004
|
}
|
|
9955
10005
|
}
|
|
9956
10006
|
function assert(condition, property, name = property) {
|
|
9957
|
-
if (!condition) {
|
|
9958
|
-
throw new Error(`The ${name} was not set. It means that \`vitest.${property}\` was called before the Vite server was established. Await the Vitest promise before accessing \`vitest.${property}\`.`);
|
|
9959
|
-
}
|
|
10007
|
+
if (!condition) throw new Error(`The ${name} was not set. It means that \`vitest.${property}\` was called before the Vite server was established. Await the Vitest promise before accessing \`vitest.${property}\`.`);
|
|
9960
10008
|
}
|
|
9961
10009
|
|
|
9962
10010
|
async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(options))) {
|
|
@@ -9973,11 +10021,10 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
9973
10021
|
this.meta.watchMode = false;
|
|
9974
10022
|
},
|
|
9975
10023
|
async config(viteConfig) {
|
|
9976
|
-
if (options.watch)
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
}
|
|
10024
|
+
if (options.watch)
|
|
10025
|
+
// Earlier runs have overwritten values of the `options`.
|
|
10026
|
+
// Reset it back to initial user config before setting up the server again.
|
|
10027
|
+
options = deepMerge({}, userConfig);
|
|
9981
10028
|
// preliminary merge of options to be able to create server options for vite
|
|
9982
10029
|
// however to allow vitest plugins to modify vitest config values
|
|
9983
10030
|
// this is repeated in configResolved where the config is final
|
|
@@ -9988,9 +10035,7 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
9988
10035
|
const defines = deleteDefineConfig(viteConfig);
|
|
9989
10036
|
options.defines = defines;
|
|
9990
10037
|
let open = false;
|
|
9991
|
-
if (testConfig.ui && testConfig.open)
|
|
9992
|
-
open = testConfig.uiBase ?? "/__vitest__/";
|
|
9993
|
-
}
|
|
10038
|
+
if (testConfig.ui && testConfig.open) open = testConfig.uiBase ?? "/__vitest__/";
|
|
9994
10039
|
const resolveOptions = getDefaultResolveOptions();
|
|
9995
10040
|
const config = {
|
|
9996
10041
|
root: viteConfig.test?.root || options.root,
|
|
@@ -10008,7 +10053,7 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10008
10053
|
...testConfig.api,
|
|
10009
10054
|
open,
|
|
10010
10055
|
hmr: false,
|
|
10011
|
-
ws: testConfig.api?.middlewareMode ? false :
|
|
10056
|
+
ws: testConfig.api?.middlewareMode ? false : void 0,
|
|
10012
10057
|
preTransformRequests: false,
|
|
10013
10058
|
fs: { allow: resolveFsAllow(options.root || process.cwd(), testConfig.config) }
|
|
10014
10059
|
},
|
|
@@ -10026,56 +10071,43 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10026
10071
|
deps: testConfig.deps ?? viteConfig.test?.deps
|
|
10027
10072
|
}
|
|
10028
10073
|
};
|
|
10029
|
-
|
|
10030
|
-
|
|
10031
|
-
|
|
10032
|
-
|
|
10074
|
+
// inherit so it's available in VitestOptimizer
|
|
10075
|
+
// I cannot wait to rewrite all of this in Vitest 4
|
|
10076
|
+
if (options.cache != null) config.test.cache = options.cache;
|
|
10077
|
+
if (vitest.configOverride.project)
|
|
10078
|
+
// project filter was set by the user, so we need to filter the project
|
|
10079
|
+
options.project = vitest.configOverride.project;
|
|
10033
10080
|
config.customLogger = createViteLogger(vitest.logger, viteConfig.logLevel || "warn", { allowClearScreen: false });
|
|
10034
10081
|
config.customLogger = silenceImportViteIgnoreWarning(config.customLogger);
|
|
10035
10082
|
// we want inline dependencies to be resolved by analyser plugin so module graph is populated correctly
|
|
10036
10083
|
if (viteConfig.ssr?.noExternal !== true) {
|
|
10037
10084
|
const inline = testConfig.server?.deps?.inline;
|
|
10038
|
-
if (inline === true) {
|
|
10039
|
-
|
|
10040
|
-
} else {
|
|
10085
|
+
if (inline === true) config.ssr = { noExternal: true };
|
|
10086
|
+
else {
|
|
10041
10087
|
const noExternal = viteConfig.ssr?.noExternal;
|
|
10042
|
-
const noExternalArray = typeof noExternal !== "undefined" ? toArray(noExternal) :
|
|
10088
|
+
const noExternalArray = typeof noExternal !== "undefined" ? toArray(noExternal) : void 0;
|
|
10043
10089
|
// filter the same packages
|
|
10044
10090
|
const uniqueInline = inline && noExternalArray ? inline.filter((dep) => !noExternalArray.includes(dep)) : inline;
|
|
10045
10091
|
config.ssr = { noExternal: uniqueInline };
|
|
10046
10092
|
}
|
|
10047
10093
|
}
|
|
10048
10094
|
// chokidar fsevents is unstable on macos when emitting "ready" event
|
|
10049
|
-
if (process.platform === "darwin" &&
|
|
10050
|
-
const watch = config.server.watch;
|
|
10051
|
-
if (watch) {
|
|
10052
|
-
// eslint-disable-next-line ts/ban-ts-comment
|
|
10053
|
-
// @ts-ignore Vite 6 compat
|
|
10054
|
-
watch.useFsEvents = false;
|
|
10055
|
-
watch.usePolling = false;
|
|
10056
|
-
}
|
|
10057
|
-
}
|
|
10095
|
+
if (process.platform === "darwin" && false);
|
|
10058
10096
|
const classNameStrategy = typeof testConfig.css !== "boolean" && testConfig.css?.modules?.classNameStrategy || "stable";
|
|
10059
10097
|
if (classNameStrategy !== "scoped") {
|
|
10060
10098
|
config.css ??= {};
|
|
10061
10099
|
config.css.modules ??= {};
|
|
10062
|
-
if (config.css.modules) {
|
|
10063
|
-
config.
|
|
10064
|
-
|
|
10065
|
-
|
|
10066
|
-
};
|
|
10067
|
-
}
|
|
10100
|
+
if (config.css.modules) config.css.modules.generateScopedName = (name, filename) => {
|
|
10101
|
+
const root = vitest.config.root || options.root || process.cwd();
|
|
10102
|
+
return generateScopedClassName(classNameStrategy, name, relative(root, filename));
|
|
10103
|
+
};
|
|
10068
10104
|
}
|
|
10069
10105
|
return config;
|
|
10070
10106
|
},
|
|
10071
10107
|
async configResolved(viteConfig) {
|
|
10072
10108
|
const viteConfigTest = viteConfig.test || {};
|
|
10073
|
-
if (viteConfigTest.watch === false)
|
|
10074
|
-
|
|
10075
|
-
}
|
|
10076
|
-
if ("alias" in viteConfigTest) {
|
|
10077
|
-
delete viteConfigTest.alias;
|
|
10078
|
-
}
|
|
10109
|
+
if (viteConfigTest.watch === false) viteConfigTest.run = true;
|
|
10110
|
+
if ("alias" in viteConfigTest) delete viteConfigTest.alias;
|
|
10079
10111
|
// viteConfig.test is final now, merge it for real
|
|
10080
10112
|
options = deepMerge({}, configDefaults, viteConfigTest, options);
|
|
10081
10113
|
options.api = resolveApiServerConfig(options, defaultPort);
|
|
@@ -10086,42 +10118,27 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10086
10118
|
// so we are making them truthy
|
|
10087
10119
|
process.env.PROD ??= PROD ? "1" : "";
|
|
10088
10120
|
process.env.DEV ??= DEV ? "1" : "";
|
|
10089
|
-
for (const name in envs)
|
|
10090
|
-
process.env[name] ??= envs[name];
|
|
10091
|
-
}
|
|
10121
|
+
for (const name in envs) process.env[name] ??= envs[name];
|
|
10092
10122
|
// don't watch files in run mode
|
|
10093
|
-
if (!options.watch)
|
|
10094
|
-
viteConfig.server.watch = null;
|
|
10095
|
-
}
|
|
10123
|
+
if (!options.watch) viteConfig.server.watch = null;
|
|
10096
10124
|
Object.defineProperty(viteConfig, "_vitest", {
|
|
10097
10125
|
value: options,
|
|
10098
10126
|
enumerable: false,
|
|
10099
10127
|
configurable: true
|
|
10100
10128
|
});
|
|
10101
10129
|
const originalName = options.name;
|
|
10102
|
-
if (options.browser?.instances) {
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
});
|
|
10106
|
-
}
|
|
10130
|
+
if (options.browser?.instances) options.browser.instances.forEach((instance) => {
|
|
10131
|
+
instance.name ??= originalName ? `${originalName} (${instance.browser})` : instance.browser;
|
|
10132
|
+
});
|
|
10107
10133
|
},
|
|
10108
10134
|
configureServer: {
|
|
10109
10135
|
order: "post",
|
|
10110
10136
|
async handler(server) {
|
|
10111
|
-
if (options.watch &&
|
|
10112
|
-
server.watcher.on("ready", () => {
|
|
10113
|
-
// eslint-disable-next-line no-console
|
|
10114
|
-
console.log("[debug] watcher is ready");
|
|
10115
|
-
});
|
|
10116
|
-
}
|
|
10137
|
+
if (options.watch && false);
|
|
10117
10138
|
await vitest._setServer(options, server);
|
|
10118
|
-
if (options.api && options.watch) {
|
|
10119
|
-
(await Promise.resolve().then(function () { return setup$1; })).setup(vitest);
|
|
10120
|
-
}
|
|
10139
|
+
if (options.api && options.watch) (await Promise.resolve().then(function () { return setup$1; })).setup(vitest);
|
|
10121
10140
|
// #415, in run mode we don't need the watcher, close it would improve the performance
|
|
10122
|
-
if (!options.watch)
|
|
10123
|
-
await server.watcher.close();
|
|
10124
|
-
}
|
|
10141
|
+
if (!options.watch) await server.watcher.close();
|
|
10125
10142
|
}
|
|
10126
10143
|
}
|
|
10127
10144
|
},
|
|
@@ -10136,11 +10153,7 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
|
|
|
10136
10153
|
].filter(notNullish);
|
|
10137
10154
|
}
|
|
10138
10155
|
function removeUndefinedValues(obj) {
|
|
10139
|
-
for (const key in Object.keys(obj))
|
|
10140
|
-
if (obj[key] === undefined) {
|
|
10141
|
-
delete obj[key];
|
|
10142
|
-
}
|
|
10143
|
-
}
|
|
10156
|
+
for (const key in Object.keys(obj)) if (obj[key] === void 0) delete obj[key];
|
|
10144
10157
|
return obj;
|
|
10145
10158
|
}
|
|
10146
10159
|
|
|
@@ -10157,9 +10170,7 @@ async function createVitest(mode, options, viteOverrides = {}, vitestOptions = {
|
|
|
10157
10170
|
plugins: await VitestPlugin(restOptions, ctx)
|
|
10158
10171
|
};
|
|
10159
10172
|
const server = await createViteServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })));
|
|
10160
|
-
if (ctx.config.api?.port)
|
|
10161
|
-
await server.listen();
|
|
10162
|
-
}
|
|
10173
|
+
if (ctx.config.api?.port) await server.listen();
|
|
10163
10174
|
return ctx;
|
|
10164
10175
|
}
|
|
10165
10176
|
|
|
@@ -10168,7 +10179,7 @@ const SELECTION_MAX_INDEX = 7;
|
|
|
10168
10179
|
const ESC = "\x1B[";
|
|
10169
10180
|
class WatchFilter {
|
|
10170
10181
|
filterRL;
|
|
10171
|
-
currentKeyword =
|
|
10182
|
+
currentKeyword = void 0;
|
|
10172
10183
|
message;
|
|
10173
10184
|
results = [];
|
|
10174
10185
|
selectionIndex = -1;
|
|
@@ -10184,9 +10195,7 @@ class WatchFilter {
|
|
|
10184
10195
|
escapeCodeTimeout: 50
|
|
10185
10196
|
});
|
|
10186
10197
|
readline.emitKeypressEvents(this.stdin, this.filterRL);
|
|
10187
|
-
if (this.stdin.isTTY)
|
|
10188
|
-
this.stdin.setRawMode(true);
|
|
10189
|
-
}
|
|
10198
|
+
if (this.stdin.isTTY) this.stdin.setRawMode(true);
|
|
10190
10199
|
}
|
|
10191
10200
|
async filter(filterFunc) {
|
|
10192
10201
|
this.write(this.promptLine());
|
|
@@ -10205,57 +10214,41 @@ class WatchFilter {
|
|
|
10205
10214
|
return async (str, key) => {
|
|
10206
10215
|
switch (true) {
|
|
10207
10216
|
case key.sequence === "":
|
|
10208
|
-
if (this.currentKeyword && this.currentKeyword?.length > 1)
|
|
10209
|
-
|
|
10210
|
-
} else {
|
|
10211
|
-
this.currentKeyword = undefined;
|
|
10212
|
-
}
|
|
10217
|
+
if (this.currentKeyword && this.currentKeyword?.length > 1) this.currentKeyword = this.currentKeyword?.slice(0, -1);
|
|
10218
|
+
else this.currentKeyword = void 0;
|
|
10213
10219
|
break;
|
|
10214
10220
|
case key?.ctrl && key?.name === "c":
|
|
10215
10221
|
case key?.name === "escape":
|
|
10216
10222
|
this.write(`${ESC}1G${ESC}0J`);
|
|
10217
|
-
onSubmit(
|
|
10223
|
+
onSubmit(void 0);
|
|
10218
10224
|
return;
|
|
10219
10225
|
case key?.name === "enter":
|
|
10220
10226
|
case key?.name === "return":
|
|
10221
10227
|
onSubmit(this.results[this.selectionIndex] || this.currentKeyword || "");
|
|
10222
|
-
this.currentKeyword =
|
|
10228
|
+
this.currentKeyword = void 0;
|
|
10223
10229
|
break;
|
|
10224
10230
|
case key?.name === "up":
|
|
10225
|
-
if (this.selectionIndex && this.selectionIndex > 0)
|
|
10226
|
-
|
|
10227
|
-
} else {
|
|
10228
|
-
this.selectionIndex = -1;
|
|
10229
|
-
}
|
|
10231
|
+
if (this.selectionIndex && this.selectionIndex > 0) this.selectionIndex--;
|
|
10232
|
+
else this.selectionIndex = -1;
|
|
10230
10233
|
break;
|
|
10231
10234
|
case key?.name === "down":
|
|
10232
|
-
if (this.selectionIndex < this.results.length - 1)
|
|
10233
|
-
|
|
10234
|
-
} else if (this.selectionIndex >= this.results.length - 1) {
|
|
10235
|
-
this.selectionIndex = this.results.length - 1;
|
|
10236
|
-
}
|
|
10235
|
+
if (this.selectionIndex < this.results.length - 1) this.selectionIndex++;
|
|
10236
|
+
else if (this.selectionIndex >= this.results.length - 1) this.selectionIndex = this.results.length - 1;
|
|
10237
10237
|
break;
|
|
10238
10238
|
case !key?.ctrl && !key?.meta:
|
|
10239
|
-
if (this.currentKeyword ===
|
|
10240
|
-
|
|
10241
|
-
} else {
|
|
10242
|
-
this.currentKeyword += str || "";
|
|
10243
|
-
}
|
|
10239
|
+
if (this.currentKeyword === void 0) this.currentKeyword = str;
|
|
10240
|
+
else this.currentKeyword += str || "";
|
|
10244
10241
|
break;
|
|
10245
10242
|
}
|
|
10246
|
-
if (this.currentKeyword)
|
|
10247
|
-
this.results = await filterFunc(this.currentKeyword);
|
|
10248
|
-
}
|
|
10243
|
+
if (this.currentKeyword) this.results = await filterFunc(this.currentKeyword);
|
|
10249
10244
|
this.render();
|
|
10250
10245
|
};
|
|
10251
10246
|
}
|
|
10252
10247
|
render() {
|
|
10253
10248
|
let printStr = this.promptLine();
|
|
10254
|
-
if (!this.currentKeyword)
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
printStr += "\nPattern matches no results";
|
|
10258
|
-
} else {
|
|
10249
|
+
if (!this.currentKeyword) printStr += "\nPlease input filter pattern";
|
|
10250
|
+
else if (this.currentKeyword && this.results.length === 0) printStr += "\nPattern matches no results";
|
|
10251
|
+
else {
|
|
10259
10252
|
const resultCountLine = this.results.length === 1 ? `Pattern matches ${this.results.length} result` : `Pattern matches ${this.results.length} results`;
|
|
10260
10253
|
let resultBody = "";
|
|
10261
10254
|
if (this.results.length > MAX_RESULT_COUNT) {
|
|
@@ -10263,12 +10256,9 @@ class WatchFilter {
|
|
|
10263
10256
|
const displayResults = this.results.slice(offset, MAX_RESULT_COUNT + offset);
|
|
10264
10257
|
const remainingResultCount = this.results.length - offset - displayResults.length;
|
|
10265
10258
|
resultBody = `${displayResults.map((result, index) => index + offset === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n")}`;
|
|
10266
|
-
if (remainingResultCount > 0)
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
} else {
|
|
10270
|
-
resultBody = this.results.map((result, index) => index === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n");
|
|
10271
|
-
}
|
|
10259
|
+
if (remainingResultCount > 0) resultBody += `
|
|
10260
|
+
${c.dim(` ...and ${remainingResultCount} more ${remainingResultCount === 1 ? "result" : "results"}`)}`;
|
|
10261
|
+
} else resultBody = this.results.map((result, index) => index === this.selectionIndex ? c.green(` › ${result}`) : c.dim(` › ${result}`)).join("\n");
|
|
10272
10262
|
printStr += `\n${resultCountLine}\n${resultBody}`;
|
|
10273
10263
|
}
|
|
10274
10264
|
this.eraseAndPrint(printStr);
|
|
@@ -10295,12 +10285,8 @@ class WatchFilter {
|
|
|
10295
10285
|
}
|
|
10296
10286
|
close() {
|
|
10297
10287
|
this.filterRL.close();
|
|
10298
|
-
if (this.onKeyPress)
|
|
10299
|
-
|
|
10300
|
-
}
|
|
10301
|
-
if (this.stdin.isTTY) {
|
|
10302
|
-
this.stdin.setRawMode(false);
|
|
10303
|
-
}
|
|
10288
|
+
if (this.onKeyPress) this.stdin.removeListener("keypress", this.onKeyPress);
|
|
10289
|
+
if (this.stdin.isTTY) this.stdin.setRawMode(false);
|
|
10304
10290
|
}
|
|
10305
10291
|
restoreCursor() {
|
|
10306
10292
|
const cursortPos = this.keywordOffset() + (this.currentKeyword?.length || 0);
|
|
@@ -10358,48 +10344,30 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10358
10344
|
}
|
|
10359
10345
|
const name = key?.name;
|
|
10360
10346
|
if (ctx.runningPromise) {
|
|
10361
|
-
if (cancelKeys.includes(name))
|
|
10362
|
-
await ctx.cancelCurrentRun("keyboard-input");
|
|
10363
|
-
}
|
|
10347
|
+
if (cancelKeys.includes(name)) await ctx.cancelCurrentRun("keyboard-input");
|
|
10364
10348
|
return;
|
|
10365
10349
|
}
|
|
10366
10350
|
// quit
|
|
10367
|
-
if (name === "q")
|
|
10368
|
-
return ctx.exit(true);
|
|
10369
|
-
}
|
|
10351
|
+
if (name === "q") return ctx.exit(true);
|
|
10370
10352
|
// help
|
|
10371
|
-
if (name === "h")
|
|
10372
|
-
return printShortcutsHelp();
|
|
10373
|
-
}
|
|
10353
|
+
if (name === "h") return printShortcutsHelp();
|
|
10374
10354
|
// update snapshot
|
|
10375
|
-
if (name === "u")
|
|
10376
|
-
return ctx.updateSnapshot();
|
|
10377
|
-
}
|
|
10355
|
+
if (name === "u") return ctx.updateSnapshot();
|
|
10378
10356
|
// rerun all tests
|
|
10379
10357
|
if (name === "a" || name === "return") {
|
|
10380
10358
|
const files = await ctx._globTestFilepaths();
|
|
10381
10359
|
return ctx.changeNamePattern("", files, "rerun all tests");
|
|
10382
10360
|
}
|
|
10383
10361
|
// rerun current pattern tests
|
|
10384
|
-
if (name === "r")
|
|
10385
|
-
return ctx.rerunFiles();
|
|
10386
|
-
}
|
|
10362
|
+
if (name === "r") return ctx.rerunFiles();
|
|
10387
10363
|
// rerun only failed tests
|
|
10388
|
-
if (name === "f")
|
|
10389
|
-
return ctx.rerunFailed();
|
|
10390
|
-
}
|
|
10364
|
+
if (name === "f") return ctx.rerunFailed();
|
|
10391
10365
|
// change project filter
|
|
10392
|
-
if (name === "w")
|
|
10393
|
-
return inputProjectName();
|
|
10394
|
-
}
|
|
10366
|
+
if (name === "w") return inputProjectName();
|
|
10395
10367
|
// change testNamePattern
|
|
10396
|
-
if (name === "t")
|
|
10397
|
-
return inputNamePattern();
|
|
10398
|
-
}
|
|
10368
|
+
if (name === "t") return inputNamePattern();
|
|
10399
10369
|
// change fileNamePattern
|
|
10400
|
-
if (name === "p")
|
|
10401
|
-
return inputFilePattern();
|
|
10402
|
-
}
|
|
10370
|
+
if (name === "p") return inputFilePattern();
|
|
10403
10371
|
if (name === "b") {
|
|
10404
10372
|
await ctx._initBrowserServers();
|
|
10405
10373
|
ctx.projects.forEach((project) => {
|
|
@@ -10427,12 +10395,10 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10427
10395
|
}
|
|
10428
10396
|
});
|
|
10429
10397
|
on();
|
|
10430
|
-
if (typeof filter === "undefined")
|
|
10431
|
-
return;
|
|
10432
|
-
}
|
|
10398
|
+
if (typeof filter === "undefined") return;
|
|
10433
10399
|
const files = ctx.state.getFilepaths();
|
|
10434
10400
|
// if running in standalone mode, Vitest instance doesn't know about any test file
|
|
10435
|
-
const cliFiles = ctx.config.standalone && !files.length ? await ctx._globTestFilepaths() :
|
|
10401
|
+
const cliFiles = ctx.config.standalone && !files.length ? await ctx._globTestFilepaths() : void 0;
|
|
10436
10402
|
await ctx.changeNamePattern(filter?.trim() || "", cliFiles, "change pattern");
|
|
10437
10403
|
}
|
|
10438
10404
|
async function inputProjectName() {
|
|
@@ -10454,12 +10420,10 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10454
10420
|
return files.map((file) => relative(ctx.config.root, file[1]));
|
|
10455
10421
|
});
|
|
10456
10422
|
on();
|
|
10457
|
-
if (typeof filter === "undefined")
|
|
10458
|
-
return;
|
|
10459
|
-
}
|
|
10423
|
+
if (typeof filter === "undefined") return;
|
|
10460
10424
|
latestFilename = filter?.trim() || "";
|
|
10461
10425
|
const lastResults = watchFilter.getLastResults();
|
|
10462
|
-
await ctx.changeFilenamePattern(latestFilename, filter && lastResults.length ? lastResults.map((i) => resolve(ctx.config.root, i)) :
|
|
10426
|
+
await ctx.changeFilenamePattern(latestFilename, filter && lastResults.length ? lastResults.map((i) => resolve(ctx.config.root, i)) : void 0);
|
|
10463
10427
|
}
|
|
10464
10428
|
let rl;
|
|
10465
10429
|
function on() {
|
|
@@ -10469,18 +10433,14 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout) {
|
|
|
10469
10433
|
escapeCodeTimeout: 50
|
|
10470
10434
|
});
|
|
10471
10435
|
readline.emitKeypressEvents(stdin, rl);
|
|
10472
|
-
if (stdin.isTTY)
|
|
10473
|
-
stdin.setRawMode(true);
|
|
10474
|
-
}
|
|
10436
|
+
if (stdin.isTTY) stdin.setRawMode(true);
|
|
10475
10437
|
stdin.on("keypress", keypressHandler);
|
|
10476
10438
|
}
|
|
10477
10439
|
function off() {
|
|
10478
10440
|
rl?.close();
|
|
10479
|
-
rl =
|
|
10441
|
+
rl = void 0;
|
|
10480
10442
|
stdin.removeListener("keypress", keypressHandler);
|
|
10481
|
-
if (stdin.isTTY)
|
|
10482
|
-
stdin.setRawMode(false);
|
|
10483
|
-
}
|
|
10443
|
+
if (stdin.isTTY) stdin.setRawMode(false);
|
|
10484
10444
|
}
|
|
10485
10445
|
on();
|
|
10486
10446
|
return function cleanup() {
|
|
@@ -10509,28 +10469,17 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, v
|
|
|
10509
10469
|
const stdin = vitestOptions?.stdin || process.stdin;
|
|
10510
10470
|
const stdout = vitestOptions?.stdout || process.stdout;
|
|
10511
10471
|
let stdinCleanup;
|
|
10512
|
-
if (stdin.isTTY && ctx.config.watch)
|
|
10513
|
-
stdinCleanup = registerConsoleShortcuts(ctx, stdin, stdout);
|
|
10514
|
-
}
|
|
10472
|
+
if (stdin.isTTY && ctx.config.watch) stdinCleanup = registerConsoleShortcuts(ctx, stdin, stdout);
|
|
10515
10473
|
ctx.onAfterSetServer(() => {
|
|
10516
|
-
if (ctx.config.standalone)
|
|
10517
|
-
|
|
10518
|
-
} else {
|
|
10519
|
-
ctx.start(cliFilters);
|
|
10520
|
-
}
|
|
10474
|
+
if (ctx.config.standalone) ctx.init();
|
|
10475
|
+
else ctx.start(cliFilters);
|
|
10521
10476
|
});
|
|
10522
10477
|
try {
|
|
10523
|
-
if (ctx.config.mergeReports)
|
|
10524
|
-
|
|
10525
|
-
|
|
10526
|
-
await ctx.init();
|
|
10527
|
-
} else {
|
|
10528
|
-
await ctx.start(cliFilters);
|
|
10529
|
-
}
|
|
10478
|
+
if (ctx.config.mergeReports) await ctx.mergeReports();
|
|
10479
|
+
else if (ctx.config.standalone) await ctx.init();
|
|
10480
|
+
else await ctx.start(cliFilters);
|
|
10530
10481
|
} catch (e) {
|
|
10531
|
-
if (e instanceof FilesNotFoundError)
|
|
10532
|
-
return ctx;
|
|
10533
|
-
}
|
|
10482
|
+
if (e instanceof FilesNotFoundError) return ctx;
|
|
10534
10483
|
if (e instanceof GitNotFoundError) {
|
|
10535
10484
|
ctx.logger.error(e.message);
|
|
10536
10485
|
return ctx;
|
|
@@ -10547,9 +10496,7 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, v
|
|
|
10547
10496
|
ctx.logger.error("\n\n");
|
|
10548
10497
|
return ctx;
|
|
10549
10498
|
}
|
|
10550
|
-
if (ctx.shouldKeepServer())
|
|
10551
|
-
return ctx;
|
|
10552
|
-
}
|
|
10499
|
+
if (ctx.shouldKeepServer()) return ctx;
|
|
10553
10500
|
stdinCleanup?.();
|
|
10554
10501
|
await ctx.close();
|
|
10555
10502
|
return ctx;
|
|
@@ -10558,9 +10505,7 @@ async function prepareVitest(mode, options = {}, viteOverrides, vitestOptions) {
|
|
|
10558
10505
|
process.env.TEST = "true";
|
|
10559
10506
|
process.env.VITEST = "true";
|
|
10560
10507
|
process.env.NODE_ENV ??= "test";
|
|
10561
|
-
if (options.run)
|
|
10562
|
-
options.watch = false;
|
|
10563
|
-
}
|
|
10508
|
+
if (options.run) options.watch = false;
|
|
10564
10509
|
// this shouldn't affect _application root_ that can be changed inside config
|
|
10565
10510
|
const root = resolve(options.root || process.cwd());
|
|
10566
10511
|
const ctx = await createVitest(mode, options, viteOverrides, vitestOptions);
|
|
@@ -10579,24 +10524,16 @@ function processCollected(ctx, files, options) {
|
|
|
10579
10524
|
ctx.logger.printError(error, { project: suite.project });
|
|
10580
10525
|
});
|
|
10581
10526
|
});
|
|
10582
|
-
if (errorsPrinted)
|
|
10583
|
-
|
|
10584
|
-
}
|
|
10585
|
-
if (typeof options.json !== "undefined") {
|
|
10586
|
-
return processJsonOutput(files, options);
|
|
10587
|
-
}
|
|
10527
|
+
if (errorsPrinted) return;
|
|
10528
|
+
if (typeof options.json !== "undefined") return processJsonOutput(files, options);
|
|
10588
10529
|
return formatCollectedAsString(files).forEach((test) => console.log(test));
|
|
10589
10530
|
}
|
|
10590
10531
|
function outputFileList(files, options) {
|
|
10591
|
-
if (typeof options.json !== "undefined")
|
|
10592
|
-
return outputJsonFileList(files, options);
|
|
10593
|
-
}
|
|
10532
|
+
if (typeof options.json !== "undefined") return outputJsonFileList(files, options);
|
|
10594
10533
|
formatFilesAsString(files, options).map((file) => console.log(file));
|
|
10595
10534
|
}
|
|
10596
10535
|
function outputJsonFileList(files, options) {
|
|
10597
|
-
if (typeof options.json === "boolean")
|
|
10598
|
-
return console.log(JSON.stringify(formatFilesAsJSON(files), null, 2));
|
|
10599
|
-
}
|
|
10536
|
+
if (typeof options.json === "boolean") return console.log(JSON.stringify(formatFilesAsJSON(files), null, 2));
|
|
10600
10537
|
if (typeof options.json === "string") {
|
|
10601
10538
|
const jsonPath = resolve(options.root || process.cwd(), options.json);
|
|
10602
10539
|
mkdirSync(dirname(jsonPath), { recursive: true });
|
|
@@ -10606,25 +10543,19 @@ function outputJsonFileList(files, options) {
|
|
|
10606
10543
|
function formatFilesAsJSON(files) {
|
|
10607
10544
|
return files.map((file) => {
|
|
10608
10545
|
const result = { file: file.moduleId };
|
|
10609
|
-
if (file.project.name)
|
|
10610
|
-
result.projectName = file.project.name;
|
|
10611
|
-
}
|
|
10546
|
+
if (file.project.name) result.projectName = file.project.name;
|
|
10612
10547
|
return result;
|
|
10613
10548
|
});
|
|
10614
10549
|
}
|
|
10615
10550
|
function formatFilesAsString(files, options) {
|
|
10616
10551
|
return files.map((file) => {
|
|
10617
10552
|
let name = relative(options.root || process.cwd(), file.moduleId);
|
|
10618
|
-
if (file.project.name) {
|
|
10619
|
-
name = `[${file.project.name}] ${name}`;
|
|
10620
|
-
}
|
|
10553
|
+
if (file.project.name) name = `[${file.project.name}] ${name}`;
|
|
10621
10554
|
return name;
|
|
10622
10555
|
});
|
|
10623
10556
|
}
|
|
10624
10557
|
function processJsonOutput(files, options) {
|
|
10625
|
-
if (typeof options.json === "boolean")
|
|
10626
|
-
return console.log(JSON.stringify(formatCollectedAsJSON(files), null, 2));
|
|
10627
|
-
}
|
|
10558
|
+
if (typeof options.json === "boolean") return console.log(JSON.stringify(formatCollectedAsJSON(files), null, 2));
|
|
10628
10559
|
if (typeof options.json === "string") {
|
|
10629
10560
|
const jsonPath = resolve(options.root || process.cwd(), options.json);
|
|
10630
10561
|
mkdirSync(dirname(jsonPath), { recursive: true });
|
|
@@ -10634,28 +10565,20 @@ function processJsonOutput(files, options) {
|
|
|
10634
10565
|
function forEachSuite(modules, callback) {
|
|
10635
10566
|
modules.forEach((testModule) => {
|
|
10636
10567
|
callback(testModule);
|
|
10637
|
-
for (const suite of testModule.children.allSuites())
|
|
10638
|
-
callback(suite);
|
|
10639
|
-
}
|
|
10568
|
+
for (const suite of testModule.children.allSuites()) callback(suite);
|
|
10640
10569
|
});
|
|
10641
10570
|
}
|
|
10642
10571
|
function formatCollectedAsJSON(files) {
|
|
10643
10572
|
const results = [];
|
|
10644
10573
|
files.forEach((file) => {
|
|
10645
10574
|
for (const test of file.children.allTests()) {
|
|
10646
|
-
if (test.result().state === "skipped")
|
|
10647
|
-
continue;
|
|
10648
|
-
}
|
|
10575
|
+
if (test.result().state === "skipped") continue;
|
|
10649
10576
|
const result = {
|
|
10650
10577
|
name: test.fullName,
|
|
10651
10578
|
file: test.module.moduleId
|
|
10652
10579
|
};
|
|
10653
|
-
if (test.project.name)
|
|
10654
|
-
|
|
10655
|
-
}
|
|
10656
|
-
if (test.location) {
|
|
10657
|
-
result.location = test.location;
|
|
10658
|
-
}
|
|
10580
|
+
if (test.project.name) result.projectName = test.project.name;
|
|
10581
|
+
if (test.location) result.location = test.location;
|
|
10659
10582
|
results.push(result);
|
|
10660
10583
|
}
|
|
10661
10584
|
});
|
|
@@ -10665,9 +10588,7 @@ function formatCollectedAsString(testModules) {
|
|
|
10665
10588
|
const results = [];
|
|
10666
10589
|
testModules.forEach((testModule) => {
|
|
10667
10590
|
for (const test of testModule.children.allTests()) {
|
|
10668
|
-
if (test.result().state === "skipped")
|
|
10669
|
-
continue;
|
|
10670
|
-
}
|
|
10591
|
+
if (test.result().state === "skipped") continue;
|
|
10671
10592
|
const fullName = `${test.module.task.name} > ${test.fullName}`;
|
|
10672
10593
|
results.push((test.project.name ? `[${test.project.name}] ` : "") + fullName);
|
|
10673
10594
|
}
|
|
@@ -10680,15 +10601,9 @@ const envPackageNames = {
|
|
|
10680
10601
|
"edge-runtime": "@edge-runtime/vm"
|
|
10681
10602
|
};
|
|
10682
10603
|
function getEnvPackageName(env) {
|
|
10683
|
-
if (env === "node")
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
if (env in envPackageNames) {
|
|
10687
|
-
return envPackageNames[env];
|
|
10688
|
-
}
|
|
10689
|
-
if (env[0] === "." || env[0] === "/") {
|
|
10690
|
-
return null;
|
|
10691
|
-
}
|
|
10604
|
+
if (env === "node") return null;
|
|
10605
|
+
if (env in envPackageNames) return envPackageNames[env];
|
|
10606
|
+
if (env[0] === "." || env[0] === "/") return null;
|
|
10692
10607
|
return `vitest-environment-${env}`;
|
|
10693
10608
|
}
|
|
10694
10609
|
|