vitest 1.2.0 → 1.2.2

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 (43) hide show
  1. package/dist/browser.d.ts +1 -1
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{api-setup.MAoRkVWJ.js → api-setup.srzH0bDf.js} +4 -4
  4. package/dist/chunks/{integrations-globals.VbxbZ7hn.js → integrations-globals.J_6tnlri.js} +3 -3
  5. package/dist/chunks/{runtime-console.hf2msWA9.js → runtime-console.Iloo9fIt.js} +2 -2
  6. package/dist/chunks/{runtime-runBaseTests.LWFmrzDk.js → runtime-runBaseTests.QReNMrJA.js} +6 -6
  7. package/dist/cli.js +4 -4
  8. package/dist/config.d.ts +1 -74
  9. package/dist/coverage.d.ts +1 -1
  10. package/dist/environments.d.ts +1 -1
  11. package/dist/execute.d.ts +3 -3
  12. package/dist/execute.js +2 -2
  13. package/dist/index.d.ts +3 -4
  14. package/dist/index.js +4 -4
  15. package/dist/node.d.ts +2 -2
  16. package/dist/node.js +4 -4
  17. package/dist/{reporters-trlZlObr.d.ts → reporters-1evA5lom.d.ts} +79 -4
  18. package/dist/reporters.d.ts +1 -1
  19. package/dist/reporters.js +3 -3
  20. package/dist/runners.d.ts +1 -1
  21. package/dist/runners.js +2 -2
  22. package/dist/{suite-6Pt_ep5V.d.ts → suite-ghspeorC.d.ts} +1 -1
  23. package/dist/suite.d.ts +3 -3
  24. package/dist/suite.js +1 -1
  25. package/dist/vendor/{base.dzu0Y6Hj.js → base.QYERqzkH.js} +1 -1
  26. package/dist/vendor/{base.8wUUWReP.js → base.Rmxiv35Y.js} +2 -2
  27. package/dist/vendor/{execute.3_hyGknJ.js → execute.TxmaEFIQ.js} +4 -15
  28. package/dist/vendor/{index.3iX2R_Z5.js → index.LgG0iblq.js} +1 -1
  29. package/dist/vendor/{index.D-jOsMas.js → index.RDKo8czB.js} +1 -1
  30. package/dist/vendor/{node.xyYo9ZvH.js → node.Zme77R4t.js} +120 -72
  31. package/dist/vendor/{reporters.2PaQ2peU.js → reporters.cA9x-5v-.js} +2 -2
  32. package/dist/vendor/{setup-common.j9IXYrbN.js → setup-common.C2iBd0K0.js} +1 -1
  33. package/dist/vendor/{vi.smj1Ggd4.js → vi.PPwhENHF.js} +15 -4
  34. package/dist/vendor/{vm.vFKXXdo0.js → vm.jVxKtN5R.js} +16 -6
  35. package/dist/worker.js +1 -1
  36. package/dist/workers/forks.js +3 -3
  37. package/dist/workers/runVmTests.js +5 -5
  38. package/dist/workers/threads.js +3 -3
  39. package/dist/workers/vmForks.js +4 -4
  40. package/dist/workers/vmThreads.js +4 -4
  41. package/dist/workers.d.ts +1 -1
  42. package/dist/workers.js +5 -5
  43. package/package.json +10 -9
@@ -2,12 +2,12 @@ import vm from 'node:vm';
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import { ViteNodeRunner, DEFAULT_REQUEST_STUBS } from 'vite-node/client';
4
4
  import { isNodeBuiltin, isInternalRequest, toFilePath, isPrimitive } from 'vite-node/utils';
5
- import { resolve, isAbsolute, dirname, join, basename, extname, relative, normalize } from 'pathe';
5
+ import { resolve, isAbsolute, dirname, join, basename, extname, normalize, relative } from 'pathe';
6
6
  import { processError } from '@vitest/utils/error';
7
7
  import { distDir } from '../path.js';
8
8
  import { existsSync, readdirSync } from 'node:fs';
9
9
  import { highlight, getType } from '@vitest/utils';
10
- import { e as getAllMockableProperties } from './base.dzu0Y6Hj.js';
10
+ import { e as getAllMockableProperties } from './base.QYERqzkH.js';
11
11
 
12
12
  const spyModulePath = resolve(distDir, "spy.js");
13
13
  class RefTracker {
@@ -118,7 +118,7 @@ class VitestMocker {
118
118
  if (mock.type === "unmock")
119
119
  this.unmockPath(fsPath);
120
120
  if (mock.type === "mock")
121
- this.mockPath(mock.id, fsPath, external, mock.factory, mock.throwIfCached);
121
+ this.mockPath(mock.id, fsPath, external, mock.factory);
122
122
  }));
123
123
  VitestMocker.pendingIds = [];
124
124
  }
@@ -295,19 +295,8 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
295
295
  delete mock[id];
296
296
  this.deleteCachedItem(id);
297
297
  }
