vitest 2.2.0-beta.1 → 3.0.0-beta.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.
Files changed (51) hide show
  1. package/dist/browser.d.ts +8 -8
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{RandomSequencer.CMRlh2v4.js → RandomSequencer.gisBJ77r.js} +11 -3
  4. package/dist/chunks/{base.BS0HhLXd.js → base.CkcgFVQd.js} +8 -3
  5. package/dist/chunks/{benchmark.geERunq4.d.ts → benchmark.CFFwLv-O.d.ts} +2 -2
  6. package/dist/chunks/{cac.Z91LBqmg.js → cac.CWCZimpS.js} +7 -7
  7. package/dist/chunks/{cli-api.DVJJMJHj.js → cli-api.BKUOv0Nc.js} +928 -661
  8. package/dist/chunks/{config.CPguQ7J1.d.ts → config.BTPBhmK5.d.ts} +1 -1
  9. package/dist/chunks/{creator.IIqd8RWT.js → creator.DcAcUhMD.js} +1 -4
  10. package/dist/chunks/{globals.BCGEw6ON.js → globals.DJTzb7B3.js} +2 -2
  11. package/dist/chunks/{index.DD5eTY2y.js → index.BqHViJW9.js} +1 -1
  12. package/dist/chunks/{index.BjjsHdBb.js → index.CkOJwybT.js} +1 -1
  13. package/dist/chunks/{index.DLRzErGF.js → index.DKe7vK-G.js} +708 -548
  14. package/dist/chunks/{index.CqYx2Nsr.js → index.DQboAxJm.js} +23 -14
  15. package/dist/chunks/{inspector.70d6emsh.js → inspector.DKLceBVD.js} +1 -1
  16. package/dist/chunks/{reporters.B_9uUTGW.d.ts → reporters.BZbwTvrM.d.ts} +1252 -1234
  17. package/dist/chunks/{resolveConfig.CQIc6fe7.js → resolveConfig.3rGGWga5.js} +88 -56
  18. package/dist/chunks/{runBaseTests.B7hcVT-s.js → runBaseTests.C6huCAng.js} +6 -6
  19. package/dist/chunks/{setup-common.BfGt8K-K.js → setup-common.B5ClyS48.js} +1 -1
  20. package/dist/chunks/{suite.B2jumIFP.d.ts → suite.BJU7kdY9.d.ts} +4 -4
  21. package/dist/chunks/{utils.DNoFbBUZ.js → utils.CMUTX-p8.js} +20 -23
  22. package/dist/chunks/{vi.BlPttogV.js → vi.CZKezqeD.js} +18 -13
  23. package/dist/chunks/{vite.Bvms8Xir.d.ts → vite.DIfmneq0.d.ts} +1 -1
  24. package/dist/chunks/{vm.Zr4qWzDJ.js → vm.DGhTouO3.js} +10 -1
  25. package/dist/chunks/{worker.9VY11NZs.d.ts → worker.CmzGeuVD.d.ts} +3 -3
  26. package/dist/chunks/{worker.Qz1UB4Fv.d.ts → worker.umPNbBNk.d.ts} +1 -1
  27. package/dist/cli.js +1 -1
  28. package/dist/config.cjs +1 -10
  29. package/dist/config.d.ts +11 -11
  30. package/dist/config.js +1 -10
  31. package/dist/coverage.d.ts +7 -7
  32. package/dist/coverage.js +4 -4
  33. package/dist/execute.d.ts +3 -3
  34. package/dist/index.d.ts +26 -17
  35. package/dist/index.js +2 -2
  36. package/dist/node.d.ts +16 -20
  37. package/dist/node.js +7 -7
  38. package/dist/reporters.d.ts +7 -7
  39. package/dist/reporters.js +3 -3
  40. package/dist/runners.d.ts +3 -4
  41. package/dist/runners.js +9 -14
  42. package/dist/suite.d.ts +2 -2
  43. package/dist/worker.js +1 -1
  44. package/dist/workers/forks.js +1 -1
  45. package/dist/workers/runVmTests.js +6 -6
  46. package/dist/workers/threads.js +1 -1
  47. package/dist/workers/vmForks.js +1 -1
  48. package/dist/workers/vmThreads.js +1 -1
  49. package/dist/workers.d.ts +3 -3
  50. package/dist/workers.js +3 -3
  51. package/package.json +22 -22
@@ -8,12 +8,12 @@ import { f as findUp, p as prompt } from './index.BJDntFik.js';
8
8
  import { searchForWorkspaceRoot, version, createServer, mergeConfig } from 'vite';
9
9
  import { A as API_PATH, c as configFiles, a as defaultBrowserPort, w as workspacesFiles, d as defaultPort } from './constants.fzPh7AOq.js';
10
10
  import { SnapshotManager } from '@vitest/snapshot/manager';
11
- import { i as isPackageExists, e as requireMicromatch, V as VitestCache, f as configDefaults, m as mm, b as resolveConfig, h as isBrowserEnabled, w as wildcardPatternToRegExp, g as getFilePoolName, j as createPool, a as resolveApiServerConfig, c as coverageConfigDefaults, s as stdout } from './resolveConfig.CQIc6fe7.js';
11
+ import { e as groupBy, i as isPackageExists, f as requireMicromatch, V as VitestCache, h as configDefaults, g as getFilePoolName, j as isBrowserEnabled, m as mm, b as resolveConfig, w as wildcardPatternToRegExp, k as createPool, a as resolveApiServerConfig, c as coverageConfigDefaults, s as stdout } from './resolveConfig.3rGGWga5.js';
12
12
  import { ViteNodeRunner } from 'vite-node/client';
13
13
  import { ViteNodeServer } from 'vite-node/server';
14
- import { v as version$1 } from './cac.Z91LBqmg.js';
14
+ import { v as version$1 } from './cac.CWCZimpS.js';
15
15
  import { c as createBirpc } from './index.68735LiX.js';
16
- import { s as stringify, p as parse, R as ReportersMap, h as BenchmarkReportsMap, f as TestModule, g as TestSuite, e as TestCase, j as generateCodeFrame, i as TestProject, L as Logger, k as BlobReporter, r as readBlobs } from './index.DLRzErGF.js';
16
+ import { s as stringify, p as parse, i as generateCodeFrame, R as ReportersMap, h as BenchmarkReportsMap, f as TestModule, g as TestSuite, e as TestCase, L as Logger, j as BlobReporter, r as readBlobs } from './index.DKe7vK-G.js';
17
17
  import require$$0$2 from 'stream';
18
18
  import require$$0 from 'zlib';
19
19
  import require$$0$1 from 'buffer';
@@ -30,7 +30,7 @@ import { distDir, rootDir } from '../path.js';
30
30
  import { createRequire } from 'node:module';
31
31
  import url from 'node:url';
32
32
  import c from 'tinyrainbow';
33
- import { h as hash, i as isWindows } from './RandomSequencer.CMRlh2v4.js';
33
+ import { h as hash, i as isWindows } from './RandomSequencer.gisBJ77r.js';
34
34
  import { isCI } from 'std-env';
35
35
  import { rm } from 'node:fs/promises';
36
36
  import nodeos__default, { tmpdir } from 'node:os';