298
- mockPath(originalId, path, external, factory, throwIfExists) {
299
- var _a, _b, _c, _d;
298
+ mockPath(originalId, path, external, factory) {
300
299
  const id = this.normalizePath(path);
301
- const { config } = this.executor.state;
302
- const isIsolatedThreads = config.pool === "threads" && (((_b = (_a = config.poolOptions) == null ? void 0 : _a.threads) == null ? void 0 : _b.isolate) ?? true);
303
- const isIsolatedForks = config.pool === "forks" && (((_d = (_c = config.poolOptions) == null ? void 0 : _c.forks) == null ? void 0 : _d.isolate) ?? true);
304
- if (throwIfExists && (isIsolatedThreads || isIsolatedForks || config.pool === "vmThreads")) {
305
- const cached = this.moduleCache.has(id) && this.moduleCache.getByModuleId(id);
306
- if (cached && cached.importers.size)
307
- throw new Error(`[vitest] Cannot mock "${originalId}" because it is already loaded by "${[...cached.importers.values()].map((i) => relative(this.root, i)).join('", "')}".
308
-
309
- Please, remove the import if you want static imports to be mocked, or clear module cache by calling "vi.resetModules()" before mocking if you are going to import the file again. See: https://vitest.dev/guide/common-errors.html#cannot-mock-mocked-file-js-because-it-is-already-loaded`);
310
- }
311
300
  const suitefile = this.getSuiteFilepath();
312
301
  const mocks = this.mockMap.get(suitefile) || {};
313
302
  const resolves = this.resolveCache.get(suitefile) || {};
@@ -1,7 +1,7 @@
1
1
  import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, suite, test } from '@vitest/runner';
2
2
  import { b as bench } from './benchmark.IlKmJkUU.js';
3
3
  import { i as isFirstRun, a as runOnce } from './run-once.Olz_Zkd8.js';
4
- import { c as createExpect, a as globalExpect, v as vi, b as vitest } from './vi.smj1Ggd4.js';
4
+ import { c as createExpect, a as globalExpect, v as vi, b as vitest } from './vi.PPwhENHF.js';
5
5
  import { g as getWorkerState } from './global.CkGT_TMy.js';
6
6
  import * as chai from 'chai';
7
7
  import { assert, should } from 'chai';
@@ -5,7 +5,7 @@ import { distDir } from '../path.js';
5
5
  import { g as getWorkerState } from './global.CkGT_TMy.js';
6
6
  import { r as rpc } from './rpc.w4v8oCkK.js';
7
7
  import { t as takeCoverageInsideWorker } from './coverage.E7sG1b3r.js';
8
- import { l as loadDiffConfig } from './setup-common.j9IXYrbN.js';
8
+ import { l as loadDiffConfig } from './setup-common.C2iBd0K0.js';
9
9
 
10
10
  function setupChaiConfig(config) {
11
11
  Object.assign(chai.config, config);
@@ -25,9 +25,9 @@ import nodeos__default from 'node:os';
25
25
  import EventEmitter from 'node:events';
26
26
  import Tinypool$1, { Tinypool } from 'tinypool';
27
27
  import { c as createBirpc } from './index.cAUulNDf.js';
28
- import { g as groupBy, A as AggregateErrorPonyfill, b as slash$1, t as toArray, a as isPrimitive, d as deepMerge, n as noop$1, c as stdout } from './base.dzu0Y6Hj.js';
28
+ import { g as groupBy, A as AggregateErrorPonyfill, b as slash$1, t as toArray, a as isPrimitive, d as deepMerge, n as noop$1, c as stdout } from './base.QYERqzkH.js';
29
29
  import { MessageChannel } from 'node:worker_threads';
30
- import { createDefer, shuffle, inspect, positionToOffset, lineSplitRE, highlight, toArray as toArray$1, notNullish } from '@vitest/utils';
30
+ import { createDefer, shuffle, highlight, inspect, positionToOffset, lineSplitRE, toArray as toArray$1, notNullish } from '@vitest/utils';
31
31
  import { writeFile, rm } from 'node:fs/promises';
32
32
  import { performance } from 'node:perf_hooks';
33
33
  import { execa } from 'execa';
@@ -35,7 +35,7 @@ import { TraceMap, generatedPositionFor, parseErrorStacktrace } from '@vitest/ut
35
35
  import ge from 'module';
36
36
  import { ancestor, findNodeAround } from 'acorn-walk';
37
37
  import { generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks, hasFailed, getTests } from '@vitest/runner/utils';
38
- import { R as ReportersMap, B as BenchmarkReportsMap, s as stripAnsi, a as ansiStyles, b as sliceAnsi, d as divider, F as F_POINTER, c as cliTruncate } from './reporters.2PaQ2peU.js';
38
+ import { R as ReportersMap, B as BenchmarkReportsMap, s as stripAnsi, a as ansiStyles, b as sliceAnsi, d as divider, F as F_POINTER, c as cliTruncate } from './reporters.cA9x-5v-.js';
39
39
  import { resolveModule, isPackageExists } from 'local-pkg';
40
40
  import { isCI, provider as provider$1 } from 'std-env';
41
41
  import crypto, { createHash } from 'node:crypto';
@@ -64,7 +64,7 @@ function _mergeNamespaces(n, m) {
64
64
  return Object.freeze(n);
65
65
  }
66
66
 
67
- var version$1 = "1.2.0";
67
+ var version$1 = "1.2.2";
68
68
 
69
69
  /*
70
70
  How it works:
@@ -3417,7 +3417,8 @@ function createThreadsPool(ctx, { execArgv, env }) {
3417
3417
  await pool.run(data, { transferList: [workerPort], name });
3418
3418
  } catch (error) {
3419
3419
  if (error instanceof Error && /Failed to terminate worker/.test(error.message))
3420
- ctx.state.addProcessTimeoutCause(`Failed to terminate worker while running ${files.join(", ")}.`);
3420
+ ctx.state.addProcessTimeoutCause(`Failed to terminate worker while running ${files.join(", ")}.
3421
+ See https://vitest.dev/guide/common-errors.html#failed-to-terminate-worker for troubleshooting.`);
3421
3422
  else if (ctx.isCancelling && error instanceof Error && /The task has been cancelled/.test(error.message))
3422
3423
  ctx.state.cancelFiles(files, ctx.config.root, project.config.name);
3423
3424
  else
@@ -3523,7 +3524,8 @@ function createBrowserPool(ctx) {
3523
3524
  });
3524
3525
  const provider = project.browserProvider;
3525
3526
  providers.add(provider);
3526
- const origin = `http://${((_a = ctx.config.browser.api) == null ? void 0 : _a.host) || "localhost"}:${project.browser.config.server.port}`;
3527
+ const resolvedUrls = (_a = project.browser) == null ? void 0 : _a.resolvedUrls;
3528
+ const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]);
3527
3529
  const paths = files.map((file) => relative(project.config.root, file));
3528
3530
  if (project.config.browser.isolate) {
3529
3531
  for (const path of paths) {
@@ -3704,7 +3706,8 @@ function createVmThreadsPool(ctx, { execArgv, env }) {
3704
3706
  await pool.run(data, { transferList: [workerPort], name });
3705
3707
  } catch (error) {
3706
3708
  if (error instanceof Error && /Failed to terminate worker/.test(error.message))
3707
- ctx.state.addProcessTimeoutCause(`Failed to terminate worker while running ${files.join(", ")}.`);
3709
+ ctx.state.addProcessTimeoutCause(`Failed to terminate worker while running ${files.join(", ")}.
3710
+ See https://vitest.dev/guide/common-errors.html#failed-to-terminate-worker for troubleshooting.`);
3708
3711
  else if (ctx.isCancelling && error instanceof Error && /The task has been cancelled/.test(error.message))
3709
3712
  ctx.state.cancelFiles(files, ctx.config.root, project.config.name);
3710
3713
  else
@@ -4250,7 +4253,7 @@ function createTypecheckPool(ctx) {
4250
4253
  await ctx.report("onTaskUpdate", checker.getTestPacks());
4251
4254
  if (!project.config.typecheck.ignoreSourceErrors)
4252
4255
  sourceErrors.forEach((error) => ctx.state.catchError(error, "Unhandled Source Error"));
4253
- const processError = !hasFailed(files) && checker.getExitCode();
4256
+ const processError = !hasFailed(files) && !sourceErrors.length && checker.getExitCode();
4254
4257
  if (processError) {
4255
4258
  const error = new Error(checker.getOutput());
4256
4259
  error.stack = "";
@@ -4475,7 +4478,6 @@ function getMemoryLimit(config) {
4475
4478
 
4476
4479
  const builtinPools = ["forks", "threads", "browser", "vmThreads", "vmForks", "typescript"];
4477
4480
  function createPool(ctx) {
4478
- var _a;
4479
4481
  const pools = {
4480
4482
  forks: null,
4481
4483
  threads: null,
@@ -4504,7 +4506,14 @@ function createPool(ctx) {
4504
4506
  }
4505
4507
  return getDefaultPoolName(project, file);
4506
4508
  }
4507
- const conditions = ((_a = ctx.server.config.resolve.conditions) == null ? void 0 : _a.flatMap((c) => ["--conditions", c])) || [];
4509
+ const potentialConditions = /* @__PURE__ */ new Set(["production", "development", ...ctx.server.config.resolve.conditions]);
4510
+ const conditions = [...potentialConditions].filter((condition) => {
4511
+ if (condition === "production")
4512
+ return ctx.server.config.isProduction;
4513
+ if (condition === "development")
4514
+ return !ctx.server.config.isProduction;
4515
+ return true;
4516
+ }).flatMap((c) => ["--conditions", c]);
4508
4517
  const execArgv = process.execArgv.filter(
4509
4518
  (execArg) => execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir")
4510
4519
  );
@@ -4567,7 +4576,7 @@ function createPool(ctx) {
4567
4576
  return sequencer.sort(specs);
4568
4577
  }
4569
4578
  await Promise.all(Object.entries(filesByPool).map(async (entry) => {
4570
- var _a2;
4579
+ var _a;
4571
4580
  const [pool, files2] = entry;
4572
4581
  if (!files2.length)
4573
4582
  return null;
@@ -4578,7 +4587,7 @@ function createPool(ctx) {
4578
4587
  return pools[pool].runTests(specs, invalidate);
4579
4588
  }
4580
4589
  const poolHandler = await resolveCustomPool(pool);
4581
- pools[_a2 = poolHandler.name] ?? (pools[_a2] = poolHandler);
4590
+ pools[_a = poolHandler.name] ?? (pools[_a] = poolHandler);
4582
4591
  return poolHandler.runTests(specs, invalidate);
4583
4592
  }));
4584
4593
  }
@@ -4587,8 +4596,8 @@ function createPool(ctx) {
4587
4596
  runTests,
4588
4597
  async close() {
4589
4598
  await Promise.all(Object.values(pools).map((p) => {
4590
- var _a2;
4591
- return (_a2 = p == null ? void 0 : p.close) == null ? void 0 : _a2.call(p);
4599
+ var _a;
4600
+ return (_a = p == null ? void 0 : p.close) == null ? void 0 : _a.call(p);
4592
4601
  }));
4593
4602
  }
4594
4603
  };
@@ -6573,7 +6582,23 @@ createLogUpdate(process$2.stdout);
6573
6582
 
6574
6583
  createLogUpdate(process$2.stderr);
6575
6584
 
6576
- var version = "1.2.0";
6585
+ var version = "1.2.2";
6586
+
6587
+ const HIGHLIGHT_SUPPORTED_EXTS = new Set(["js", "ts"].flatMap((lang) => [
6588
+ `.${lang}`,
6589
+ `.m${lang}`,
6590
+ `.c${lang}`,
6591
+ `.${lang}x`,
6592
+ `.m${lang}x`,
6593
+ `.c${lang}x`
6594
+ ]));
6595
+ function highlightCode(id, source, colors) {
6596
+ const ext = extname(id);
6597
+ if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext))
6598
+ return source;
6599
+ const isJsx = ext.endsWith("x");
6600
+ return highlight(source, { jsx: isJsx, colors: colors || c });
6601
+ }
6577
6602
 
6578
6603
  async function printError(error, project, options) {
6579
6604
  const { showCodeFrame = true, fullStack = false, type } = options;
@@ -6807,14 +6832,6 @@ const ERASE_DOWN = `${ESC$1}J`;
6807
6832
  const ERASE_SCROLLBACK = `${ESC$1}3J`;
6808
6833
  const CURSOR_TO_START = `${ESC$1}1;1H`;
6809
6834
  const CLEAR_SCREEN = "\x1Bc";
6810
- const HIGHLIGHT_SUPPORTED_EXTS = new Set(["js", "ts"].flatMap((lang) => [
6811
- `.${lang}`,
6812
- `.m${lang}`,
6813
- `.c${lang}`,
6814
- `.${lang}x`,
6815
- `.m${lang}x`,
6816
- `.c${lang}x`
6817
- ]));
6818
6835
  class Logger {
6819
6836
  constructor(ctx, console = globalThis.console) {
6820
6837
  this.ctx = ctx;
@@ -6880,11 +6897,7 @@ class Logger {
6880
6897
  highlight(filename, source) {
6881
6898
  if (this._highlights.has(filename))
6882
6899
  return this._highlights.get(filename);
6883
- const ext = extname(filename);
6884
- if (!HIGHLIGHT_SUPPORTED_EXTS.has(ext))
6885
- return source;
6886
- const isJsx = ext.endsWith("x");
6887
- const code = highlight(source, { jsx: isJsx, colors: c });
6900
+ const code = highlightCode(filename, source);
6888
6901
  this._highlights.set(filename, code);
6889
6902
  return code;
6890
6903
  }
@@ -6935,12 +6948,13 @@ No ${config.mode} files found, exiting with code 1`));
6935
6948
  if (this.ctx.config.sequence.sequencer === RandomSequencer)
6936
6949
  this.log(c.gray(` Running tests with seed "${this.ctx.config.sequence.seed}"`));
6937
6950
  this.ctx.projects.forEach((project) => {
6938
- var _a2;
6939
6951
  if (!project.browser)
6940
6952
  return;
6941
6953
  const name = project.getName();
6942
6954
  const output = project.isCore() ? "" : ` [${name}]`;
6943
- this.log(c.dim(c.green(` ${output} Browser runner started at http://${((_a2 = project.config.browser.api) == null ? void 0 : _a2.host) || "localhost"}:${c.bold(`${project.browser.config.server.port}`)}`)));
6955
+ const resolvedUrls = project.browser.resolvedUrls;
6956
+ const origin = (resolvedUrls == null ? void 0 : resolvedUrls.local[0]) ?? (resolvedUrls == null ? void 0 : resolvedUrls.network[0]);
6957
+ this.log(c.dim(c.green(` ${output} Browser runner started at ${new URL("/", origin)}`)));
6944
6958
  });
6945
6959
  if (this.ctx.config.ui)
6946
6960
  this.log(c.dim(c.green(` UI started at http://${((_a = this.ctx.config.api) == null ? void 0 : _a.host) || "localhost"}:${c.bold(`${this.ctx.server.config.server.port}`)}${this.ctx.config.uiBase}`)));
@@ -7023,12 +7037,11 @@ function getBetterEnd(code, node) {
7023
7037
  end += 1;
7024
7038
  return end;
7025
7039
  }
7026
- const regexpHoistable = /^[ \t]*\b(vi|vitest)\s*\.\s*(mock|unmock|hoisted)\(/m;
7027
- const regexpAssignedHoisted = /=[ \t]*(\bawait|)[ \t]*\b(vi|vitest)\s*\.\s*hoisted\(/;
7040
+ const regexpHoistable = /\b(vi|vitest)\s*\.\s*(mock|unmock|hoisted)\(/;
7028
7041
  const hashbangRE = /^#!.*\n/;
7029
- function hoistMocks(code, id, parse) {
7042
+ function hoistMocks(code, id, parse, colors) {
7030
7043
  var _a;
7031
- const needHoisting = regexpHoistable.test(code) || regexpAssignedHoisted.test(code);
7044
+ const needHoisting = regexpHoistable.test(code);
7032
7045
  if (!needHoisting)
7033
7046
  return;
7034
7047
  const s = new MagicString(code);
@@ -7092,6 +7105,35 @@ ${err.message}`);
7092
7105
  }
7093
7106
  const declaredConst = /* @__PURE__ */ new Set();
7094
7107
  const hoistedNodes = [];
7108
+ function createSyntaxError(node, message) {
7109
+ const _error = new SyntaxError(message);
7110
+ Error.captureStackTrace(_error, createSyntaxError);
7111
+ return {
7112
+ name: "SyntaxError",
7113
+ message: _error.message,
7114
+ stack: _error.stack,
7115
+ frame: generateCodeFrame(highlightCode(id, code, colors), 4, node.start + 1)
7116
+ };
7117
+ }
7118
+ function assertNotDefaultExport(node, error) {
7119
+ var _a2;
7120
+ const defaultExport = (_a2 = findNodeAround(ast, node.start, "ExportDefaultDeclaration")) == null ? void 0 : _a2.node;
7121
+ if ((defaultExport == null ? void 0 : defaultExport.declaration) === node || (defaultExport == null ? void 0 : defaultExport.declaration.type) === "AwaitExpression" && defaultExport.declaration.argument === node)
7122
+ throw createSyntaxError(defaultExport, error);
7123
+ }
7124
+ function assertNotNamedExport(node, error) {
7125
+ var _a2;
7126
+ const nodeExported = (_a2 = findNodeAround(ast, node.start, "ExportNamedDeclaration")) == null ? void 0 : _a2.node;
7127
+ if ((nodeExported == null ? void 0 : nodeExported.declaration) === node)
7128
+ throw createSyntaxError(nodeExported, error);
7129
+ }
7130
+ function getVariableDeclaration(node) {
7131
+ var _a2, _b;
7132
+ const declarationNode = (_a2 = findNodeAround(ast, node.start, "VariableDeclaration")) == null ? void 0 : _a2.node;
7133
+ const init = (_b = declarationNode == null ? void 0 : declarationNode.declarations[0]) == null ? void 0 : _b.init;
7134
+ if (init && (init === node || init.type === "AwaitExpression" && init.argument === node))
7135
+ return declarationNode;
7136
+ }
7095
7137
  esmWalker(ast, {
7096
7138
  onIdentifier(id2, info, parentStack) {
7097
7139
  const binding = idToImportMap.get(id2.name);
@@ -7114,22 +7156,25 @@ ${err.message}`);
7114
7156
  }
7115
7157
  },
7116
7158
  onCallExpression(node) {
7117
- var _a2, _b, _c;
7159
+ var _a2;
7118
7160
  if (node.callee.type === "MemberExpression" && isIdentifier(node.callee.object) && (node.callee.object.name === "vi" || node.callee.object.name === "vitest") && isIdentifier(node.callee.property)) {
7119
7161
  const methodName = node.callee.property.name;
7120
- if (methodName === "mock" || methodName === "unmock")
7162
+ if (methodName === "mock" || methodName === "unmock") {
7163
+ const method = `${node.callee.object.name}.${methodName}`;
7164
+ assertNotDefaultExport(node, `Cannot export the result of "${method}". Remove export declaration because "${method}" doesn't return anything.`);
7165
+ const declarationNode = getVariableDeclaration(node);
7166
+ if (declarationNode)
7167
+ assertNotNamedExport(declarationNode, `Cannot export the result of "${method}". Remove export declaration because "${method}" doesn't return anything.`);
7121
7168
  hoistedNodes.push(node);
7169
+ }
7122
7170
  if (methodName === "hoisted") {
7123
- const declarationNode = (_a2 = findNodeAround(ast, node.start, "VariableDeclaration")) == null ? void 0 : _a2.node;
7124
- const init = (_b = declarationNode == null ? void 0 : declarationNode.declarations[0]) == null ? void 0 : _b.init;
7125
- const isViHoisted = (node2) => {
7126
- return node2.callee.type === "MemberExpression" && isIdentifier(node2.callee.object) && (node2.callee.object.name === "vi" || node2.callee.object.name === "vitest") && isIdentifier(node2.callee.property) && node2.callee.property.name === "hoisted";
7127
- };
7128
- const canMoveDeclaration = init && init.type === "CallExpression" && isViHoisted(init) || init && init.type === "AwaitExpression" && init.argument.type === "CallExpression" && isViHoisted(init.argument);
7129
- if (canMoveDeclaration) {
7171
+ assertNotDefaultExport(node, "Cannot export hoisted variable. You can control hoisting behavior by placing the import from this file first.");
7172
+ const declarationNode = getVariableDeclaration(node);
7173
+ if (declarationNode) {
7174
+ assertNotNamedExport(declarationNode, "Cannot export hoisted variable. You can control hoisting behavior by placing the import from this file first.");
7130
7175
  hoistedNodes.push(declarationNode);
7131
7176
  } else {
7132
- const awaitedExpression = (_c = findNodeAround(ast, node.start, "AwaitExpression")) == null ? void 0 : _c.node;
7177
+ const awaitedExpression = (_a2 = findNodeAround(ast, node.start, "AwaitExpression")) == null ? void 0 : _a2.node;
7133
7178
  hoistedNodes.push((awaitedExpression == null ? void 0 : awaitedExpression.argument) === node ? awaitedExpression : node);
7134
7179
  }
7135
7180
  }
@@ -7161,14 +7206,10 @@ ${err.message}`);
7161
7206
  function createError(outsideNode, insideNode) {
7162
7207
  const outsideCall = getNodeCall(outsideNode);
7163
7208
  const insideCall = getNodeCall(insideNode);
7164
- const _error = new SyntaxError(`Cannot call ${getNodeName(insideCall)} inside ${getNodeName(outsideCall)}: both methods are hoisted to the top of the file and not actually called inside each other.`);
7165
- const error = {
7166
- name: "SyntaxError",
7167
- message: _error.message,
7168
- stack: _error.stack,
7169
- frame: generateCodeFrame(highlight(code), 4, insideCall.start + 1)
7170
- };
7171
- throw error;
7209
+ throw createSyntaxError(
7210
+ insideCall,
7211
+ `Cannot call ${getNodeName(insideCall)} inside ${getNodeName(outsideCall)}: both methods are hoisted to the top of the file and not actually called inside each other.`
7212
+ );
7172
7213
  }
7173
7214
  for (let i = 0; i < hoistedNodes.length; i++) {
7174
7215
  const node = hoistedNodes[i];
@@ -7299,10 +7340,13 @@ function resolveFsAllow(projectRoot, rootConfigFile) {
7299
7340
  }
7300
7341
 
7301
7342
  async function createBrowserServer(project, configFile) {
7343
+ var _a;
7302
7344
  const root = project.config.root;
7303
7345
  await project.ctx.packageInstaller.ensureInstalled("@vitest/browser", root);
7304
7346
  const configPath = typeof configFile === "string" ? configFile : false;
7305
7347
  const server = await createServer({
7348
+ ...project.options,
7349
+ // spread project config inlined in root workspace config
7306
7350
  logLevel: "error",
7307
7351
  mode: project.config.mode,
7308
7352
  configFile: configPath,
@@ -7314,14 +7358,15 @@ async function createBrowserServer(project, configFile) {
7314
7358
  }
7315
7359
  },
7316
7360
  plugins: [
7361
+ ...((_a = project.options) == null ? void 0 : _a.plugins) || [],
7317
7362
  (await import('@vitest/browser')).default(project, "/"),
7318
7363
  CoverageTransform(project.ctx),
7319
7364
  {
7320
7365
  enforce: "post",
7321
7366
  name: "vitest:browser:config",
7322
7367
  async config(config) {
7323
- var _a, _b, _c;
7324
- const server2 = resolveApiServerConfig(((_a = config.test) == null ? void 0 : _a.browser) || {}) || {
7368
+ var _a2, _b, _c;
7369
+ const server2 = resolveApiServerConfig(((_a2 = config.test) == null ? void 0 : _a2.browser) || {}) || {
7325
7370
  port: defaultBrowserPort
7326
7371
  };
7327
7372
  server2.middlewareMode = false;
@@ -7351,7 +7396,7 @@ async function createBrowserServer(project, configFile) {
7351
7396
  ]
7352
7397
  });
7353
7398
  await server.listen();
7354
- (await import('../chunks/api-setup.MAoRkVWJ.js')).setup(project, server);
7399
+ (await import('../chunks/api-setup.srzH0bDf.js')).setup(project, server);
7355
7400
  return server;
7356
7401
  }
7357
7402
 
@@ -7680,7 +7725,7 @@ async function loadGlobalSetupFile(file, runner) {
7680
7725
 
7681
7726
  async function initializeProject(workspacePath, ctx, options) {
7682
7727
  var _a;
7683
- const project = new WorkspaceProject(workspacePath, ctx);
7728
+ const project = new WorkspaceProject(workspacePath, ctx, options);
7684
7729
  const configFile = options.extends ? resolve(dirname(options.workspaceConfigPath), options.extends) : typeof workspacePath === "number" || workspacePath.endsWith("/") ? false : workspacePath;
7685
7730
  const root = options.root || (typeof workspacePath === "number" ? void 0 : workspacePath.endsWith("/") ? workspacePath : dirname(workspacePath));
7686
7731
  const config = {
@@ -7699,9 +7744,10 @@ async function initializeProject(workspacePath, ctx, options) {
7699
7744
  return project;
7700
7745
  }
7701
7746
  class WorkspaceProject {
7702
- constructor(path, ctx) {
7747
+ constructor(path, ctx, options) {
7703
7748
  this.path = path;
7704
7749
  this.ctx = ctx;
7750
+ this.options = options;
7705
7751
  }
7706
7752
  configOverride;
7707
7753
  config;
@@ -8294,9 +8340,8 @@ class Vitest {
8294
8340
  this.config.related = void 0;
8295
8341
  if (files.length) {
8296
8342
  await this.cache.stats.populateStats(this.config.root, files);
8297
- await this.runFiles(files);
8343
+ await this.runFiles(files, true);
8298
8344
  }
8299
- await this.reportCoverage(true);
8300
8345
  if (this.config.watch)
8301
8346
  await this.report("onWatcherStart");
8302
8347
  }
@@ -8304,6 +8349,7 @@ class Vitest {
8304
8349
  const addImports = async ([project, filepath2]) => {
8305
8350
  if (deps.has(filepath2))
8306
8351
  return;
8352
+ deps.add(filepath2);
8307
8353
  const mod = project.server.moduleGraph.getModuleById(filepath2);
8308
8354
  const transformed = (mod == null ? void 0 : mod.ssrTransformResult) || await project.vitenode.transformRequest(filepath2);
8309
8355
  if (!transformed)
@@ -8312,13 +8358,12 @@ class Vitest {
8312
8358
  await Promise.all(dependencies.map(async (dep) => {
8313
8359
  const path = await project.server.pluginContainer.resolveId(dep, filepath2, { ssr: true });
8314
8360
  const fsPath = path && !path.external && path.id.split("?")[0];
8315
- if (fsPath && !fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath)) {
8316
- deps.add(fsPath);
8361
+ if (fsPath && !fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath))
8317
8362
  await addImports([project, fsPath]);
8318
- }
8319
8363
  }));
8320
8364
  };
8321
8365
  await addImports(filepath);
8366
+ deps.delete(filepath[1]);
8322
8367
  return deps;
8323
8368
  }
8324
8369
  async filterTestsBySource(specs) {
@@ -8369,7 +8414,7 @@ class Vitest {
8369
8414
  for await (const project of projects)
8370
8415
  await project.initializeGlobalSetup();
8371
8416
  }
8372
- async runFiles(paths) {
8417
+ async runFiles(paths, allTestsRun) {
8373
8418
  const filepaths = paths.map(([, file]) => file);
8374
8419
  this.state.collectPaths(filepaths);
8375
8420
  await this.report("onPathsCollected", filepaths);
@@ -8377,12 +8422,15 @@ class Vitest {
8377
8422
  this._onCancelListeners = [];
8378
8423
  this.isCancelling = false;
8379
8424
  this.runningPromise = (async () => {
8425
+ var _a;
8380
8426
  if (!this.pool)
8381
8427
  this.pool = createPool(this);
8382
8428
  const invalidates = Array.from(this.invalidates);
8383
8429
  this.invalidates.clear();
8384
8430
  this.snapshot.clear();
8385
8431
  this.state.clearErrors();
8432
+ if (!this.isFirstRun && this.config.coverage.cleanOnRerun)
8433
+ await ((_a = this.coverageProvider) == null ? void 0 : _a.clean());
8386
8434
  await this.initializeGlobalSetup(paths);
8387
8435
  try {
8388
8436
  await this.pool.runTests(paths, invalidates);
@@ -8397,7 +8445,9 @@ class Vitest {
8397
8445
  })().finally(async () => {
8398
8446
  const specs = Array.from(new Set(paths.map(([, p]) => p)));
8399
8447
  await this.report("onFinished", this.state.getFiles(specs), this.state.getUnhandledErrors());
8448
+ await this.reportCoverage(allTestsRun);
8400
8449
  this.runningPromise = void 0;
8450
+ this.isFirstRun = false;
8401
8451
  });
8402
8452
  return await this.runningPromise;
8403
8453
  }
@@ -8410,11 +8460,8 @@ class Vitest {
8410
8460
  const filteredFiles = await this.globTestFiles([this.filenamePattern]);
8411
8461
  files = files.filter((file) => filteredFiles.some((f) => f[1] === file));
8412
8462
  }
8413
- if (this.coverageProvider && this.config.coverage.cleanOnRerun)
8414
- await this.coverageProvider.clean();
8415
8463
  await this.report("onWatcherRerun", files, trigger);
8416
- await this.runFiles(files.flatMap((file) => this.getProjectsByTestFile(file)));
8417
- await this.reportCoverage(!trigger);
8464
+ await this.runFiles(files.flatMap((file) => this.getProjectsByTestFile(file)), !trigger);
8418
8465
  await this.report("onWatcherStart", this.state.getFiles(files));
8419
8466
  }
8420
8467
  async changeProjectName(pattern) {
@@ -8482,13 +8529,10 @@ class Vitest {
8482
8529
  return;
8483
8530
  }
8484
8531
  this.changedTests.clear();
8485
- if (this.coverageProvider && this.config.coverage.cleanOnRerun)
8486
- await this.coverageProvider.clean();
8487
8532
  const triggerIds = new Set(triggerId.map((id) => relative(this.config.root, id)));
8488
8533
  const triggerLabel = Array.from(triggerIds).join(", ");
8489
8534
  await this.report("onWatcherRerun", files, triggerLabel);
8490
- await this.runFiles(files.flatMap((file) => this.getProjectsByTestFile(file)));
8491
- await this.reportCoverage(false);
8535
+ await this.runFiles(files.flatMap((file) => this.getProjectsByTestFile(file)), false);
8492
8536
  await this.report("onWatcherStart", this.state.getFiles(files));
8493
8537
  }, WATCHER_DEBOUNCE);
8494
8538
  }
@@ -8542,6 +8586,10 @@ class Vitest {
8542
8586
  this.projectsTestFiles.set(id, new Set(matchingProjects));
8543
8587
  this.changedTests.add(id);
8544
8588
  this.scheduleRerun([id]);
8589
+ } else {
8590
+ const needsRerun = this.handleFileChanged(id);
8591
+ if (needsRerun.length)
8592
+ this.scheduleRerun(needsRerun);
8545
8593
  }
8546
8594
  };
8547
8595
  const watcher = this.server.watcher;
@@ -8833,7 +8881,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
8833
8881
  try {
8834
8882
  await ctx.setServer(options, server, userConfig);
8835
8883
  if (options.api && options.watch)
8836
- (await import('../chunks/api-setup.MAoRkVWJ.js')).setup(ctx);
8884
+ (await import('../chunks/api-setup.srzH0bDf.js')).setup(ctx);
8837
8885
  } catch (err) {
8838
8886
  await ctx.logger.printError(err, { fullStack: true });
8839
8887
  process.exit(1);
@@ -1,9 +1,9 @@
1
1
  import { performance } from 'node:perf_hooks';
2
2
  import c from 'picocolors';
3
3
  import { b as isNode, c as relativePath } from './index.rJjbcrrp.js';
4
- import { UNKNOWN_TEST_ID } from '../chunks/runtime-console.hf2msWA9.js';
4
+ import { UNKNOWN_TEST_ID } from '../chunks/runtime-console.Iloo9fIt.js';
5
5
  import { isAbsolute, relative, dirname, basename, resolve } from 'pathe';
6
- import { b as slash, t as toArray } from './base.dzu0Y6Hj.js';
6
+ import { b as slash, t as toArray } from './base.QYERqzkH.js';
7
7
  import { g as getFullName, h as hasFailedSnapshot } from './tasks.IknbGB2n.js';
8
8
  import { getSafeTimers, notNullish } from '@vitest/utils';
9
9
  import { isCI } from 'std-env';
@@ -10,7 +10,7 @@ async function setupCommonEnv(config) {
10
10
  globalSetup = true;
11
11
  setSafeTimers();
12
12
  if (config.globals)
13
- (await import('../chunks/integrations-globals.VbxbZ7hn.js')).registerApiGlobally();
13
+ (await import('../chunks/integrations-globals.J_6tnlri.js')).registerApiGlobally();
14
14
  }
15
15
  function setupDefines(defines) {
16
16
  for (const key in defines)
@@ -9,7 +9,7 @@ import { g as getFullName } from './tasks.IknbGB2n.js';
9
9
  import { g as getWorkerState, a as getCurrentEnvironment } from './global.CkGT_TMy.js';
10
10
  import { getSafeTimers, assertTypes, createSimpleStackTrace } from '@vitest/utils';
11
11
  import { parseSingleStack } from '@vitest/utils/source-map';
12
- import { i as isChildProcess } from './base.dzu0Y6Hj.js';
12
+ import { i as isChildProcess } from './base.QYERqzkH.js';
13
13
  import { R as RealDate, r as resetDate, m as mockDate } from './date.Ns1pGd_X.js';
14
14
  import { spyOn, fn, isMockFunction, mocks } from '@vitest/spy';
15
15
 
@@ -3036,6 +3036,7 @@ defaultImplementation.install;
3036
3036
  var withGlobal_1 = withGlobal;
3037
3037
 
3038
3038
  class FakeTimers {
3039
+ _global;
3039
3040
  _clock;
3040
3041
  _fakingTime;
3041
3042
  _fakingDate;
@@ -3050,6 +3051,7 @@ class FakeTimers {
3050
3051
  this._fakingDate = false;
3051
3052
  this._fakingTime = false;
3052
3053
  this._fakeTimers = withGlobal_1(global);
3054
+ this._global = global;
3053
3055
  }
3054
3056
  clearAllTimers() {
3055
3057
  if (this._fakingTime)
@@ -3118,7 +3120,7 @@ class FakeTimers {
3118
3120
  }
3119
3121
  }
3120
3122
  useFakeTimers() {
3121
- var _a, _b;
3123
+ var _a, _b, _c;
3122
3124
  if (this._fakingDate) {
3123
3125
  throw new Error(
3124
3126
  '"setSystemTime" was called already and date was mocked. Reset timers using `vi.useRealTimers()` if you want to use fake timers again.'
@@ -3128,10 +3130,19 @@ class FakeTimers {
3128
3130
  const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick");
3129
3131
  if (((_b = (_a = this._userConfig) == null ? void 0 : _a.toFake) == null ? void 0 : _b.includes("nextTick")) && isChildProcess())
3130
3132
  throw new Error("process.nextTick cannot be mocked inside child_process");
3133
+ const existingFakedMethods = (((_c = this._userConfig) == null ? void 0 : _c.toFake) || toFake).filter((method) => {
3134
+ switch (method) {
3135
+ case "setImmediate":
3136
+ case "clearImmediate":
3137
+ return method in this._global && this._global[method];
3138
+ default:
3139
+ return true;
3140
+ }
3141
+ });
3131
3142
  this._clock = this._fakeTimers.install({
3132
3143
  now: Date.now(),
3133
- toFake,
3134
- ...this._userConfig
3144
+ ...this._userConfig,
3145
+ toFake: existingFakedMethods
3135
3146
  });
3136
3147
  this._fakingTime = true;
3137
3148
  }