@@ -4845,7 +4845,7 @@ async function getModuleGraph(ctx, projectName, id, browser = false) {
4845
4845
  if (browser && project.browser) {
4846
4846
  await get(project.browser.vite.moduleGraph.getModuleById(id));
4847
4847
  } else {
4848
- await get(project.server.moduleGraph.getModuleById(id));
4848
+ await get(project.vite.moduleGraph.getModuleById(id));
4849
4849
  }
4850
4850
  return {
4851
4851
  graph,
@@ -4924,11 +4924,14 @@ function setup(ctx, _server) {
4924
4924
  }
4925
4925
  return promises.writeFile(id, content, "utf-8");
4926
4926
  },
4927
- async rerun(files) {
4928
- await ctx.rerunFiles(files);
4927
+ async rerun(files, resetTestNamePattern) {
4928
+ await ctx.rerunFiles(files, void 0, true, resetTestNamePattern);
4929
+ },
4930
+ async rerunTask(id) {
4931
+ await ctx.rerunTask(id);
4929
4932
  },
4930
4933
  getConfig() {
4931
- return ctx.getCoreWorkspaceProject().getSerializableConfig();
4934
+ return ctx.getRootTestProject().serializedConfig;
4932
4935
  },
4933
4936
  async getTransformResult(projectName, id, browser = false) {
4934
4937
  const project = ctx.getProjectByName(projectName);
@@ -5066,6 +5069,59 @@ class GitNotFoundError extends Error {
5066
5069
  super("Could not find Git root. Have you initialized git with `git init`?");
5067
5070
  }
5068
5071
  }
5072
+ class LocationFilterFileNotFoundError extends Error {
5073
+ code = "VITEST_LOCATION_FILTER_FILE_NOT_FOUND";
5074
+ constructor(filename) {
5075
+ super(`Couldn't find file ${filename}. Note when specifying the test location you have to specify the full test filename.`);
5076
+ }
5077
+ }
5078
+ class IncludeTaskLocationDisabledError extends Error {
5079
+ code = "VITEST_INCLUDE_TASK_LOCATION_DISABLED";
5080
+ constructor() {
5081
+ super("Recieved line number filters while `includeTaskLocation` option is disabled");
5082
+ }
5083
+ }
5084
+ class RangeLocationFilterProvidedError extends Error {
5085
+ code = "VITEST_RANGE_LOCATION_FILTER_PROVIDED";
5086
+ constructor(filter) {
5087
+ super(`Found "-" in location filter ${filter}. Note that range location filters are not supported. Consider specifying the exact line numbers of your tests.`);
5088
+ }
5089
+ }
5090
+
5091
+ function parseFilter(filter) {
5092
+ const colonIndex = filter.lastIndexOf(":");
5093
+ if (colonIndex === -1) {
5094
+ return { filename: filter };
5095
+ }
5096
+ const [parsedFilename, lineNumber] = [
5097
+ filter.substring(0, colonIndex),
5098
+ filter.substring(colonIndex + 1)
5099
+ ];
5100
+ if (lineNumber.match(/^\d+$/)) {
5101
+ return {
5102
+ filename: parsedFilename,
5103
+ lineNumber: Number.parseInt(lineNumber)
5104
+ };
5105
+ } else if (lineNumber.match(/^\d+-\d+$/)) {
5106
+ throw new RangeLocationFilterProvidedError(filter);
5107
+ } else {
5108
+ return { filename: filter };
5109
+ }
5110
+ }
5111
+ function groupFilters(filters) {
5112
+ const groupedFilters_ = groupBy(filters, (f) => f.filename);
5113
+ const groupedFilters = Object.fromEntries(
5114
+ Object.entries(groupedFilters_).map((entry) => {
5115
+ const [filename, filters2] = entry;
5116
+ const testLocations = filters2.map((f) => f.lineNumber);
5117
+ return [
5118
+ filename,
5119
+ testLocations.filter((l) => l !== void 0)
5120
+ ];
5121
+ })
5122
+ );
5123
+ return groupedFilters;
5124
+ }
5069
5125
 
5070
5126
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
5071
5127
  class VitestPackageInstaller {
@@ -5108,7 +5164,7 @@ class VitestPackageInstaller {
5108
5164
  });
5109
5165
  if (install) {
5110
5166
  const packageName = version ? `${dependency}@${version}` : dependency;
5111
- await (await import('./index.CqYx2Nsr.js')).installPackage(packageName, { dev: true });
5167
+ await (await import('./index.DQboAxJm.js')).installPackage(packageName, { dev: true });
5112
5168
  process.stderr.write(
5113
5169
  c.yellow(
5114
5170
  `
@@ -5123,404 +5179,160 @@ Package ${packageName} installed, re-run the command to start.
5123
5179
  }
5124
5180
  }
5125
5181
 
5126
- async function loadCustomReporterModule(path, runner) {
5127
- let customReporterModule;
5128
- try {
5129
- customReporterModule = await runner.executeId(path);
5130
- } catch (customReporterModuleError) {
5131
- throw new Error(`Failed to load custom Reporter from ${path}`, {
5132
- cause: customReporterModuleError
5133
- });
5134
- }
5135
- if (customReporterModule.default === null || customReporterModule.default === void 0) {
5136
- throw new Error(
5137
- `Custom reporter loaded from ${path} was not the default export`
5138
- );
5139
- }
5140
- return customReporterModule.default;
5182
+ var tasks = {};
5183
+
5184
+ var utils$1 = {};
5185
+
5186
+ var array = {};
5187
+
5188
+ var hasRequiredArray;
5189
+
5190
+ function requireArray () {
5191
+ if (hasRequiredArray) return array;
5192
+ hasRequiredArray = 1;
5193
+ Object.defineProperty(array, "__esModule", { value: true });
5194
+ array.splitWhen = array.flatten = void 0;
5195
+ function flatten(items) {
5196
+ return items.reduce((collection, item) => [].concat(collection, item), []);
5197
+ }
5198
+ array.flatten = flatten;
5199
+ function splitWhen(items, predicate) {
5200
+ const result = [[]];
5201
+ let groupIndex = 0;
5202
+ for (const item of items) {
5203
+ if (predicate(item)) {
5204
+ groupIndex++;
5205
+ result[groupIndex] = [];
5206
+ }
5207
+ else {
5208
+ result[groupIndex].push(item);
5209
+ }
5210
+ }
5211
+ return result;
5212
+ }
5213
+ array.splitWhen = splitWhen;
5214
+ return array;
5141
5215
  }
5142
- function createReporters(reporterReferences, ctx) {
5143
- const runner = ctx.runner;
5144
- const promisedReporters = reporterReferences.map(
5145
- async (referenceOrInstance) => {
5146
- if (Array.isArray(referenceOrInstance)) {
5147
- const [reporterName, reporterOptions] = referenceOrInstance;
5148
- if (reporterName === "html") {
5149
- await ctx.packageInstaller.ensureInstalled("@vitest/ui", runner.root, ctx.version);
5150
- const CustomReporter = await loadCustomReporterModule(
5151
- "@vitest/ui/reporter",
5152
- runner
5153
- );
5154
- return new CustomReporter(reporterOptions);
5155
- } else if (reporterName in ReportersMap) {
5156
- const BuiltinReporter = ReportersMap[reporterName];
5157
- return new BuiltinReporter(reporterOptions);
5158
- } else {
5159
- const CustomReporter = await loadCustomReporterModule(
5160
- reporterName,
5161
- runner
5162
- );
5163
- return new CustomReporter(reporterOptions);
5164
- }
5165
- }
5166
- return referenceOrInstance;
5167
- }
5168
- );
5169
- return Promise.all(promisedReporters);
5216
+
5217
+ var errno = {};
5218
+
5219
+ var hasRequiredErrno;
5220
+
5221
+ function requireErrno () {
5222
+ if (hasRequiredErrno) return errno;
5223
+ hasRequiredErrno = 1;
5224
+ Object.defineProperty(errno, "__esModule", { value: true });
5225
+ errno.isEnoentCodeError = void 0;
5226
+ function isEnoentCodeError(error) {
5227
+ return error.code === 'ENOENT';
5228
+ }
5229
+ errno.isEnoentCodeError = isEnoentCodeError;
5230
+ return errno;
5170
5231
  }
5171
- function createBenchmarkReporters(reporterReferences, runner) {
5172
- const promisedReporters = reporterReferences.map(
5173
- async (referenceOrInstance) => {
5174
- if (typeof referenceOrInstance === "string") {
5175
- if (referenceOrInstance in BenchmarkReportsMap) {
5176
- const BuiltinReporter = BenchmarkReportsMap[referenceOrInstance];
5177
- return new BuiltinReporter();
5178
- } else {
5179
- const CustomReporter = await loadCustomReporterModule(
5180
- referenceOrInstance,
5181
- runner
5182
- );
5183
- return new CustomReporter();
5184
- }
5185
- }
5186
- return referenceOrInstance;
5187
- }
5188
- );
5189
- return Promise.all(promisedReporters);
5232
+
5233
+ var fs$3 = {};
5234
+
5235
+ var hasRequiredFs$3;
5236
+
5237
+ function requireFs$3 () {
5238
+ if (hasRequiredFs$3) return fs$3;
5239
+ hasRequiredFs$3 = 1;
5240
+ Object.defineProperty(fs$3, "__esModule", { value: true });
5241
+ fs$3.createDirentFromStats = void 0;
5242
+ class DirentFromStats {
5243
+ constructor(name, stats) {
5244
+ this.name = name;
5245
+ this.isBlockDevice = stats.isBlockDevice.bind(stats);
5246
+ this.isCharacterDevice = stats.isCharacterDevice.bind(stats);
5247
+ this.isDirectory = stats.isDirectory.bind(stats);
5248
+ this.isFIFO = stats.isFIFO.bind(stats);
5249
+ this.isFile = stats.isFile.bind(stats);
5250
+ this.isSocket = stats.isSocket.bind(stats);
5251
+ this.isSymbolicLink = stats.isSymbolicLink.bind(stats);
5252
+ }
5253
+ }
5254
+ function createDirentFromStats(name, stats) {
5255
+ return new DirentFromStats(name, stats);
5256
+ }
5257
+ fs$3.createDirentFromStats = createDirentFromStats;
5258
+ return fs$3;
5190
5259
  }
5191
5260
 
5192
- function isAggregateError(err) {
5193
- if (typeof AggregateError !== "undefined" && err instanceof AggregateError) {
5194
- return true;
5195
- }
5196
- return err instanceof Error && "errors" in err;
5197
- }
5198
- class StateManager {
5199
- filesMap = /* @__PURE__ */ new Map();
5200
- pathsSet = /* @__PURE__ */ new Set();
5201
- idMap = /* @__PURE__ */ new Map();
5202
- taskFileMap = /* @__PURE__ */ new WeakMap();
5203
- errorsSet = /* @__PURE__ */ new Set();
5204
- processTimeoutCauses = /* @__PURE__ */ new Set();
5205
- reportedTasksMap = /* @__PURE__ */ new WeakMap();
5206
- catchError(err, type) {
5207
- if (isAggregateError(err)) {
5208
- return err.errors.forEach((error) => this.catchError(error, type));
5209
- }
5210
- if (err === Object(err)) {
5211
- err.type = type;
5212
- } else {
5213
- err = { type, message: err };
5214
- }
5215
- const _err = err;
5216
- if (_err && typeof _err === "object" && _err.code === "VITEST_PENDING") {
5217
- const task = this.idMap.get(_err.taskId);
5218
- if (task) {
5219
- task.mode = "skip";
5220
- task.result ??= { state: "skip" };
5221
- task.result.state = "skip";
5222
- task.result.note = _err.note;
5223
- }
5224
- return;
5225
- }
5226
- this.errorsSet.add(err);
5227
- }
5228
- clearErrors() {
5229
- this.errorsSet.clear();
5230
- }
5231
- getUnhandledErrors() {
5232
- return Array.from(this.errorsSet.values());
5233
- }
5234
- addProcessTimeoutCause(cause) {
5235
- this.processTimeoutCauses.add(cause);
5236
- }
5237
- getProcessTimeoutCauses() {
5238
- return Array.from(this.processTimeoutCauses.values());
5239
- }
5240
- getPaths() {
5241
- return Array.from(this.pathsSet);
5242
- }
5243
- /**
5244
- * Return files that were running or collected.
5245
- */
5246
- getFiles(keys) {
5247
- if (keys) {
5248
- return keys.map((key) => this.filesMap.get(key)).flat().filter((file) => file && !file.local);
5249
- }
5250
- return Array.from(this.filesMap.values()).flat().filter((file) => !file.local).sort((f1, f2) => {
5251
- if (f1.meta?.typecheck && f2.meta?.typecheck) {
5252
- return 0;
5253
- }
5254
- if (f1.meta?.typecheck) {
5255
- return -1;
5256
- }
5257
- return 1;
5258
- });
5259
- }
5260
- getFilepaths() {
5261
- return Array.from(this.filesMap.keys());
5262
- }
5263
- getFailedFilepaths() {
5264
- return this.getFiles().filter((i) => i.result?.state === "fail").map((i) => i.filepath);
5265
- }
5266
- collectPaths(paths = []) {
5267
- paths.forEach((path) => {
5268
- this.pathsSet.add(path);
5269
- });
5270
- }
5271
- collectFiles(project, files = []) {
5272
- files.forEach((file) => {
5273
- const existing = this.filesMap.get(file.filepath) || [];
5274
- const otherFiles = existing.filter(
5275
- (i) => i.projectName !== file.projectName || i.meta.typecheck !== file.meta.typecheck
5276
- );
5277
- const currentFile = existing.find(
5278
- (i) => i.projectName === file.projectName
5279
- );
5280
- if (currentFile) {
5281
- file.logs = currentFile.logs;
5282
- }
5283
- otherFiles.push(file);
5284
- this.filesMap.set(file.filepath, otherFiles);
5285
- this.updateId(file, project);
5286
- });
5287
- }
5288
- clearFiles(project, paths = []) {
5289
- paths.forEach((path) => {
5290
- const files = this.filesMap.get(path);
5291
- const fileTask = createFileTask(
5292
- path,
5293
- project.config.root,
5294
- project.config.name
5295
- );
5296
- fileTask.local = true;
5297
- TestModule.register(fileTask, project);
5298
- this.idMap.set(fileTask.id, fileTask);
5299
- if (!files) {
5300
- this.filesMap.set(path, [fileTask]);
5301
- return;
5302
- }
5303
- const filtered = files.filter(
5304
- (file) => file.projectName !== project.config.name
5305
- );
5306
- if (!filtered.length) {
5307
- this.filesMap.set(path, [fileTask]);
5308
- } else {
5309
- this.filesMap.set(path, [...filtered, fileTask]);
5310
- }
5311
- });
5312
- }
5313
- updateId(task, project) {
5314
- if (this.idMap.get(task.id) === task) {
5315
- return;
5316
- }
5317
- if (task.type === "suite" && "filepath" in task) {
5318
- TestModule.register(task, project);
5319
- } else if (task.type === "suite") {
5320
- TestSuite.register(task, project);
5321
- } else {
5322
- TestCase.register(task, project);
5323
- }
5324
- this.idMap.set(task.id, task);
5325
- if (task.type === "suite") {
5326
- task.tasks.forEach((task2) => {
5327
- this.updateId(task2, project);
5328
- });
5329
- }
5330
- }
5331
- getReportedEntity(task) {
5332
- return this.reportedTasksMap.get(task);
5333
- }
5334
- updateTasks(packs) {
5335
- for (const [id, result, meta] of packs) {
5336
- const task = this.idMap.get(id);
5337
- if (task) {
5338
- task.result = result;
5339
- task.meta = meta;
5340
- if (result?.state === "skip") {
5341
- task.mode = "skip";
5342
- }
5343
- }
5344
- }
5345
- }
5346
- updateUserLog(log) {
5347
- const task = log.taskId && this.idMap.get(log.taskId);
5348
- if (task) {
5349
- if (!task.logs) {
5350
- task.logs = [];
5351
- }
5352
- task.logs.push(log);
5353
- }
5354
- }
5355
- getCountOfFailedTests() {
5356
- return Array.from(this.idMap.values()).filter(
5357
- (t) => t.result?.state === "fail"
5358
- ).length;
5359
- }
5360
- cancelFiles(files, project) {
5361
- this.collectFiles(
5362
- project,
5363
- files.map(
5364
- (filepath) => createFileTask(filepath, project.config.root, project.config.name)
5365
- )
5366
- );
5367
- }
5368
- }
5369
-
5370
- var tasks = {};
5371
-
5372
- var utils$1 = {};
5373
-
5374
- var array = {};
5375
-
5376
- var hasRequiredArray;
5377
-
5378
- function requireArray () {
5379
- if (hasRequiredArray) return array;
5380
- hasRequiredArray = 1;
5381
- Object.defineProperty(array, "__esModule", { value: true });
5382
- array.splitWhen = array.flatten = void 0;
5383
- function flatten(items) {
5384
- return items.reduce((collection, item) => [].concat(collection, item), []);
5385
- }
5386
- array.flatten = flatten;
5387
- function splitWhen(items, predicate) {
5388
- const result = [[]];
5389
- let groupIndex = 0;
5390
- for (const item of items) {
5391
- if (predicate(item)) {
5392
- groupIndex++;
5393
- result[groupIndex] = [];
5394
- }
5395
- else {
5396
- result[groupIndex].push(item);
5397
- }
5398
- }
5399
- return result;
5400
- }
5401
- array.splitWhen = splitWhen;
5402
- return array;
5403
- }
5404
-
5405
- var errno = {};
5406
-
5407
- var hasRequiredErrno;
5408
-
5409
- function requireErrno () {
5410
- if (hasRequiredErrno) return errno;
5411
- hasRequiredErrno = 1;
5412
- Object.defineProperty(errno, "__esModule", { value: true });
5413
- errno.isEnoentCodeError = void 0;
5414
- function isEnoentCodeError(error) {
5415
- return error.code === 'ENOENT';
5416
- }
5417
- errno.isEnoentCodeError = isEnoentCodeError;
5418
- return errno;
5419
- }
5420
-
5421
- var fs$3 = {};
5422
-
5423
- var hasRequiredFs$3;
5424
-
5425
- function requireFs$3 () {
5426
- if (hasRequiredFs$3) return fs$3;
5427
- hasRequiredFs$3 = 1;
5428
- Object.defineProperty(fs$3, "__esModule", { value: true });
5429
- fs$3.createDirentFromStats = void 0;
5430
- class DirentFromStats {
5431
- constructor(name, stats) {
5432
- this.name = name;
5433
- this.isBlockDevice = stats.isBlockDevice.bind(stats);
5434
- this.isCharacterDevice = stats.isCharacterDevice.bind(stats);
5435
- this.isDirectory = stats.isDirectory.bind(stats);
5436
- this.isFIFO = stats.isFIFO.bind(stats);
5437
- this.isFile = stats.isFile.bind(stats);
5438
- this.isSocket = stats.isSocket.bind(stats);
5439
- this.isSymbolicLink = stats.isSymbolicLink.bind(stats);
5440
- }
5441
- }
5442
- function createDirentFromStats(name, stats) {
5443
- return new DirentFromStats(name, stats);
5444
- }
5445
- fs$3.createDirentFromStats = createDirentFromStats;
5446
- return fs$3;
5447
- }
5448
-
5449
- var path = {};
5450
-
5451
- var hasRequiredPath;
5452
-
5453
- function requirePath () {
5454
- if (hasRequiredPath) return path;
5455
- hasRequiredPath = 1;
5456
- Object.defineProperty(path, "__esModule", { value: true });
5457
- path.convertPosixPathToPattern = path.convertWindowsPathToPattern = path.convertPathToPattern = path.escapePosixPath = path.escapeWindowsPath = path.escape = path.removeLeadingDotSegment = path.makeAbsolute = path.unixify = void 0;
5458
- const os = require$$0$4;
5459
- const path$1 = require$$0$5;
5460
- const IS_WINDOWS_PLATFORM = os.platform() === 'win32';
5461
- const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\
5462
- /**
5463
- * All non-escaped special characters.
5464
- * Posix: ()*?[]{|}, !+@ before (, ! at the beginning, \\ before non-special characters.
5465
- * Windows: (){}[], !+@ before (, ! at the beginning.
5466
- */
5467
- const POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g;
5468
- const WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()[\]{}]|^!|[!+@](?=\())/g;
5469
- /**
5470
- * The device path (\\.\ or \\?\).
5471
- * https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths
5472
- */
5473
- const DOS_DEVICE_PATH_RE = /^\\\\([.?])/;
5474
- /**
5475
- * All backslashes except those escaping special characters.
5476
- * Windows: !()+@{}
5477
- * https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
5478
- */
5479
- const WINDOWS_BACKSLASHES_RE = /\\(?![!()+@[\]{}])/g;
5480
- /**
5481
- * Designed to work only with simple paths: `dir\\file`.
5482
- */
5483
- function unixify(filepath) {
5484
- return filepath.replace(/\\/g, '/');
5485
- }
5486
- path.unixify = unixify;
5487
- function makeAbsolute(cwd, filepath) {
5488
- return path$1.resolve(cwd, filepath);
5489
- }
5490
- path.makeAbsolute = makeAbsolute;
5491
- function removeLeadingDotSegment(entry) {
5492
- // We do not use `startsWith` because this is 10x slower than current implementation for some cases.
5493
- // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
5494
- if (entry.charAt(0) === '.') {
5495
- const secondCharactery = entry.charAt(1);
5496
- if (secondCharactery === '/' || secondCharactery === '\\') {
5497
- return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT);
5498
- }
5499
- }
5500
- return entry;
5501
- }
5502
- path.removeLeadingDotSegment = removeLeadingDotSegment;
5503
- path.escape = IS_WINDOWS_PLATFORM ? escapeWindowsPath : escapePosixPath;
5504
- function escapeWindowsPath(pattern) {
5505
- return pattern.replace(WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2');
5506
- }
5507
- path.escapeWindowsPath = escapeWindowsPath;
5508
- function escapePosixPath(pattern) {
5509
- return pattern.replace(POSIX_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2');
5510
- }
5511
- path.escapePosixPath = escapePosixPath;
5512
- path.convertPathToPattern = IS_WINDOWS_PLATFORM ? convertWindowsPathToPattern : convertPosixPathToPattern;
5513
- function convertWindowsPathToPattern(filepath) {
5514
- return escapeWindowsPath(filepath)
5515
- .replace(DOS_DEVICE_PATH_RE, '//$1')
5516
- .replace(WINDOWS_BACKSLASHES_RE, '/');
5517
- }
5518
- path.convertWindowsPathToPattern = convertWindowsPathToPattern;
5519
- function convertPosixPathToPattern(filepath) {
5520
- return escapePosixPath(filepath);
5521
- }
5522
- path.convertPosixPathToPattern = convertPosixPathToPattern;
5523
- return path;
5261
+ var path = {};
5262
+
5263
+ var hasRequiredPath;
5264
+
5265
+ function requirePath () {
5266
+ if (hasRequiredPath) return path;
5267
+ hasRequiredPath = 1;
5268
+ Object.defineProperty(path, "__esModule", { value: true });
5269
+ path.convertPosixPathToPattern = path.convertWindowsPathToPattern = path.convertPathToPattern = path.escapePosixPath = path.escapeWindowsPath = path.escape = path.removeLeadingDotSegment = path.makeAbsolute = path.unixify = void 0;
5270
+ const os = require$$0$4;
5271
+ const path$1 = require$$0$5;
5272
+ const IS_WINDOWS_PLATFORM = os.platform() === 'win32';
5273
+ const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\
5274
+ /**
5275
+ * All non-escaped special characters.
5276
+ * Posix: ()*?[]{|}, !+@ before (, ! at the beginning, \\ before non-special characters.
5277
+ * Windows: (){}[], !+@ before (, ! at the beginning.
5278
+ */
5279
+ const POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g;
5280
+ const WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()[\]{}]|^!|[!+@](?=\())/g;
5281
+ /**
5282
+ * The device path (\\.\ or \\?\).
5283
+ * https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths
5284
+ */
5285
+ const DOS_DEVICE_PATH_RE = /^\\\\([.?])/;
5286
+ /**
5287
+ * All backslashes except those escaping special characters.
5288
+ * Windows: !()+@{}
5289
+ * https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
5290
+ */
5291
+ const WINDOWS_BACKSLASHES_RE = /\\(?![!()+@[\]{}])/g;
5292
+ /**
5293
+ * Designed to work only with simple paths: `dir\\file`.
5294
+ */
5295
+ function unixify(filepath) {
5296
+ return filepath.replace(/\\/g, '/');
5297
+ }
5298
+ path.unixify = unixify;
5299
+ function makeAbsolute(cwd, filepath) {
5300
+ return path$1.resolve(cwd, filepath);
5301
+ }
5302
+ path.makeAbsolute = makeAbsolute;
5303
+ function removeLeadingDotSegment(entry) {
5304
+ // We do not use `startsWith` because this is 10x slower than current implementation for some cases.
5305
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
5306
+ if (entry.charAt(0) === '.') {
5307
+ const secondCharactery = entry.charAt(1);
5308
+ if (secondCharactery === '/' || secondCharactery === '\\') {
5309
+ return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT);
5310
+ }
5311
+ }
5312
+ return entry;
5313
+ }
5314
+ path.removeLeadingDotSegment = removeLeadingDotSegment;
5315
+ path.escape = IS_WINDOWS_PLATFORM ? escapeWindowsPath : escapePosixPath;
5316
+ function escapeWindowsPath(pattern) {
5317
+ return pattern.replace(WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2');
5318
+ }
5319
+ path.escapeWindowsPath = escapeWindowsPath;
5320
+ function escapePosixPath(pattern) {
5321
+ return pattern.replace(POSIX_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2');
5322
+ }
5323
+ path.escapePosixPath = escapePosixPath;
5324
+ path.convertPathToPattern = IS_WINDOWS_PLATFORM ? convertWindowsPathToPattern : convertPosixPathToPattern;
5325
+ function convertWindowsPathToPattern(filepath) {
5326
+ return escapeWindowsPath(filepath)
5327
+ .replace(DOS_DEVICE_PATH_RE, '//$1')
5328
+ .replace(WINDOWS_BACKSLASHES_RE, '/');
5329
+ }
5330
+ path.convertWindowsPathToPattern = convertWindowsPathToPattern;
5331
+ function convertPosixPathToPattern(filepath) {
5332
+ return escapePosixPath(filepath);
5333
+ }
5334
+ path.convertPosixPathToPattern = convertPosixPathToPattern;
5335
+ return path;
5524
5336
  }
5525
5337
 
5526
5338
  var pattern = {};
@@ -8944,7 +8756,7 @@ function requireJsTokens () {
8944
8756
  // Copyright 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell
8945
8757
  // License: MIT.
8946
8758
  var HashbangComment, Identifier, JSXIdentifier, JSXPunctuator, JSXString, JSXText, KeywordsWithExpressionAfter, KeywordsWithNoLineTerminatorAfter, LineTerminatorSequence, MultiLineComment, Newline, NumericLiteral, Punctuator, RegularExpressionLiteral, SingleLineComment, StringLiteral, Template, TokensNotPrecedingObjectLiteral, TokensPrecedingExpression, WhiteSpace;
8947
- RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:[^\]\\\n\r\u2028\u2029]+|\\.)*\]|[^\/\\\n\r\u2028\u2029]+|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu;
8759
+ RegularExpressionLiteral = /\/(?![*\/])(?:\[(?:[^\]\\\n\r\u2028\u2029]+|\\.)*\]?|[^\/[\\\n\r\u2028\u2029]+|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu;
8948
8760
  Punctuator = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y;
8949
8761
  Identifier = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]+|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/yu;
8950
8762
  StringLiteral = /(['"])(?:[^'"\\\n\r]+|(?!\1)['"]|\\(?:\r\n|[^]))*(\1)?/y;
@@ -9447,7 +9259,7 @@ function NormalizeURLPlugin() {
9447
9259
  };
9448
9260
  }
9449
9261
 
9450
- function resolveOptimizerConfig(_testOptions, viteOptions, testConfig) {
9262
+ function resolveOptimizerConfig(_testOptions, viteOptions, testConfig, viteCacheDir) {
9451
9263
  const testOptions = _testOptions || {};
9452
9264
  const newConfig = {};
9453
9265
  const [major, minor, fix] = version.split(".").map(Number);
@@ -9468,7 +9280,6 @@ function resolveOptimizerConfig(_testOptions, viteOptions, testConfig) {
9468
9280
  };
9469
9281
  } else {
9470
9282
  const root = testConfig.root ?? process.cwd();
9471
- const cacheDir = testConfig.cache !== false ? testConfig.cache?.dir : void 0;
9472
9283
  const currentInclude = testOptions.include || viteOptions?.include || [];
9473
9284
  const exclude = [
9474
9285
  "vitest",
@@ -9484,7 +9295,7 @@ function resolveOptimizerConfig(_testOptions, viteOptions, testConfig) {
9484
9295
  const include = (testOptions.include || viteOptions?.include || []).filter(
9485
9296
  (n) => !exclude.includes(n)
9486
9297
  );
9487
- newConfig.cacheDir = cacheDir ?? VitestCache.resolveCacheDir(root, cacheDir, testConfig.name);
9298
+ newConfig.cacheDir = testConfig.cache !== false && testConfig.cache?.dir || VitestCache.resolveCacheDir(root, viteCacheDir, testConfig.name);
9488
9299
  newConfig.optimizeDeps = {
9489
9300
  ...viteOptions,
9490
9301
  ...testOptions,
@@ -9567,12 +9378,14 @@ function VitestOptimizer() {
9567
9378
  const webOptimizer = resolveOptimizerConfig(
9568
9379
  testConfig.deps?.optimizer?.web,
9569
9380
  viteConfig.optimizeDeps,
9570
- testConfig
9381
+ testConfig,
9382
+ viteConfig.cacheDir
9571
9383
  );
9572
9384
  const ssrOptimizer = resolveOptimizerConfig(
9573
9385
  testConfig.deps?.optimizer?.ssr,
9574
9386
  viteConfig.ssr?.optimizeDeps,
9575
- testConfig
9387
+ testConfig,
9388
+ viteConfig.cacheDir
9576
9389
  );
9577
9390
  viteConfig.cacheDir = webOptimizer.cacheDir || ssrOptimizer.cacheDir || viteConfig.cacheDir;
9578
9391
  viteConfig.optimizeDeps = webOptimizer.optimizeDeps;
@@ -9753,7 +9566,7 @@ function WorkspaceVitestPlugin(project, options) {
9753
9566
  },
9754
9567
  async configureServer(server) {
9755
9568
  const options2 = deepMerge({}, configDefaults, server.config.test || {});
9756
- await project.setServer(options2, server);
9569
+ await project._configureServer(options2, server);
9757
9570
  await server.watcher.close();
9758
9571
  }
9759
9572
  },
@@ -9783,14 +9596,17 @@ class TestSpecification {
9783
9596
  project;
9784
9597
  moduleId;
9785
9598
  pool;
9599
+ /** @private */
9600
+ testLocations;
9786
9601
  // public readonly location: WorkspaceSpecLocation | undefined
9787
- constructor(workspaceProject, moduleId, pool) {
9788
- this[0] = workspaceProject;
9602
+ constructor(project, moduleId, pool, testLocations) {
9603
+ this[0] = project;
9789
9604
  this[1] = moduleId;
9790
9605
  this[2] = { pool };
9791
- this.project = workspaceProject.testProject;
9606
+ this.project = project;
9792
9607
  this.moduleId = moduleId;
9793
9608
  this.pool = pool;
9609
+ this.testLocations = testLocations;
9794
9610
  }
9795
9611
  toJSON() {
9796
9612
  return [
@@ -9807,7 +9623,7 @@ class TestSpecification {
9807
9623
  * @deprecated
9808
9624
  */
9809
9625
  *[Symbol.iterator]() {
9810
- yield this.project.workspaceProject;
9626
+ yield this.project;
9811
9627
  yield this.moduleId;
9812
9628
  yield this.pool;
9813
9629
  }
@@ -9822,56 +9638,53 @@ async function createViteServer(inlineConfig) {
9822
9638
  error(...args);
9823
9639
  };
9824
9640
  const server = await createServer(inlineConfig);
9825
- console.error = error;
9826
- return server;
9827
- }
9828
-
9829
- async function initializeProject(workspacePath, ctx, options) {
9830
- const project = new WorkspaceProject(workspacePath, ctx, options);
9831
- const root = options.root || (typeof workspacePath === "number" ? void 0 : workspacePath.endsWith("/") ? workspacePath : dirname(workspacePath));
9832
- const configFile = options.extends ? resolve(dirname(options.workspaceConfigPath), options.extends) : typeof workspacePath === "number" || workspacePath.endsWith("/") ? false : workspacePath;
9833
- const config = {
9834
- ...options,
9835
- root,
9836
- configFile,
9837
- // this will make "mode": "test" | "benchmark" inside defineConfig
9838
- mode: options.test?.mode || options.mode || ctx.config.mode,
9839
- plugins: [
9840
- ...options.plugins || [],
9841
- WorkspaceVitestPlugin(project, { ...options, root, workspacePath })
9842
- ]
9843
- };
9844
- await createViteServer(config);
9845
- return project;
9641
+ console.error = error;
9642
+ return server;
9846
9643
  }
9847
- class WorkspaceProject {
9848
- constructor(path2, ctx, options) {
9644
+
9645
+ class TestProject {
9646
+ constructor(path2, vitest, options) {
9849
9647
  this.path = path2;
9850
- this.ctx = ctx;
9851
9648
  this.options = options;
9649
+ this.vitest = vitest;
9650
+ this.ctx = vitest;
9651
+ this.globalConfig = vitest.config;
9852
9652
  }
9853
- configOverride;
9854
- config;
9855
- server;
9653
+ /**
9654
+ * The global Vitest instance.
9655
+ * @experimental The public Vitest API is experimental and does not follow semver.
9656
+ */
9657
+ vitest;
9658
+ /**
9659
+ * Resolved global configuration. If there are no workspace projects, this will be the same as `config`.
9660
+ */
9661
+ globalConfig;
9662
+ /**
9663
+ * Browser instance if the browser is enabled. This is initialized when the tests run for the first time.
9664
+ */
9665
+ browser;
9666
+ /** @deprecated use `vitest` instead */
9667
+ ctx;
9668
+ /**
9669
+ * Temporary directory for the project. This is unique for each project. Vitest stores transformed content here.
9670
+ */
9671
+ tmpDir = join(tmpdir(), nanoid());
9856
9672
  vitenode;
9857
9673
  runner;
9858
- browser;
9859
9674
  typechecker;
9860
9675
  closingPromise;
9861
9676
  testFilesList = null;
9862
9677
  typecheckFilesList = null;
9863
- testProject;
9864
- id = nanoid();
9865
- tmpDir = join(tmpdir(), this.id);
9866
9678
  _globalSetups;
9867
9679
  _provided = {};
9868
- getName() {
9869
- return this.config.name || "";
9870
- }
9871
- isCore() {
9872
- return this.ctx.getCoreWorkspaceProject() === this;
9873
- }
9874
- provide(key, value) {
9680
+ _config;
9681
+ _vite;
9682
+ // "provide" is a property, not a method to keep the context when destructed in the global setup,
9683
+ // making it a method would be a breaking change, and can be done in Vitest 3 at minimum
9684
+ /**
9685
+ * Provide a value to the test context. This value will be available to all tests with `inject`.
9686
+ */
9687
+ provide = (key, value) => {
9875
9688
  try {
9876
9689
  structuredClone(value);
9877
9690
  } catch (err) {
@@ -9883,20 +9696,92 @@ class WorkspaceProject {
9883
9696
  );
9884
9697
  }
9885
9698
  this._provided[key] = value;
9886
- }
9699
+ };
9700
+ /**
9701
+ * Get the provided context. The project context is merged with the global context.
9702
+ */
9887
9703
  getProvidedContext() {
9888
- if (this.isCore()) {
9704
+ if (this.isRootProject()) {
9889
9705
  return this._provided;
9890
9706
  }
9891
9707
  return {
9892
- ...this.ctx.getCoreWorkspaceProject().getProvidedContext(),
9708
+ ...this.vitest.getRootTestProject().getProvidedContext(),
9893
9709
  ...this._provided
9894
9710
  };
9895
9711
  }
9712
+ /**
9713
+ * Creates a new test specification. Specifications describe how to run tests.
9714
+ * @param moduleId The file path
9715
+ */
9716
+ createSpecification(moduleId, pool, testLocations) {
9717
+ return new TestSpecification(
9718
+ this,
9719
+ moduleId,
9720
+ pool || getFilePoolName(this, moduleId),
9721
+ testLocations
9722
+ );
9723
+ }
9724
+ toJSON() {
9725
+ return {
9726
+ name: this.name,
9727
+ serializedConfig: this.serializedConfig,
9728
+ context: this.getProvidedContext()
9729
+ };
9730
+ }
9731
+ /**
9732
+ * Vite's dev server instance. Every workspace project has its own server.
9733
+ */
9734
+ get vite() {
9735
+ if (!this._vite) {
9736
+ throw new Error("The server was not set. It means that `project.vite` was called before the Vite server was established.");
9737
+ }
9738
+ return this._vite;
9739
+ }
9740
+ /**
9741
+ * Resolved project configuration.
9742
+ */
9743
+ get config() {
9744
+ if (!this._config) {
9745
+ throw new Error("The config was not set. It means that `project.config` was called before the Vite server was established.");
9746
+ }
9747
+ return this._config;
9748
+ }
9749
+ /**
9750
+ * The name of the project or an empty string if not set.
9751
+ */
9752
+ get name() {
9753
+ return this.config.name || "";
9754
+ }
9755
+ /**
9756
+ * Serialized project configuration. This is the config that tests receive.
9757
+ */
9758
+ get serializedConfig() {
9759
+ return this._serializeOverridenConfig();
9760
+ }
9761
+ /** @deprecated use `vite` instead */
9762
+ get server() {
9763
+ return this._vite;
9764
+ }
9765
+ /**
9766
+ * Check if this is the root project. The root project is the one that has the root config.
9767
+ */
9768
+ isRootProject() {
9769
+ return this.vitest.getRootTestProject() === this;
9770
+ }
9771
+ /** @deprecated use `isRootProject` instead */
9772
+ isCore() {
9773
+ return this.isRootProject();
9774
+ }
9775
+ /** @deprecated use `createSpecification` instead */
9896
9776
  createSpec(moduleId, pool) {
9897
9777
  return new TestSpecification(this, moduleId, pool);
9898
9778
  }
9899
- async initializeGlobalSetup() {
9779
+ /** @deprecated */
9780
+ initializeGlobalSetup() {
9781
+ return this._initializeGlobalSetup();
9782
+ }
9783
+ /** @internal */
9784
+ async _initializeGlobalSetup() {
9900
9785
  if (this._globalSetups) {
9901
9786
  return;
9902
9787
  }
@@ -9905,11 +9790,7 @@ class WorkspaceProject {
9905
9790
  this.config.globalSetup
9906
9791
  );
9907
9792
  for (const globalSetupFile of this._globalSetups) {
9908
- const teardown = await globalSetupFile.setup?.({
9909
- provide: (key, value) => this.provide(key, value),
9910
- config: this.config,
9911
- onTestsRerun: (cb) => this.ctx.onTestsRerun(cb)
9912
- });
9793
+ const teardown = await globalSetupFile.setup?.(this);
9913
9794
  if (teardown == null || !!globalSetupFile.teardown) {
9914
9795
  continue;
9915
9796
  }
@@ -9921,7 +9802,15 @@ class WorkspaceProject {
9921
9802
  globalSetupFile.teardown = teardown;
9922
9803
  }
9923
9804
  }
9924
- async teardownGlobalSetup() {
9805
+ onTestsRerun(cb) {
9806
+ this.vitest.onTestsRerun(cb);
9807
+ }
9808
+ /** @deprecated */
9809
+ teardownGlobalSetup() {
9810
+ return this._teardownGlobalSetup();
9811
+ }
9812
+ /** @internal */
9813
+ async _teardownGlobalSetup() {
9925
9814
  if (!this._globalSetups) {
9926
9815
  return;
9927
9816
  }
@@ -9929,24 +9818,33 @@ class WorkspaceProject {
9929
9818
  await globalSetupFile.teardown?.();
9930
9819
  }
9931
9820
  }
9821
+ /** @deprecated use `vitest.logger` instead */
9932
9822
  get logger() {
9933
- return this.ctx.logger;
9823
+ return this.vitest.logger;
9934
9824
  }
9935
9825
  // it's possible that file path was imported with different queries (?raw, ?url, etc)
9826
+ /** @deprecated use `.vite` or `.browser.vite` directly */
9936
9827
  getModulesByFilepath(file) {
9937
9828
  const set = this.server.moduleGraph.getModulesByFile(file) || this.browser?.vite.moduleGraph.getModulesByFile(file);
9938
9829
  return set || /* @__PURE__ */ new Set();
9939
9830
  }
9831
+ /** @deprecated use `.vite` or `.browser.vite` directly */
9940
9832
  getModuleById(id) {
9941
9833
  return this.server.moduleGraph.getModuleById(id) || this.browser?.vite.moduleGraph.getModuleById(id);
9942
9834
  }
9835
+ /** @deprecated use `.vite` or `.browser.vite` directly */
9943
9836
  getSourceMapModuleById(id) {
9944
9837
  const mod = this.server.moduleGraph.getModuleById(id);
9945
9838
  return mod?.ssrTransformResult?.map || mod?.transformResult?.map;
9946
9839
  }
9840
+ /** @deprecated use `vitest.reporters` instead */
9947
9841
  get reporters() {
9948
9842
  return this.ctx.reporters;
9949
9843
  }
9844
+ /**
9845
+ * Get all files in the project that match the globs in the config and the filters.
9846
+ * @param filters String filters to match the test files.
9847
+ */
9950
9848
  async globTestFiles(filters = []) {
9951
9849
  const dir = this.config.dir || this.config.root;
9952
9850
  const { include, exclude, includeSource } = this.config;
@@ -9980,7 +9878,7 @@ class WorkspaceProject {
9980
9878
  files.map(async (file) => {
9981
9879
  try {
9982
9880
  const code = await promises.readFile(file, "utf-8");
9983
- if (this.isInSourceTestFile(code)) {
9881
+ if (this.isInSourceTestCode(code)) {
9984
9882
  testFiles.push(file);
9985
9883
  }
9986
9884
  } catch {
@@ -9992,12 +9890,32 @@ class WorkspaceProject {
9992
9890
  this.testFilesList = testFiles;
9993
9891
  return testFiles;
9994
9892
  }
9995
- isTestFile(id) {
9996
- return this.testFilesList && this.testFilesList.includes(id);
9893
+ isBrowserEnabled() {
9894
+ return isBrowserEnabled(this.config);
9895
+ }
9896
+ /** @internal */
9897
+ _markTestFile(testPath) {
9898
+ this.testFilesList?.push(testPath);
9899
+ }
9900
+ /**
9901
+ * Returns if the file is a test file. Requires `.globTestFiles()` to be called first.
9902
+ * @internal
9903
+ */
9904
+ isTestFile(testPath) {
9905
+ return !!this.testFilesList && this.testFilesList.includes(testPath);
9906
+ }
9907
+ /**
9908
+ * Returns if the file is a typecheck test file. Requires `.globTestFiles()` to be called first.
9909
+ * @internal
9910
+ */
9911
+ isTypecheckFile(testPath) {
9912
+ return !!this.typecheckFilesList && this.typecheckFilesList.includes(testPath);
9997
9913
  }
9998
- isTypecheckFile(id) {
9999
- return this.typecheckFilesList && this.typecheckFilesList.includes(id);
9914
+ /** @deprecated use `serializedConfig` instead */
9915
+ getSerializableConfig() {
9916
+ return this._serializeOverridenConfig();
10000
9917
  }
9918
+ /** @internal */
10001
9919
  async globFiles(include, exclude, cwd) {
10002
9920
  const globOptions = {
10003
9921
  dot: true,
@@ -10007,8 +9925,11 @@ class WorkspaceProject {
10007
9925
  const files = await fg(include, globOptions);
10008
9926
  return files.map((file) => slash(a.resolve(cwd, file)));
10009
9927
  }
10010
- async isTargetFile(id, source) {
10011
- const relativeId = relative(this.config.dir || this.config.root, id);
9928
+ /**
9929
+ * Test if a file matches the test globs. This does the actual glob matching unlike `isTestFile`.
9930
+ */
9931
+ matchesTestGlob(filepath, source) {
9932
+ const relativeId = relative(this.config.dir || this.config.root, filepath);
10012
9933
  if (mm.isMatch(relativeId, this.config.exclude)) {
10013
9934
  return false;
10014
9935
  }
@@ -10016,12 +9937,16 @@ class WorkspaceProject {
10016
9937
  return true;
10017
9938
  }
10018
9939
  if (this.config.includeSource?.length && mm.isMatch(relativeId, this.config.includeSource)) {
10019
- source = source || await promises.readFile(id, "utf-8");
10020
- return this.isInSourceTestFile(source);
9940
+ const code = source || readFileSync(filepath, "utf-8");
9941
+ return this.isInSourceTestCode(code);
10021
9942
  }
10022
9943
  return false;
10023
9944
  }
10024
- isInSourceTestFile(code) {
9945
+ /** @deprecated use `matchesTestGlob` instead */
9946
+ async isTargetFile(id, source) {
9947
+ return this.matchesTestGlob(id, source);
9948
+ }
9949
+ isInSourceTestCode(code) {
10025
9950
  return code.includes("import.meta.vitest");
10026
9951
  }
10027
9952
  filterFiles(testFiles, filters, dir) {
@@ -10042,15 +9967,16 @@ class WorkspaceProject {
10042
9967
  }
10043
9968
  return testFiles;
10044
9969
  }
10045
- async initBrowserServer() {
9970
+ /** @internal */
9971
+ async _initBrowserServer() {
10046
9972
  if (!this.isBrowserEnabled() || this.browser) {
10047
9973
  return;
10048
9974
  }
10049
- await this.ctx.packageInstaller.ensureInstalled("@vitest/browser", this.config.root, this.ctx.version);
9975
+ await this.vitest.packageInstaller.ensureInstalled("@vitest/browser", this.config.root, this.ctx.version);
10050
9976
  const { createBrowserServer, distRoot } = await import('@vitest/browser');
10051
9977
  const browser = await createBrowserServer(
10052
9978
  this,
10053
- this.server.config.configFile,
9979
+ this.vite.config.configFile,
10054
9980
  [
10055
9981
  ...MocksPlugins({
10056
9982
  filter(id) {
@@ -10065,108 +9991,385 @@ class WorkspaceProject {
10065
9991
  );
10066
9992
  this.browser = browser;
10067
9993
  if (this.config.browser.ui) {
10068
- setup(this.ctx, browser.vite);
9994
+ setup(this.vitest, browser.vite);
9995
+ }
9996
+ }
9997
+ /**
9998
+ * Closes the project and all associated resources. This can only be called once; the closing promise is cached until the server restarts.
9999
+ * If the resources are needed again, create a new project.
10000
+ */
10001
+ close() {
10002
+ if (!this.closingPromise) {
10003
+ this.closingPromise = Promise.all(
10004
+ [
10005
+ this.vite?.close(),
10006
+ this.typechecker?.stop(),
10007
+ this.browser?.close(),
10008
+ this.clearTmpDir()
10009
+ ].filter(Boolean)
10010
+ ).then(() => {
10011
+ this._provided = {};
10012
+ this._vite = void 0;
10013
+ });
10014
+ }
10015
+ return this.closingPromise;
10016
+ }
10017
+ /** @deprecated use `name` instead */
10018
+ getName() {
10019
+ return this.config.name || "";
10020
+ }
10021
+ /** @deprecated internal */
10022
+ setServer(options, server) {
10023
+ return this._configureServer(options, server);
10024
+ }
10025
+ /** @internal */
10026
+ async _configureServer(options, server) {
10027
+ this._config = resolveConfig(
10028
+ this.vitest.mode,
10029
+ {
10030
+ ...options,
10031
+ coverage: this.vitest.config.coverage
10032
+ },
10033
+ server.config,
10034
+ this.vitest.logger
10035
+ );
10036
+ for (const _providedKey in this.config.provide) {
10037
+ const providedKey = _providedKey;
10038
+ this.provide(
10039
+ providedKey,
10040
+ this.config.provide[providedKey]
10041
+ );
10042
+ }
10043
+ this.closingPromise = void 0;
10044
+ this._vite = server;
10045
+ this.vitenode = new ViteNodeServer(server, this.config.server);
10046
+ const node = this.vitenode;
10047
+ this.runner = new ViteNodeRunner({
10048
+ root: server.config.root,
10049
+ base: server.config.base,
10050
+ fetchModule(id) {
10051
+ return node.fetchModule(id);
10052
+ },
10053
+ resolveId(id, importer) {
10054
+ return node.resolveId(id, importer);
10055
+ }
10056
+ });
10057
+ }
10058
+ _serializeOverridenConfig() {
10059
+ const config = serializeConfig(
10060
+ this.config,
10061
+ this.vitest.config,
10062
+ this.vite.config
10063
+ );
10064
+ if (!this.vitest.configOverride) {
10065
+ return config;
10066
+ }
10067
+ return deepMerge(
10068
+ config,
10069
+ this.vitest.configOverride
10070
+ );
10071
+ }
10072
+ async clearTmpDir() {
10073
+ try {
10074
+ await rm(this.tmpDir, { recursive: true });
10075
+ } catch {
10076
+ }
10077
+ }
10078
+ /** @deprecated */
10079
+ initBrowserProvider() {
10080
+ return this._initBrowserProvider();
10081
+ }
10082
+ /** @internal */
10083
+ async _initBrowserProvider() {
10084
+ if (!this.isBrowserEnabled() || this.browser?.provider) {
10085
+ return;
10086
+ }
10087
+ if (!this.browser) {
10088
+ await this._initBrowserServer();
10089
+ }
10090
+ await this.browser?.initBrowserProvider();
10091
+ }
10092
+ /** @internal */
10093
+ static _createBasicProject(vitest) {
10094
+ const project = new TestProject(
10095
+ vitest.config.name || vitest.config.root,
10096
+ vitest
10097
+ );
10098
+ project.vitenode = vitest.vitenode;
10099
+ project.runner = vitest.runner;
10100
+ project._vite = vitest.server;
10101
+ project._config = vitest.config;
10102
+ for (const _providedKey in vitest.config.provide) {
10103
+ const providedKey = _providedKey;
10104
+ project.provide(
10105
+ providedKey,
10106
+ vitest.config.provide[providedKey]
10107
+ );
10108
+ }
10109
+ return project;
10110
+ }
10111
+ }
10112
+ async function initializeProject(workspacePath, ctx, options) {
10113
+ const project = new TestProject(workspacePath, ctx, options);
10114
+ const { extends: extendsConfig, configFile, ...restOptions } = options;
10115
+ const config = {
10116
+ ...restOptions,
10117
+ configFile,
10118
+ // this will make "mode": "test" | "benchmark" inside defineConfig
10119
+ mode: options.test?.mode || options.mode || ctx.config.mode,
10120
+ plugins: [
10121
+ ...options.plugins || [],
10122
+ WorkspaceVitestPlugin(project, { ...options, workspacePath })
10123
+ ]
10124
+ };
10125
+ await createViteServer(config);
10126
+ return project;
10127
+ }
10128
+
10129
+ async function loadCustomReporterModule(path, runner) {
10130
+ let customReporterModule;
10131
+ try {
10132
+ customReporterModule = await runner.executeId(path);
10133
+ } catch (customReporterModuleError) {
10134
+ throw new Error(`Failed to load custom Reporter from ${path}`, {
10135
+ cause: customReporterModuleError
10136
+ });
10137
+ }
10138
+ if (customReporterModule.default === null || customReporterModule.default === void 0) {
10139
+ throw new Error(
10140
+ `Custom reporter loaded from ${path} was not the default export`
10141
+ );
10142
+ }
10143
+ return customReporterModule.default;
10144
+ }
10145
+ function createReporters(reporterReferences, ctx) {
10146
+ const runner = ctx.runner;
10147
+ const promisedReporters = reporterReferences.map(
10148
+ async (referenceOrInstance) => {
10149
+ if (Array.isArray(referenceOrInstance)) {
10150
+ const [reporterName, reporterOptions] = referenceOrInstance;
10151
+ if (reporterName === "html") {
10152
+ await ctx.packageInstaller.ensureInstalled("@vitest/ui", runner.root, ctx.version);
10153
+ const CustomReporter = await loadCustomReporterModule(
10154
+ "@vitest/ui/reporter",
10155
+ runner
10156
+ );
10157
+ return new CustomReporter(reporterOptions);
10158
+ } else if (reporterName in ReportersMap) {
10159
+ const BuiltinReporter = ReportersMap[reporterName];
10160
+ return new BuiltinReporter(reporterOptions);
10161
+ } else {
10162
+ const CustomReporter = await loadCustomReporterModule(
10163
+ reporterName,
10164
+ runner
10165
+ );
10166
+ return new CustomReporter(reporterOptions);
10167
+ }
10168
+ }
10169
+ return referenceOrInstance;
10170
+ }
10171
+ );
10172
+ return Promise.all(promisedReporters);
10173
+ }
10174
+ function createBenchmarkReporters(reporterReferences, runner) {
10175
+ const promisedReporters = reporterReferences.map(
10176
+ async (referenceOrInstance) => {
10177
+ if (typeof referenceOrInstance === "string") {
10178
+ if (referenceOrInstance in BenchmarkReportsMap) {
10179
+ const BuiltinReporter = BenchmarkReportsMap[referenceOrInstance];
10180
+ return new BuiltinReporter();
10181
+ } else {
10182
+ const CustomReporter = await loadCustomReporterModule(
10183
+ referenceOrInstance,
10184
+ runner
10185
+ );
10186
+ return new CustomReporter();
10187
+ }
10188
+ }
10189
+ return referenceOrInstance;
10190
+ }
10191
+ );
10192
+ return Promise.all(promisedReporters);
10193
+ }
10194
+
10195
+ function isAggregateError(err) {
10196
+ if (typeof AggregateError !== "undefined" && err instanceof AggregateError) {
10197
+ return true;
10198
+ }
10199
+ return err instanceof Error && "errors" in err;
10200
+ }
10201
+ class StateManager {
10202
+ filesMap = /* @__PURE__ */ new Map();
10203
+ pathsSet = /* @__PURE__ */ new Set();
10204
+ idMap = /* @__PURE__ */ new Map();
10205
+ taskFileMap = /* @__PURE__ */ new WeakMap();
10206
+ errorsSet = /* @__PURE__ */ new Set();
10207
+ processTimeoutCauses = /* @__PURE__ */ new Set();
10208
+ reportedTasksMap = /* @__PURE__ */ new WeakMap();
10209
+ catchError(err, type) {
10210
+ if (isAggregateError(err)) {
10211
+ return err.errors.forEach((error) => this.catchError(error, type));
10212
+ }
10213
+ if (err === Object(err)) {
10214
+ err.type = type;
10215
+ } else {
10216
+ err = { type, message: err };
10217
+ }
10218
+ const _err = err;
10219
+ if (_err && typeof _err === "object" && _err.code === "VITEST_PENDING") {
10220
+ const task = this.idMap.get(_err.taskId);
10221
+ if (task) {
10222
+ task.mode = "skip";
10223
+ task.result ??= { state: "skip" };
10224
+ task.result.state = "skip";
10225
+ task.result.note = _err.note;
10226
+ }
10227
+ return;
10069
10228
  }
10229
+ this.errorsSet.add(err);
10070
10230
  }
10071
- static createBasicProject(ctx) {
10072
- const project = new WorkspaceProject(
10073
- ctx.config.name || ctx.config.root,
10074
- ctx
10075
- );
10076
- project.vitenode = ctx.vitenode;
10077
- project.server = ctx.server;
10078
- project.runner = ctx.runner;
10079
- project.config = ctx.config;
10080
- for (const _providedKey in ctx.config.provide) {
10081
- const providedKey = _providedKey;
10082
- project.provide(
10083
- providedKey,
10084
- ctx.config.provide[providedKey]
10085
- );
10231
+ clearErrors() {
10232
+ this.errorsSet.clear();
10233
+ }
10234
+ getUnhandledErrors() {
10235
+ return Array.from(this.errorsSet.values());
10236
+ }
10237
+ addProcessTimeoutCause(cause) {
10238
+ this.processTimeoutCauses.add(cause);
10239
+ }
10240
+ getProcessTimeoutCauses() {
10241
+ return Array.from(this.processTimeoutCauses.values());
10242
+ }
10243
+ getPaths() {
10244
+ return Array.from(this.pathsSet);
10245
+ }
10246
+ /**
10247
+ * Return files that were running or collected.
10248
+ */
10249
+ getFiles(keys) {
10250
+ if (keys) {
10251
+ return keys.map((key) => this.filesMap.get(key)).flat().filter((file) => file && !file.local);
10086
10252
  }
10087
- project.testProject = new TestProject(project);
10088
- return project;
10253
+ return Array.from(this.filesMap.values()).flat().filter((file) => !file.local).sort((f1, f2) => {
10254
+ if (f1.meta?.typecheck && f2.meta?.typecheck) {
10255
+ return 0;
10256
+ }
10257
+ if (f1.meta?.typecheck) {
10258
+ return -1;
10259
+ }
10260
+ return 1;
10261
+ });
10089
10262
  }
10090
- static async createCoreProject(ctx) {
10091
- return WorkspaceProject.createBasicProject(ctx);
10263
+ getTestModules(keys) {
10264
+ return this.getFiles(keys).map((file) => this.getReportedEntity(file));
10092
10265
  }
10093
- async setServer(options, server) {
10094
- this.config = resolveConfig(
10095
- this.ctx.mode,
10096
- {
10097
- ...options,
10098
- coverage: this.ctx.config.coverage
10099
- },
10100
- server.config,
10101
- this.ctx.logger
10102
- );
10103
- for (const _providedKey in this.config.provide) {
10104
- const providedKey = _providedKey;
10105
- this.provide(
10106
- providedKey,
10107
- this.config.provide[providedKey]
10266
+ getFilepaths() {
10267
+ return Array.from(this.filesMap.keys());
10268
+ }
10269
+ getFailedFilepaths() {
10270
+ return this.getFiles().filter((i) => i.result?.state === "fail").map((i) => i.filepath);
10271
+ }
10272
+ collectPaths(paths = []) {
10273
+ paths.forEach((path) => {
10274
+ this.pathsSet.add(path);
10275
+ });
10276
+ }
10277
+ collectFiles(project, files = []) {
10278
+ files.forEach((file) => {
10279
+ const existing = this.filesMap.get(file.filepath) || [];
10280
+ const otherFiles = existing.filter(
10281
+ (i) => i.projectName !== file.projectName || i.meta.typecheck !== file.meta.typecheck
10108
10282
  );
10109
- }
10110
- this.closingPromise = void 0;
10111
- this.testProject = new TestProject(this);
10112
- this.server = server;
10113
- this.vitenode = new ViteNodeServer(server, this.config.server);
10114
- const node = this.vitenode;
10115
- this.runner = new ViteNodeRunner({
10116
- root: server.config.root,
10117
- base: server.config.base,
10118
- fetchModule(id) {
10119
- return node.fetchModule(id);
10120
- },
10121
- resolveId(id, importer) {
10122
- return node.resolveId(id, importer);
10283
+ const currentFile = existing.find(
10284
+ (i) => i.projectName === file.projectName
10285
+ );
10286
+ if (currentFile) {
10287
+ file.logs = currentFile.logs;
10123
10288
  }
10289
+ otherFiles.push(file);
10290
+ this.filesMap.set(file.filepath, otherFiles);
10291
+ this.updateId(file, project);
10124
10292
  });
10125
10293
  }
10126
- isBrowserEnabled() {
10127
- return isBrowserEnabled(this.config);
10294
+ clearFiles(project, paths = []) {
10295
+ paths.forEach((path) => {
10296
+ const files = this.filesMap.get(path);
10297
+ const fileTask = createFileTask(
10298
+ path,
10299
+ project.config.root,
10300
+ project.config.name
10301
+ );
10302
+ fileTask.local = true;
10303
+ TestModule.register(fileTask, project);
10304
+ this.idMap.set(fileTask.id, fileTask);
10305
+ if (!files) {
10306
+ this.filesMap.set(path, [fileTask]);
10307
+ return;
10308
+ }
10309
+ const filtered = files.filter(
10310
+ (file) => file.projectName !== project.config.name
10311
+ );
10312
+ if (!filtered.length) {
10313
+ this.filesMap.set(path, [fileTask]);
10314
+ } else {
10315
+ this.filesMap.set(path, [...filtered, fileTask]);
10316
+ }
10317
+ });
10128
10318
  }
10129
- getSerializableConfig() {
10130
- const config = serializeConfig(
10131
- this.config,
10132
- this.ctx.config,
10133
- this.server.config
10134
- );
10135
- if (!this.ctx.configOverride) {
10136
- return config;
10319
+ updateId(task, project) {
10320
+ if (this.idMap.get(task.id) === task) {
10321
+ return;
10137
10322
  }
10138
- return deepMerge(
10139
- config,
10140
- this.ctx.configOverride
10141
- );
10142
- }
10143
- close() {
10144
- if (!this.closingPromise) {
10145
- this.closingPromise = Promise.all(
10146
- [
10147
- this.server?.close(),
10148
- this.typechecker?.stop(),
10149
- this.browser?.close(),
10150
- this.clearTmpDir()
10151
- ].filter(Boolean)
10152
- ).then(() => this._provided = {});
10323
+ if (task.type === "suite" && "filepath" in task) {
10324
+ TestModule.register(task, project);
10325
+ } else if (task.type === "suite") {
10326
+ TestSuite.register(task, project);
10327
+ } else {
10328
+ TestCase.register(task, project);
10153
10329
  }
10154
- return this.closingPromise;
10155
- }
10156
- async clearTmpDir() {
10157
- try {
10158
- await rm(this.tmpDir, { recursive: true });
10159
- } catch {
10330
+ this.idMap.set(task.id, task);
10331
+ if (task.type === "suite") {
10332
+ task.tasks.forEach((task2) => {
10333
+ this.updateId(task2, project);
10334
+ });
10160
10335
  }
10161
10336
  }
10162
- async initBrowserProvider() {
10163
- if (!this.isBrowserEnabled() || this.browser?.provider) {
10164
- return;
10337
+ getReportedEntity(task) {
10338
+ return this.reportedTasksMap.get(task);
10339
+ }
10340
+ updateTasks(packs) {
10341
+ for (const [id, result, meta] of packs) {
10342
+ const task = this.idMap.get(id);
10343
+ if (task) {
10344
+ task.result = result;
10345
+ task.meta = meta;
10346
+ if (result?.state === "skip") {
10347
+ task.mode = "skip";
10348
+ }
10349
+ }
10165
10350
  }
10166
- if (!this.browser) {
10167
- await this.initBrowserServer();
10351
+ }
10352
+ updateUserLog(log) {
10353
+ const task = log.taskId && this.idMap.get(log.taskId);
10354
+ if (task) {
10355
+ if (!task.logs) {
10356
+ task.logs = [];
10357
+ }
10358
+ task.logs.push(log);
10168
10359
  }
10169
- await this.browser?.initBrowserProvider();
10360
+ }
10361
+ getCountOfFailedTests() {
10362
+ return Array.from(this.idMap.values()).filter(
10363
+ (t) => t.result?.state === "fail"
10364
+ ).length;
10365
+ }
10366
+ cancelFiles(files, project) {
10367
+ this.collectFiles(
10368
+ project,
10369
+ files.map(
10370
+ (filepath) => createFileTask(filepath, project.config.root, project.config.name)
10371
+ )
10372
+ );
10170
10373
  }
10171
10374
  }
10172
10375
 
@@ -10208,7 +10411,7 @@ function hasBraceExpansion(pattern) {
10208
10411
  }
10209
10412
 
10210
10413
  async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspaceDefinition) {
10211
- const { configFiles, projectConfigs, nonConfigDirectories } = await resolveWorkspaceProjectConfigs(
10414
+ const { configFiles, projectConfigs, nonConfigDirectories } = await resolveTestProjectConfigs(
10212
10415
  vitest,
10213
10416
  workspaceConfigPath,
10214
10417
  workspaceDefinition
@@ -10239,35 +10442,41 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
10239
10442
  const projectPromises = [];
10240
10443
  const fileProjects = [...configFiles, ...nonConfigDirectories];
10241
10444
  const concurrent = limitConcurrency(nodeos__default.availableParallelism?.() || nodeos__default.cpus().length || 5);
10242
- for (const filepath of fileProjects) {
10243
- if (vitest.server.config.configFile === filepath) {
10244
- projectPromises.push(concurrent(() => vitest._createCoreProject()));
10445
+ projectConfigs.forEach((options, index) => {
10446
+ const configRoot = workspaceConfigPath ? dirname(workspaceConfigPath) : vitest.config.root;
10447
+ const configFile = typeof options.extends === "string" ? resolve(configRoot, options.extends) : false;
10448
+ const rootOptions = options.extends === true ? vitest._options : {};
10449
+ const root = options.root ? resolve(configRoot, options.root) : vitest.config.root;
10450
+ projectPromises.push(concurrent(() => initializeProject(
10451
+ index,
10452
+ vitest,
10453
+ mergeConfig(rootOptions, { ...options, root, configFile })
10454
+ )));
10455
+ });
10456
+ for (const path of fileProjects) {
10457
+ if (vitest.server.config.configFile === path) {
10458
+ projectPromises.push(Promise.resolve(vitest._createRootProject()));
10245
10459
  continue;
10246
10460
  }
10461
+ const configFile = path.endsWith("/") ? false : path;
10462
+ const root = path.endsWith("/") ? path : dirname(path);
10247
10463
  projectPromises.push(
10248
10464
  concurrent(() => initializeProject(
10249
- filepath,
10465
+ path,
10250
10466
  vitest,
10251
- { workspaceConfigPath, test: cliOverrides }
10467
+ { root, configFile, test: cliOverrides }
10252
10468
  ))
10253
10469
  );
10254
10470
  }
10255
- projectConfigs.forEach((options, index) => {
10256
- projectPromises.push(concurrent(() => initializeProject(
10257
- index,
10258
- vitest,
10259
- mergeConfig(options, { workspaceConfigPath, test: cliOverrides })
10260
- )));
10261
- });
10262
10471
  if (!projectPromises.length) {
10263
- return [await vitest._createCoreProject()];
10472
+ return [vitest._createRootProject()];
10264
10473
  }
10265
10474
  const resolvedProjects = await Promise.all(projectPromises);
10266
10475
  const names = /* @__PURE__ */ new Set();
10267
10476
  for (const project of resolvedProjects) {
10268
- const name = project.getName();
10477
+ const name = project.name;
10269
10478
  if (names.has(name)) {
10270
- const duplicate = resolvedProjects.find((p) => p.getName() === name && p !== project);
10479
+ const duplicate = resolvedProjects.find((p) => p.name === name && p !== project);
10271
10480
  const filesError = fileProjects.length ? [
10272
10481
  "\n\nYour config matched these files:\n",
10273
10482
  fileProjects.map((p) => ` - ${relative(vitest.config.root, p)}`).join("\n"),
@@ -10275,9 +10484,9 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
10275
10484
  ].join("") : [" "];
10276
10485
  throw new Error([
10277
10486
  `Project name "${name}"`,
10278
- project.server.config.configFile ? ` from "${relative(vitest.config.root, project.server.config.configFile)}"` : "",
10487
+ project.vite.config.configFile ? ` from "${relative(vitest.config.root, project.vite.config.configFile)}"` : "",
10279
10488
  " is not unique.",
10280
- duplicate?.server.config.configFile ? ` The project is already defined by "${relative(vitest.config.root, duplicate.server.config.configFile)}".` : "",
10489
+ duplicate?.vite.config.configFile ? ` The project is already defined by "${relative(vitest.config.root, duplicate.vite.config.configFile)}".` : "",
10281
10490
  filesError,
10282
10491
  "All projects in a workspace should have unique names. Make sure your configuration is correct."
10283
10492
  ].join(""));
@@ -10286,19 +10495,20 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
10286
10495
  }
10287
10496
  return resolvedProjects;
10288
10497
  }
10289
- async function resolveWorkspaceProjectConfigs(vitest, workspaceConfigPath, workspaceDefinition) {
10498
+ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, workspaceDefinition) {
10290
10499
  const projectsOptions = [];
10291
10500
  const workspaceConfigFiles = [];
10292
10501
  const workspaceGlobMatches = [];
10293
10502
  const nonConfigProjectDirectories = [];
10294
- const relativeWorkpaceConfigPath = relative(vitest.config.root, workspaceConfigPath);
10295
10503
  for (const definition of workspaceDefinition) {
10296
10504
  if (typeof definition === "string") {
10297
10505
  const stringOption = definition.replace("<rootDir>", vitest.config.root);
10298
10506
  if (!isDynamicPattern(stringOption)) {
10299
10507
  const file = resolve(vitest.config.root, stringOption);
10300
10508
  if (!existsSync(file)) {
10301
- throw new Error(`Workspace config file "${relativeWorkpaceConfigPath}" references a non-existing file or a directory: ${file}`);
10509
+ const relativeWorkpaceConfigPath = workspaceConfigPath ? relative(vitest.config.root, workspaceConfigPath) : void 0;
10510
+ const note = workspaceConfigPath ? `Workspace config file "${relativeWorkpaceConfigPath}"` : "Inline workspace";
10511
+ throw new Error(`${note} references a non-existing file or a directory: ${file}`);
10302
10512
  }
10303
10513
  const stats = await promises.stat(file);
10304
10514
  if (stats.isFile()) {
@@ -10346,16 +10556,16 @@ async function resolveWorkspaceProjectConfigs(vitest, workspaceConfigPath, works
10346
10556
  ]
10347
10557
  };
10348
10558
  const workspacesFs = await fg.glob(workspaceGlobMatches, globOptions);
10349
- await Promise.all(workspacesFs.map(async (filepath) => {
10350
- if (filepath.endsWith("/")) {
10351
- const configFile = await resolveDirectoryConfig(filepath);
10559
+ await Promise.all(workspacesFs.map(async (path) => {
10560
+ if (path.endsWith("/")) {
10561
+ const configFile = await resolveDirectoryConfig(path);
10352
10562
  if (configFile) {
10353
10563
  workspaceConfigFiles.push(configFile);
10354
10564
  } else {
10355
- nonConfigProjectDirectories.push(filepath);
10565
+ nonConfigProjectDirectories.push(path);
10356
10566
  }
10357
10567
  } else {
10358
- workspaceConfigFiles.push(filepath);
10568
+ workspaceConfigFiles.push(path);
10359
10569
  }
10360
10570
  }));
10361
10571
  }
@@ -10405,6 +10615,8 @@ class Vitest {
10405
10615
  restartsCount = 0;
10406
10616
  runner = void 0;
10407
10617
  packageInstaller;
10618
+ /** TODO: rename to `_coreRootProject` */
10619
+ /** @internal */
10408
10620
  coreWorkspaceProject;
10409
10621
  /** @private */
10410
10622
  resolvedProjects = [];
@@ -10414,14 +10626,17 @@ class Vitest {
10414
10626
  _workspaceConfigPath;
10415
10627
  /** @deprecated use `_cachedSpecs` */
10416
10628
  projectTestFiles = this._cachedSpecs;
10417
- /** @private */
10629
+ /** @internal */
10418
10630
  _browserLastPort = defaultBrowserPort;
10631
+ /** @internal */
10632
+ _options = {};
10419
10633
  _onRestartListeners = [];
10420
10634
  _onClose = [];
10421
10635
  _onSetServer = [];
10422
10636
  _onCancelListeners = [];
10423
10637
  _onUserTestsRerun = [];
10424
10638
  async setServer(options, server, cliOptions) {
10639
+ this._options = options;
10425
10640
  this.unregisterWatcher?.();
10426
10641
  clearTimeout(this._rerunTimer);
10427
10642
  this.restartsCount += 1;
@@ -10467,7 +10682,7 @@ class Vitest {
10467
10682
  };
10468
10683
  server.watcher.on("change", async (file) => {
10469
10684
  file = normalize(file);
10470
- const isConfig = file === server.config.configFile || this.resolvedProjects.some((p) => p.server.config.configFile === file) || file === this._workspaceConfigPath;
10685
+ const isConfig = file === server.config.configFile || this.resolvedProjects.some((p) => p.vite.config.configFile === file) || file === this._workspaceConfigPath;
10471
10686
  if (isConfig) {
10472
10687
  await Promise.all(this._onRestartListeners.map((fn) => fn("config")));
10473
10688
  this.report("onServerRestart", "config");
@@ -10488,11 +10703,11 @@ class Vitest {
10488
10703
  const filters = toArray(resolved.project).map((s) => wildcardPatternToRegExp(s));
10489
10704
  if (filters.length > 0) {
10490
10705
  this.projects = this.projects.filter(
10491
- (p) => filters.some((pattern) => pattern.test(p.getName()))
10706
+ (p) => filters.some((pattern) => pattern.test(p.name))
10492
10707
  );
10493
10708
  }
10494
10709
  if (!this.coreWorkspaceProject) {
10495
- this.coreWorkspaceProject = WorkspaceProject.createBasicProject(this);
10710
+ this.coreWorkspaceProject = TestProject._createBasicProject(this);
10496
10711
  }
10497
10712
  if (this.config.testNamePattern) {
10498
10713
  this.configOverride.testNamePattern = this.config.testNamePattern;
@@ -10500,22 +10715,19 @@ class Vitest {
10500
10715
  await Promise.all(this._onSetServer.map((fn) => fn()));
10501
10716
  }
10502
10717
  provide(key, value) {
10503
- this.getCoreWorkspaceProject().provide(key, value);
10504
- }
10505
- /**
10506
- * @deprecated internal, use `_createCoreProject` instead
10507
- */
10508
- createCoreProject() {
10509
- return this._createCoreProject();
10718
+ this.getRootTestProject().provide(key, value);
10510
10719
  }
10511
10720
  /**
10512
10721
  * @internal
10513
10722
  */
10514
- async _createCoreProject() {
10515
- this.coreWorkspaceProject = await WorkspaceProject.createCoreProject(this);
10723
+ _createRootProject() {
10724
+ this.coreWorkspaceProject = TestProject._createBasicProject(this);
10516
10725
  return this.coreWorkspaceProject;
10517
10726
  }
10518
- getCoreWorkspaceProject() {
10727
+ getRootTestProject() {
10728
+ if (!this.coreWorkspaceProject) {
10729
+ 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.`);
10730
+ }
10519
10731
  return this.coreWorkspaceProject;
10520
10732
  }
10521
10733
  /**
@@ -10524,13 +10736,13 @@ class Vitest {
10524
10736
  getProjectByTaskId(taskId) {
10525
10737
  const task = this.state.idMap.get(taskId);
10526
10738
  const projectName = task.projectName || task?.file?.projectName || "";
10527
- return this.projects.find((p) => p.getName() === projectName) || this.getCoreWorkspaceProject() || this.projects[0];
10739
+ return this.projects.find((p) => p.name === projectName) || this.getRootTestProject() || this.projects[0];
10528
10740
  }
10529
10741
  getProjectByName(name = "") {
10530
- return this.projects.find((p) => p.getName() === name) || this.getCoreWorkspaceProject() || this.projects[0];
10742
+ return this.projects.find((p) => p.name === name) || this.coreWorkspaceProject || this.projects[0];
10531
10743
  }
10532
- async getWorkspaceConfigPath() {
10533
- if (this.config.workspace) {
10744
+ async resolveWorkspaceConfigPath() {
10745
+ if (typeof this.config.workspace === "string") {
10534
10746
  return this.config.workspace;
10535
10747
  }
10536
10748
  const configDir = this.server.config.configFile ? dirname(this.server.config.configFile) : this.config.root;
@@ -10544,10 +10756,18 @@ class Vitest {
10544
10756
  return join(configDir, workspaceConfigName);
10545
10757
  }
10546
10758
  async resolveWorkspace(cliOptions) {
10547
- const workspaceConfigPath = await this.getWorkspaceConfigPath();
10759
+ if (Array.isArray(this.config.workspace)) {
10760
+ return resolveWorkspace(
10761
+ this,
10762
+ cliOptions,
10763
+ void 0,
10764
+ this.config.workspace
10765
+ );
10766
+ }
10767
+ const workspaceConfigPath = await this.resolveWorkspaceConfigPath();
10548
10768
  this._workspaceConfigPath = workspaceConfigPath;
10549
10769
  if (!workspaceConfigPath) {
10550
- return [await this._createCoreProject()];
10770
+ return [this._createRootProject()];
10551
10771
  }
10552
10772
  const workspaceModule = await this.runner.executeFile(workspaceConfigPath);
10553
10773
  if (!workspaceModule.default || !Array.isArray(workspaceModule.default)) {
@@ -10689,21 +10909,21 @@ class Vitest {
10689
10909
  return;
10690
10910
  }
10691
10911
  deps.add(filepath);
10692
- const mod = project.server.moduleGraph.getModuleById(filepath);
10912
+ const mod = project.vite.moduleGraph.getModuleById(filepath);
10693
10913
  const transformed = mod?.ssrTransformResult || await project.vitenode.transformRequest(filepath);
10694
10914
  if (!transformed) {
10695
10915
  return;
10696
10916
  }
10697
10917
  const dependencies = [...transformed.deps || [], ...transformed.dynamicDeps || []];
10698
10918
  await Promise.all(dependencies.map(async (dep) => {
10699
- const path = await project.server.pluginContainer.resolveId(dep, filepath, { ssr: true });
10919
+ const path = await project.vite.pluginContainer.resolveId(dep, filepath, { ssr: true });
10700
10920
  const fsPath = path && !path.external && path.id.split("?")[0];
10701
10921
  if (fsPath && !fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath)) {
10702
10922
  await addImports(project, fsPath);
10703
10923
  }
10704
10924
  }));
10705
10925
  };
10706
- await addImports(spec.project.workspaceProject, spec.moduleId);
10926
+ await addImports(spec.project, spec.moduleId);
10707
10927
  deps.delete(spec.moduleId);
10708
10928
  return deps;
10709
10929
  }
@@ -10759,24 +10979,23 @@ class Vitest {
10759
10979
  const specs = [];
10760
10980
  for (const project of this.projects) {
10761
10981
  if (project.isTestFile(file)) {
10762
- const pool = getFilePoolName(project, file);
10763
- specs.push(project.createSpec(file, pool));
10982
+ specs.push(project.createSpecification(file));
10764
10983
  }
10765
10984
  if (project.isTypecheckFile(file)) {
10766
- specs.push(project.createSpec(file, "typescript"));
10985
+ specs.push(project.createSpecification(file, "typescript"));
10767
10986
  }
10768
10987
  }
10769
10988
  specs.forEach((spec) => this.ensureSpecCached(spec));
10770
10989
  return specs;
10771
10990
  }
10772
10991
  async initializeGlobalSetup(paths) {
10773
- const projects = new Set(paths.map((spec) => spec.project.workspaceProject));
10774
- const coreProject = this.getCoreWorkspaceProject();
10992
+ const projects = new Set(paths.map((spec) => spec.project));
10993
+ const coreProject = this.getRootTestProject();
10775
10994
  if (!projects.has(coreProject)) {
10776
10995
  projects.add(coreProject);
10777
10996
  }
10778
10997
  for (const project of projects) {
10779
- await project.initializeGlobalSetup();
10998
+ await project._initializeGlobalSetup();
10780
10999
  }
10781
11000
  }
10782
11001
  async runFiles(specs, allTestsRun) {
@@ -10788,35 +11007,38 @@ class Vitest {
10788
11007
  this._onCancelListeners = [];
10789
11008
  this.isCancelling = false;
10790
11009
  this.runningPromise = (async () => {
10791
- if (!this.pool) {
10792
- this.pool = createPool(this);
10793
- }
10794
- const invalidates = Array.from(this.invalidates);
10795
- this.invalidates.clear();
10796
- this.snapshot.clear();
10797
- this.state.clearErrors();
10798
- if (!this.isFirstRun && this.config.coverage.cleanOnRerun) {
10799
- await this.coverageProvider?.clean();
10800
- }
10801
- await this.initializeGlobalSetup(specs);
10802
11010
  try {
10803
- await this.pool.runTests(specs, invalidates);
10804
- } catch (err) {
10805
- this.state.catchError(err, "Unhandled Error");
10806
- }
10807
- const files = this.state.getFiles();
10808
- if (hasFailed(files)) {
10809
- process.exitCode = 1;
11011
+ if (!this.pool) {
11012
+ this.pool = createPool(this);
11013
+ }
11014
+ const invalidates = Array.from(this.invalidates);
11015
+ this.invalidates.clear();
11016
+ this.snapshot.clear();
11017
+ this.state.clearErrors();
11018
+ if (!this.isFirstRun && this.config.coverage.cleanOnRerun) {
11019
+ await this.coverageProvider?.clean();
11020
+ }
11021
+ await this.initializeGlobalSetup(specs);
11022
+ try {
11023
+ await this.pool.runTests(specs, invalidates);
11024
+ } catch (err) {
11025
+ this.state.catchError(err, "Unhandled Error");
11026
+ }
11027
+ const files = this.state.getFiles();
11028
+ if (hasFailed(files)) {
11029
+ process.exitCode = 1;
11030
+ }
11031
+ this.cache.results.updateResults(files);
11032
+ await this.cache.results.writeToCache();
11033
+ } finally {
11034
+ const files = Array.from(new Set(specs.map((spec) => spec.moduleId)));
11035
+ const errors = this.state.getUnhandledErrors();
11036
+ const coverage = await this.coverageProvider?.generateCoverage({ allTestsRun });
11037
+ this.checkUnhandledErrors(errors);
11038
+ await this.report("onFinished", this.state.getFiles(files), errors, coverage);
11039
+ await this.reportCoverage(coverage, allTestsRun);
10810
11040
  }
10811
- this.cache.results.updateResults(files);
10812
- await this.cache.results.writeToCache();
10813
- })().finally(async () => {
10814
- const files = Array.from(new Set(specs.map((spec) => spec.moduleId)));
10815
- const errors = this.state.getUnhandledErrors();
10816
- const coverage = await this.coverageProvider?.generateCoverage({ allTestsRun });
10817
- this.checkUnhandledErrors(errors);
10818
- await this.report("onFinished", this.state.getFiles(files), errors, coverage);
10819
- await this.reportCoverage(coverage, allTestsRun);
11041
+ })().finally(() => {
10820
11042
  this.runningPromise = void 0;
10821
11043
  this.isFirstRun = false;
10822
11044
  this.config.changed = false;
@@ -10848,7 +11070,7 @@ class Vitest {
10848
11070
  if (hasFailed(files)) {
10849
11071
  process.exitCode = 1;
10850
11072
  }
10851
- })().finally(async () => {
11073
+ })().finally(() => {
10852
11074
  this.runningPromise = void 0;
10853
11075
  this.config.changed = false;
10854
11076
  this.config.related = void 0;
@@ -10860,9 +11082,12 @@ class Vitest {
10860
11082
  await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason)));
10861
11083
  }
10862
11084
  async initBrowserServers() {
10863
- await Promise.all(this.projects.map((p) => p.initBrowserServer()));
11085
+ await Promise.all(this.projects.map((p) => p._initBrowserServer()));
10864
11086
  }
10865
- async rerunFiles(files = this.state.getFilepaths(), trigger, allTestsRun = true) {
11087
+ async rerunFiles(files = this.state.getFilepaths(), trigger, allTestsRun = true, resetTestNamePattern = false) {
11088
+ if (resetTestNamePattern) {
11089
+ this.configOverride.testNamePattern = void 0;
11090
+ }
10866
11091
  if (this.filenamePattern) {
10867
11092
  const filteredFiles = await this.globTestFiles([this.filenamePattern]);
10868
11093
  files = files.filter((file) => filteredFiles.some((f) => f[1] === file));
@@ -10874,13 +11099,27 @@ class Vitest {
10874
11099
  await this.runFiles(files.flatMap((file) => this.getProjectsByTestFile(file)), allTestsRun);
10875
11100
  await this.report("onWatcherStart", this.state.getFiles(files));
10876
11101
  }
11102
+ isSuite(task) {
11103
+ return Object.hasOwnProperty.call(task, "tasks");
11104
+ }
11105
+ async rerunTask(id) {
11106
+ const task = this.state.idMap.get(id);
11107
+ if (!task) {
11108
+ throw new Error(`Task ${id} was not found`);
11109
+ }
11110
+ await this.changeNamePattern(
11111
+ task.name,
11112
+ [task.file.filepath],
11113
+ this.isSuite(task) ? "rerun suite" : "rerun test"
11114
+ );
11115
+ }
10877
11116
  async changeProjectName(pattern) {
10878
11117
  if (pattern === "") {
10879
11118
  delete this.configOverride.project;
10880
11119
  } else {
10881
11120
  this.configOverride.project = pattern;
10882
11121
  }
10883
- this.projects = this.resolvedProjects.filter((p) => p.getName() === pattern);
11122
+ this.projects = this.resolvedProjects.filter((p) => p.name === pattern);
10884
11123
  const files = (await this.globTestSpecs()).map((spec) => spec.moduleId);
10885
11124
  await this.rerunFiles(files, "change project filter", pattern === "");
10886
11125
  }
@@ -11018,13 +11257,14 @@ class Vitest {
11018
11257
  onAdd = async (id) => {
11019
11258
  id = slash(id);
11020
11259
  this.updateLastChanged(id);
11260
+ const fileContent = readFileSync(id, "utf-8");
11021
11261
  const matchingProjects = [];
11022
- await Promise.all(this.projects.map(async (project) => {
11023
- if (await project.isTargetFile(id)) {
11262
+ this.projects.forEach((project) => {
11263
+ if (project.matchesTestGlob(id, fileContent)) {
11024
11264
  matchingProjects.push(project);
11025
- project.testFilesList?.push(id);
11265
+ project._markTestFile(id);
11026
11266
  }
11027
- }));
11267
+ });
11028
11268
  if (matchingProjects.length > 0) {
11029
11269
  this.changedTests.add(id);
11030
11270
  this.scheduleRerun([id]);
@@ -11128,10 +11368,10 @@ class Vitest {
11128
11368
  if (!teardownProjects.includes(this.coreWorkspaceProject)) {
11129
11369
  teardownProjects.push(this.coreWorkspaceProject);
11130
11370
  }
11131
- for await (const project of teardownProjects.reverse()) {
11132
- await project.teardownGlobalSetup();
11371
+ for (const project of teardownProjects.reverse()) {
11372
+ await project._teardownGlobalSetup();
11133
11373
  }
11134
- const closePromises = this.resolvedProjects.map((w) => w.close().then(() => w.server = void 0));
11374
+ const closePromises = this.resolvedProjects.map((w) => w.close());
11135
11375
  if (!this.resolvedProjects.includes(this.coreWorkspaceProject)) {
11136
11376
  closePromises.push(this.coreWorkspaceProject.close().then(() => this.server = void 0));
11137
11377
  }
@@ -11191,24 +11431,45 @@ class Vitest {
11191
11431
  }
11192
11432
  async globTestSpecs(filters = []) {
11193
11433
  const files = [];
11434
+ const dir = process.cwd();
11435
+ const parsedFilters = filters.map((f) => parseFilter(f));
11436
+ if (!this.config.includeTaskLocation && parsedFilters.some((f) => f.lineNumber !== void 0)) {
11437
+ throw new IncludeTaskLocationDisabledError();
11438
+ }
11439
+ const testLocations = groupFilters(parsedFilters.map(
11440
+ (f) => ({ ...f, filename: slash(resolve$1(dir, f.filename)) })
11441
+ ));
11442
+ const testLocHasMatch = {};
11194
11443
  await Promise.all(this.projects.map(async (project) => {
11195
- const { testFiles, typecheckTestFiles } = await project.globTestFiles(filters);
11444
+ const { testFiles, typecheckTestFiles } = await project.globTestFiles(
11445
+ parsedFilters.map((f) => f.filename)
11446
+ );
11196
11447
  testFiles.forEach((file) => {
11197
- const pool = getFilePoolName(project, file);
11198
- const spec = project.createSpec(file, pool);
11448
+ const loc = testLocations[file];
11449
+ testLocHasMatch[file] = true;
11450
+ const spec = project.createSpecification(file, void 0, loc);
11199
11451
  this.ensureSpecCached(spec);
11200
11452
  files.push(spec);
11201
11453
  });
11202
11454
  typecheckTestFiles.forEach((file) => {
11203
- const spec = project.createSpec(file, "typescript");
11455
+ const loc = testLocations[file];
11456
+ testLocHasMatch[file] = true;
11457
+ const spec = project.createSpecification(file, "typescript", loc);
11204
11458
  this.ensureSpecCached(spec);
11205
11459
  files.push(spec);
11206
11460
  });
11207
11461
  }));
11462
+ Object.entries(testLocations).forEach(([filepath, loc]) => {
11463
+ if (loc.length !== 0 && !testLocHasMatch[filepath]) {
11464
+ throw new LocationFilterFileNotFoundError(
11465
+ relative(dir, filepath)
11466
+ );
11467
+ }
11468
+ });
11208
11469
  return files;
11209
11470
  }
11210
11471
  /**
11211
- * @deprecated use globTestSpecs instead
11472
+ * @deprecated use `globTestSpecs` instead
11212
11473
  */
11213
11474
  async globTestFiles(filters = []) {
11214
11475
  return this.globTestSpecs(filters);
@@ -11329,7 +11590,9 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
11329
11590
  forks: {
11330
11591
  isolate: options.poolOptions?.forks?.isolate ?? options.isolate ?? testConfig.poolOptions?.forks?.isolate ?? viteConfig.test?.isolate
11331
11592
  }
11332
- }
11593
+ },
11594
+ root: testConfig.root ?? viteConfig.test?.root,
11595
+ deps: testConfig.deps ?? viteConfig.test?.deps
11333
11596
  }
11334
11597
  };
11335
11598
  config.customLogger = createViteLogger(
@@ -11849,6 +12112,10 @@ async function startVitest(mode, cliFilters = [], options = {}, viteOverrides, v
11849
12112
  ctx.logger.error(e.message);
11850
12113
  return ctx;
11851
12114
  }
12115
+ if (e instanceof IncludeTaskLocationDisabledError || e instanceof RangeLocationFilterProvidedError || e instanceof LocationFilterFileNotFoundError) {
12116
+ ctx.logger.printError(e, { verbose: false });
12117
+ return ctx;
12118
+ }
11852
12119
  process.exitCode = 1;
11853
12120
  ctx.logger.printError(e, { fullStack: true, type: "Unhandled Error" });
11854
12121
  ctx.logger.error("\n\n");