vitest 3.0.0-beta.4 → 3.0.0

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 (38) hide show
  1. package/dist/browser.d.ts +2 -2
  2. package/dist/chunks/{base.BJ8KO-VX.js → base.CUDzyU2J.js} +1 -1
  3. package/dist/chunks/{cac.BAYqQ2aM.js → cac.DZC9WjGM.js} +6 -6
  4. package/dist/chunks/{cli-api.Dhl34Trr.js → cli-api.CmJw5Cd_.js} +901 -65
  5. package/dist/chunks/{creator.Ot9GlSGw.js → creator.DztqrnyH.js} +1 -1
  6. package/dist/chunks/global.CnI8_G5V.d.ts +133 -0
  7. package/dist/chunks/{index.B2M9nD1V.js → index.CUcwvygK.js} +4 -4
  8. package/dist/chunks/{index.DQboAxJm.js → index.D9C26wCk.js} +1 -0
  9. package/dist/chunks/{index.CAueP3cK.js → index.TKSL1HjN.js} +188 -933
  10. package/dist/chunks/{reporters.Dcdq51WE.d.ts → reporters.Y8BYiXBN.d.ts} +340 -239
  11. package/dist/chunks/{resolveConfig.kZFMjKCQ.js → resolveConfig.CSLLD33d.js} +137 -52
  12. package/dist/chunks/{rpc.C3q9uwRX.js → rpc.TVf73xOu.js} +0 -1
  13. package/dist/chunks/{runBaseTests.URiUrnWK.js → runBaseTests.C0T_TQwH.js} +2 -2
  14. package/dist/chunks/{RandomSequencer.DB__To1b.js → typechecker.BJMkWMXo.js} +53 -106
  15. package/dist/chunks/{utils.yHKcm4dz.js → utils.DJWL04yX.js} +1 -1
  16. package/dist/chunks/{vite.DzluO1Kj.d.ts → vite.CQ0dHgkN.d.ts} +1 -1
  17. package/dist/chunks/{worker.BIVMnzXw.d.ts → worker.B1y96qmv.d.ts} +1 -1
  18. package/dist/chunks/{worker.Hz_LAzfd.d.ts → worker.CIpff8Eg.d.ts} +2 -4
  19. package/dist/cli.js +1 -1
  20. package/dist/config.d.ts +3 -3
  21. package/dist/coverage.d.ts +1 -1
  22. package/dist/coverage.js +5 -4
  23. package/dist/execute.d.ts +1 -1
  24. package/dist/index.d.ts +17 -118
  25. package/dist/node.d.ts +11 -8
  26. package/dist/node.js +25 -23
  27. package/dist/reporters.d.ts +1 -1
  28. package/dist/reporters.js +4 -6
  29. package/dist/runners.d.ts +1 -0
  30. package/dist/runners.js +7 -7
  31. package/dist/worker.js +1 -1
  32. package/dist/workers/forks.js +1 -1
  33. package/dist/workers/runVmTests.js +2 -2
  34. package/dist/workers/threads.js +1 -1
  35. package/dist/workers.d.ts +2 -2
  36. package/dist/workers.js +2 -2
  37. package/package.json +13 -13
  38. package/dist/chunks/types.BOjykUpq.d.ts +0 -27
@@ -1,4 +1,4 @@
1
- import { slash, createDefer, toArray } from '@vitest/utils';
1
+ import { slash, createDefer, shuffle, toArray } from '@vitest/utils';
2
2
  import fs, { statSync, realpathSync, promises as promises$1 } from 'node:fs';
3
3
  import { mkdir, writeFile } from 'node:fs/promises';
4
4
  import { builtinModules, createRequire } from 'node:module';
@@ -13,8 +13,10 @@ import c from 'tinyrainbow';
13
13
  import { e as extraInlineDeps, d as defaultPort, a as defaultBrowserPort, b as defaultInspectPort } from './constants.fzPh7AOq.js';
14
14
  import * as nodeos from 'node:os';
15
15
  import nodeos__default from 'node:os';
16
- import { h as hash, w as wrapSerializableConfig, a as Typechecker, b as isWindows, R as RandomSequencer, B as BaseSequencer } from './RandomSequencer.DB__To1b.js';
16
+ import { w as wrapSerializableConfig, a as Typechecker, b as isWindows } from './typechecker.BJMkWMXo.js';
17
17
  import { isCI, provider } from 'std-env';
18
+ import crypto from 'node:crypto';
19
+ import { isatty } from 'node:tty';
18
20
  import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
19
21
  import require$$0 from 'util';
20
22
  import require$$0$1 from 'path';
@@ -24,6 +26,7 @@ import Tinypool$1, { Tinypool } from 'tinypool';
24
26
  import { MessageChannel } from 'node:worker_threads';
25
27
  import { hasFailed } from '@vitest/runner/utils';
26
28
  import { rootDir } from '../path.js';
29
+ import { slash as slash$1 } from 'vite-node/utils';
27
30
 
28
31
  function groupBy(collection, iteratee) {
29
32
  return collection.reduce((acc, item) => {
@@ -51,6 +54,8 @@ function wildcardPatternToRegExp(pattern) {
51
54
  return new RegExp(`^${regexp}`, "i");
52
55
  }
53
56
 
57
+ const hash = crypto.hash ?? ((algorithm, data, outputEncoding) => crypto.createHash(algorithm).update(data).digest(outputEncoding));
58
+
54
59
  class FilesStatsCache {
55
60
  cache = /* @__PURE__ */ new Map();
56
61
  getStats(key) {
@@ -6600,7 +6605,7 @@ async function groupFilesByEnv(files) {
6600
6605
  const created = /* @__PURE__ */ new Set();
6601
6606
  const promises = /* @__PURE__ */ new Map();
6602
6607
  function createMethodsRPC(project, options = {}) {
6603
- const ctx = project.ctx;
6608
+ const ctx = project.vitest;
6604
6609
  const cacheFs = options.cacheFs ?? false;
6605
6610
  return {
6606
6611
  snapshotSaved(snapshot) {
@@ -6658,38 +6663,40 @@ function createMethodsRPC(project, options = {}) {
6658
6663
  transform(id, environment) {
6659
6664
  return project.vitenode.transformModule(id, environment).catch(handleRollupError);
6660
6665
  },
6661
- onPathsCollected(paths) {
6662
- ctx.state.collectPaths(paths);
6663
- return ctx.report("onPathsCollected", paths);
6664
- },
6665
- onQueued(file) {
6666
- ctx.state.collectFiles(project, [file]);
6667
- const testModule = ctx.state.getReportedEntity(file);
6668
- return ctx.report("onTestModuleQueued", testModule);
6666
+ async onQueued(file) {
6667
+ if (options.collect) {
6668
+ ctx.state.collectFiles(project, [file]);
6669
+ } else {
6670
+ await ctx._testRun.enqueued(project, file);
6671
+ }
6669
6672
  },
6670
- onCollected(files) {
6671
- ctx.state.collectFiles(project, files);
6672
- return ctx.report("onCollected", files);
6673
+ async onCollected(files) {
6674
+ if (options.collect) {
6675
+ ctx.state.collectFiles(project, files);
6676
+ } else {
6677
+ await ctx._testRun.collected(project, files);
6678
+ }
6673
6679
  },
6674
6680
  onAfterSuiteRun(meta) {
6675
6681
  ctx.coverageProvider?.onAfterSuiteRun(meta);
6676
6682
  },
6677
- onTaskUpdate(packs) {
6678
- ctx.state.updateTasks(packs);
6679
- return ctx.report("onTaskUpdate", packs);
6683
+ async onTaskUpdate(packs, events) {
6684
+ if (options.collect) {
6685
+ ctx.state.updateTasks(packs);
6686
+ } else {
6687
+ await ctx._testRun.updated(packs, events);
6688
+ }
6680
6689
  },
6681
- onUserConsoleLog(log) {
6682
- ctx.state.updateUserLog(log);
6683
- ctx.report("onUserConsoleLog", log);
6690
+ async onUserConsoleLog(log) {
6691
+ if (options.collect) {
6692
+ ctx.state.updateUserLog(log);
6693
+ } else {
6694
+ await ctx._testRun.log(log);
6695
+ }
6684
6696
  },
6685
6697
  onUnhandledError(err, type) {
6686
6698
  ctx.state.catchError(err, type);
6687
6699
  },
6688
- onFinished(files) {
6689
- const errors = ctx.state.getUnhandledErrors();
6690
- ctx._checkUnhandledErrors(errors);
6691
- return ctx.report("onFinished", files, errors);
6692
- },
6693
6700
  onCancel(reason) {
6694
6701
  ctx.cancelCurrentRun(reason);
6695
6702
  },
@@ -6716,7 +6723,7 @@ function handleRollupError(e) {
6716
6723
  throw e;
6717
6724
  }
6718
6725
 
6719
- function createChildProcessChannel$1(project) {
6726
+ function createChildProcessChannel$1(project, collect = false) {
6720
6727
  const emitter = new EventEmitter();
6721
6728
  const cleanup = () => emitter.removeAllListeners();
6722
6729
  const events = { message: "message", response: "response" };
@@ -6724,7 +6731,7 @@ function createChildProcessChannel$1(project) {
6724
6731
  onMessage: (callback) => emitter.on(events.message, callback),
6725
6732
  postMessage: (message) => emitter.emit(events.response, message)
6726
6733
  };
6727
- const rpc = createBirpc(createMethodsRPC(project, { cacheFs: true }), {
6734
+ const rpc = createBirpc(createMethodsRPC(project, { cacheFs: true, collect }), {
6728
6735
  eventNames: ["onCancel"],
6729
6736
  serialize: v8.serialize,
6730
6737
  deserialize: (v) => v8.deserialize(Buffer.from(v)),
@@ -6772,7 +6779,7 @@ function createForksPool(ctx, { execArgv, env }) {
6772
6779
  async function runFiles(project, config, files, environment, invalidates = []) {
6773
6780
  const paths = files.map((f) => f.filepath);
6774
6781
  ctx.state.clearFiles(project, paths);
6775
- const { channel, cleanup } = createChildProcessChannel$1(project);
6782
+ const { channel, cleanup } = createChildProcessChannel$1(project, name === "collect");
6776
6783
  const workerId = ++id;
6777
6784
  const data = {
6778
6785
  pool: "forks",
@@ -6907,11 +6914,11 @@ function createForksPool(ctx, { execArgv, env }) {
6907
6914
  };
6908
6915
  }
6909
6916
 
6910
- function createWorkerChannel$1(project) {
6917
+ function createWorkerChannel$1(project, collect) {
6911
6918
  const channel = new MessageChannel();
6912
6919
  const port = channel.port2;
6913
6920
  const workerPort = channel.port1;
6914
- const rpc = createBirpc(createMethodsRPC(project), {
6921
+ const rpc = createBirpc(createMethodsRPC(project, { collect }), {
6915
6922
  eventNames: ["onCancel"],
6916
6923
  post(v) {
6917
6924
  port.postMessage(v);
@@ -6959,7 +6966,7 @@ function createThreadsPool(ctx, { execArgv, env }) {
6959
6966
  async function runFiles(project, config, files, environment, invalidates = []) {
6960
6967
  const paths = files.map((f) => f.filepath);
6961
6968
  ctx.state.clearFiles(project, paths);
6962
- const { workerPort, port } = createWorkerChannel$1(project);
6969
+ const { workerPort, port } = createWorkerChannel$1(project, name === "collect");
6963
6970
  const workerId = ++id;
6964
6971
  const data = {
6965
6972
  pool: "threads",
@@ -7103,7 +7110,8 @@ function createTypecheckPool(ctx) {
7103
7110
  const rerunTriggered = /* @__PURE__ */ new WeakSet();
7104
7111
  async function onParseEnd(project, { files, sourceErrors }) {
7105
7112
  const checker = project.typechecker;
7106
- await ctx.report("onTaskUpdate", checker.getTestPacks());
7113
+ const { packs, events } = checker.getTestPacksAndEvents();
7114
+ await ctx._testRun.updated(packs, events);
7107
7115
  if (!project.config.typecheck.ignoreSourceErrors) {
7108
7116
  sourceErrors.forEach(
7109
7117
  (error) => ctx.state.catchError(error, "Unhandled Source Error")
@@ -7133,8 +7141,11 @@ function createTypecheckPool(ctx) {
7133
7141
  project.typechecker = checker;
7134
7142
  checker.setFiles(files);
7135
7143
  checker.onParseStart(async () => {
7136
- ctx.state.collectFiles(project, checker.getTestFiles());
7137
- await ctx.report("onCollected");
7144
+ const files2 = checker.getTestFiles();
7145
+ for (const file of files2) {
7146
+ await ctx._testRun.enqueued(project, file);
7147
+ }
7148
+ await ctx._testRun.collected(project, files2);
7138
7149
  });
7139
7150
  checker.onParseEnd((result) => onParseEnd(project, result));
7140
7151
  checker.onWatcherRerun(async () => {
@@ -7148,9 +7159,13 @@ function createTypecheckPool(ctx) {
7148
7159
  );
7149
7160
  }
7150
7161
  await checker.collectTests();
7151
- ctx.state.collectFiles(project, checker.getTestFiles());
7152
- await ctx.report("onTaskUpdate", checker.getTestPacks());
7153
- await ctx.report("onCollected");
7162
+ const testFiles = checker.getTestFiles();
7163
+ for (const file of testFiles) {
7164
+ await ctx._testRun.enqueued(project, file);
7165
+ }
7166
+ await ctx._testRun.collected(project, testFiles);
7167
+ const { packs, events } = checker.getTestPacksAndEvents();
7168
+ await ctx._testRun.updated(packs, events);
7154
7169
  });
7155
7170
  await checker.prepare();
7156
7171
  return checker;
@@ -7171,8 +7186,11 @@ function createTypecheckPool(ctx) {
7171
7186
  const checker = await createWorkspaceTypechecker(project, files);
7172
7187
  checker.setFiles(files);
7173
7188
  await checker.collectTests();
7174
- ctx.state.collectFiles(project, checker.getTestFiles());
7175
- await ctx.report("onCollected");
7189
+ const testFiles = checker.getTestFiles();
7190
+ for (const file of testFiles) {
7191
+ await ctx._testRun.enqueued(project, file);
7192
+ }
7193
+ await ctx._testRun.collected(project, testFiles);
7176
7194
  }
7177
7195
  }
7178
7196
  async function runTests(specs) {
@@ -7196,8 +7214,11 @@ function createTypecheckPool(ctx) {
7196
7214
  });
7197
7215
  const triggered = await _p;
7198
7216
  if (project.typechecker && !triggered) {
7199
- ctx.state.collectFiles(project, project.typechecker.getTestFiles());
7200
- await ctx.report("onCollected");
7217
+ const testFiles = project.typechecker.getTestFiles();
7218
+ for (const file of testFiles) {
7219
+ await ctx._testRun.enqueued(project, file);
7220
+ }
7221
+ await ctx._testRun.collected(project, testFiles);
7201
7222
  await onParseEnd(project, project.typechecker.getResult());
7202
7223
  continue;
7203
7224
  }
@@ -7285,7 +7306,7 @@ function stringToBytes(input, percentageReference) {
7285
7306
  }
7286
7307
 
7287
7308
  const suppressWarningsPath$1 = resolve$1(rootDir, "./suppress-warnings.cjs");
7288
- function createChildProcessChannel(project) {
7309
+ function createChildProcessChannel(project, collect) {
7289
7310
  const emitter = new EventEmitter();
7290
7311
  const cleanup = () => emitter.removeAllListeners();
7291
7312
  const events = { message: "message", response: "response" };
@@ -7294,7 +7315,7 @@ function createChildProcessChannel(project) {
7294
7315
  postMessage: (message) => emitter.emit(events.response, message)
7295
7316
  };
7296
7317
  const rpc = createBirpc(
7297
- createMethodsRPC(project, { cacheFs: true }),
7318
+ createMethodsRPC(project, { cacheFs: true, collect }),
7298
7319
  {
7299
7320
  eventNames: ["onCancel"],
7300
7321
  serialize: v8.serialize,
@@ -7348,7 +7369,7 @@ function createVmForksPool(ctx, { execArgv, env }) {
7348
7369
  async function runFiles(project, config, files, environment, invalidates = []) {
7349
7370
  const paths = files.map((f) => f.filepath);
7350
7371
  ctx.state.clearFiles(project, paths);
7351
- const { channel, cleanup } = createChildProcessChannel(project);
7372
+ const { channel, cleanup } = createChildProcessChannel(project, name === "collect");
7352
7373
  const workerId = ++id;
7353
7374
  const data = {
7354
7375
  pool: "forks",
@@ -7431,11 +7452,11 @@ function getMemoryLimit$1(config) {
7431
7452
  }
7432
7453
 
7433
7454
  const suppressWarningsPath = resolve$1(rootDir, "./suppress-warnings.cjs");
7434
- function createWorkerChannel(project) {
7455
+ function createWorkerChannel(project, collect) {
7435
7456
  const channel = new MessageChannel();
7436
7457
  const port = channel.port2;
7437
7458
  const workerPort = channel.port1;
7438
- const rpc = createBirpc(createMethodsRPC(project), {
7459
+ const rpc = createBirpc(createMethodsRPC(project, { collect }), {
7439
7460
  eventNames: ["onCancel"],
7440
7461
  post(v) {
7441
7462
  port.postMessage(v);
@@ -7487,7 +7508,7 @@ function createVmThreadsPool(ctx, { execArgv, env }) {
7487
7508
  async function runFiles(project, config, files, environment, invalidates = []) {
7488
7509
  const paths = files.map((f) => f.filepath);
7489
7510
  ctx.state.clearFiles(project, paths);
7490
- const { workerPort, port } = createWorkerChannel(project);
7511
+ const { workerPort, port } = createWorkerChannel(project, name === "collect");
7491
7512
  const workerId = ++id;
7492
7513
  const data = {
7493
7514
  pool: "vmThreads",
@@ -7634,6 +7655,7 @@ function createPool(ctx) {
7634
7655
  VITEST: "true",
7635
7656
  NODE_ENV: process.env.NODE_ENV || "test",
7636
7657
  VITEST_MODE: ctx.config.watch ? "WATCH" : "RUN",
7658
+ FORCE_TTY: isatty(1) ? "true" : "",
7637
7659
  ...process.env,
7638
7660
  ...ctx.config.env
7639
7661
  }
@@ -7730,6 +7752,61 @@ function createPool(ctx) {
7730
7752
  };
7731
7753
  }
7732
7754
 
7755
+ class BaseSequencer {
7756
+ ctx;
7757
+ constructor(ctx) {
7758
+ this.ctx = ctx;
7759
+ }
7760
+ // async so it can be extended by other sequelizers
7761
+ async shard(files) {
7762
+ const { config } = this.ctx;
7763
+ const { index, count } = config.shard;
7764
+ const shardSize = Math.ceil(files.length / count);
7765
+ const shardStart = shardSize * (index - 1);
7766
+ const shardEnd = shardSize * index;
7767
+ return [...files].map((spec) => {
7768
+ const fullPath = resolve(slash$1(config.root), slash$1(spec.moduleId));
7769
+ const specPath = fullPath?.slice(config.root.length);
7770
+ return {
7771
+ spec,
7772
+ hash: hash("sha1", specPath, "hex")
7773
+ };
7774
+ }).sort((a, b) => a.hash < b.hash ? -1 : a.hash > b.hash ? 1 : 0).slice(shardStart, shardEnd).map(({ spec }) => spec);
7775
+ }
7776
+ // async so it can be extended by other sequelizers
7777
+ async sort(files) {
7778
+ const cache = this.ctx.cache;
7779
+ return [...files].sort((a, b) => {
7780
+ const keyA = `${a.project.name}:${relative(this.ctx.config.root, a.moduleId)}`;
7781
+ const keyB = `${b.project.name}:${relative(this.ctx.config.root, b.moduleId)}`;
7782
+ const aState = cache.getFileTestResults(keyA);
7783
+ const bState = cache.getFileTestResults(keyB);
7784
+ if (!aState || !bState) {
7785
+ const statsA = cache.getFileStats(keyA);
7786
+ const statsB = cache.getFileStats(keyB);
7787
+ if (!statsA || !statsB) {
7788
+ return !statsA && statsB ? -1 : !statsB && statsA ? 1 : 0;
7789
+ }
7790
+ return statsB.size - statsA.size;
7791
+ }
7792
+ if (aState.failed && !bState.failed) {
7793
+ return -1;
7794
+ }
7795
+ if (!aState.failed && bState.failed) {
7796
+ return 1;
7797
+ }
7798
+ return bState.duration - aState.duration;
7799
+ });
7800
+ }
7801
+ }
7802
+
7803
+ class RandomSequencer extends BaseSequencer {
7804
+ async sort(files) {
7805
+ const { sequence } = this.ctx.config;
7806
+ return shuffle(files, sequence.seed);
7807
+ }
7808
+ }
7809
+
7733
7810
  function resolvePath(path, root) {
7734
7811
  return normalize(
7735
7812
  /* @__PURE__ */ resolveModule(path, { paths: [root] }) ?? resolve(root, path)
@@ -7889,15 +7966,22 @@ function resolveConfig(mode, options, viteConfig, logger) {
7889
7966
  ].join(""));
7890
7967
  }
7891
7968
  }
7892
- if (browser.enabled && !(browser.provider === "playwright" && browser.name === "chromium")) {
7893
- const browserConfig = { browser: { provider: browser.provider, name: browser.name } };
7969
+ const playwrightChromiumOnly = browser.provider === "playwright" && (browser.name === "chromium" || browser.instances?.every((i) => i.browser === "chromium"));
7970
+ if (browser.enabled && !playwrightChromiumOnly) {
7971
+ const browserConfig = {
7972
+ browser: {
7973
+ provider: browser.provider,
7974
+ name: browser.name,
7975
+ instances: browser.instances
7976
+ }
7977
+ };
7894
7978
  if (resolved.coverage.enabled && resolved.coverage.provider === "v8") {
7895
7979
  throw new Error(
7896
7980
  `@vitest/coverage-v8 does not work with
7897
7981
  ${JSON.stringify(browserConfig, null, 2)}
7898
7982
 
7899
7983
  Use either:
7900
- ${JSON.stringify({ browser: { provider: "playwright", name: "chromium" } }, null, 2)}
7984
+ ${JSON.stringify({ browser: { provider: "playwright", instances: [{ browser: "chromium" }] } }, null, 2)}
7901
7985
 
7902
7986
  ...or change your coverage provider to:
7903
7987
  ${JSON.stringify({ coverage: { provider: "istanbul" } }, null, 2)}
@@ -7911,7 +7995,7 @@ ${JSON.stringify({ coverage: { provider: "istanbul" } }, null, 2)}
7911
7995
  ${JSON.stringify(browserConfig, null, 2)}
7912
7996
 
7913
7997
  Use either:
7914
- ${JSON.stringify({ browser: { provider: "playwright", name: "chromium" } }, null, 2)}
7998
+ ${JSON.stringify({ browser: { provider: "playwright", instances: [{ browser: "chromium" }] } }, null, 2)}
7915
7999
 
7916
8000
  ...or disable ${inspectOption}
7917
8001
  `
@@ -7976,6 +8060,7 @@ ${JSON.stringify({ browser: { provider: "playwright", name: "chromium" } }, null
7976
8060
  )}`
7977
8061
  )
7978
8062
  );
8063
+ resolved.coverage.exclude.push(...resolved.include);
7979
8064
  resolved.forceRerunTriggers = [
7980
8065
  ...resolved.forceRerunTriggers,
7981
8066
  ...resolved.setupFiles
@@ -8383,4 +8468,4 @@ function resolveCoverageReporters(configReporters) {
8383
8468
  return resolvedReporters;
8384
8469
  }
8385
8470
 
8386
- export { VitestCache as V, resolveConfig as a, resolveApiServerConfig as b, coverageConfigDefaults as c, createMethodsRPC as d, requireMicromatch as e, configDefaults as f, getFilePoolName as g, isBrowserEnabled as h, isPackageExists as i, groupBy as j, createPool as k, mm as m, resolveCoverageReporters as r, stdout as s, wildcardPatternToRegExp as w };
8471
+ export { BaseSequencer as B, RandomSequencer as R, VitestCache as V, resolveConfig as a, resolveApiServerConfig as b, coverageConfigDefaults as c, createMethodsRPC as d, requireMicromatch as e, configDefaults as f, getFilePoolName as g, hash as h, isPackageExists as i, isBrowserEnabled as j, groupBy as k, createPool as l, mm as m, resolveCoverageReporters as r, stdout as s, wildcardPatternToRegExp as w };
@@ -54,7 +54,6 @@ function createRuntimeRpc(options) {
54
54
  {
55
55
  eventNames: [
56
56
  "onUserConsoleLog",
57
- "onFinished",
58
57
  "onCollected",
59
58
  "onCancel"
60
59
  ],
@@ -1,6 +1,6 @@
1
1
  import { performance } from 'node:perf_hooks';
2
2
  import { startTests, collectTests } from '@vitest/runner';
3
- import { a as resolveSnapshotEnvironment, s as setupChaiConfig, r as resolveTestRunner } from './index.B2M9nD1V.js';
3
+ import { a as resolveSnapshotEnvironment, s as setupChaiConfig, r as resolveTestRunner } from './index.CUcwvygK.js';
4
4
  import { s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from './coverage.BWeNbfBa.js';
5
5
  import { a as globalExpect, v as vi } from './vi.Da_PT3Vw.js';
6
6
  import { c as closeInspector } from './inspector.DKLceBVD.js';
@@ -18,7 +18,7 @@ import 'chai';
18
18
  import 'node:path';
19
19
  import '../path.js';
20
20
  import 'node:url';
21
- import './rpc.C3q9uwRX.js';
21
+ import './rpc.TVf73xOu.js';
22
22
  import './index.68735LiX.js';
23
23
  import '@vitest/expect';
24
24
  import '@vitest/runner/utils';
@@ -1,10 +1,11 @@
1
1
  import { isCI } from 'std-env';
2
2
  import { writeFile, rm } from 'node:fs/promises';
3
3
  import { performance } from 'node:perf_hooks';
4
- import { generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks } from '@vitest/runner/utils';
5
4
  import { TraceMap, generatedPositionFor, eachMapping } from '@vitest/utils/source-map';
6
5
  import { relative, basename, dirname, resolve, join, extname } from 'pathe';
7
6
  import { x as x$1 } from 'tinyexec';
7
+ import { getTests, generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes } from '@vitest/runner/utils';
8
+ import '@vitest/utils';
8
9
  import { parseAstAsync } from 'vite';
9
10
  import nodeos__default from 'node:os';
10
11
  import url from 'node:url';
@@ -12,11 +13,37 @@ import a$1 from 'node:path';
12
13
  import fs from 'node:fs';
13
14
  import Te from 'node:module';
14
15
  import require$$0 from 'fs';
15
- import { shuffle } from '@vitest/utils';
16
- import { slash } from 'vite-node/utils';
17
- import crypto from 'node:crypto';
18
16
 
19
- const hash = crypto.hash ?? ((algorithm, data, outputEncoding) => crypto.createHash(algorithm).update(data).digest(outputEncoding));
17
+ function hasFailedSnapshot(suite) {
18
+ return getTests(suite).some((s) => {
19
+ return s.result?.errors?.some(
20
+ (e) => typeof e?.message === "string" && e.message.match(/Snapshot .* mismatched/)
21
+ );
22
+ });
23
+ }
24
+ function convertTasksToEvents(file, onTask) {
25
+ const packs = [];
26
+ const events = [];
27
+ function visit(suite) {
28
+ onTask?.(suite);
29
+ packs.push([suite.id, suite.result, suite.meta]);
30
+ events.push([suite.id, "suite-prepare"]);
31
+ suite.tasks.forEach((task) => {
32
+ if (task.type === "suite") {
33
+ visit(task);
34
+ } else {
35
+ onTask?.(task);
36
+ packs.push([task.id, task.result, task.meta]);
37
+ if (task.mode !== "skip" && task.mode !== "todo") {
38
+ events.push([task.id, "test-prepare"], [task.id, "test-finished"]);
39
+ }
40
+ }
41
+ });
42
+ events.push([suite.id, "suite-finished"]);
43
+ }
44
+ visit(file);
45
+ return { packs, events };
46
+ }
20
47
 
21
48
  const isNode = typeof process < "u" && typeof process.stdout < "u" && !process.versions?.deno && !globalThis.window;
22
49
  const isDeno = typeof process < "u" && typeof process.stdout < "u" && process.versions?.deno !== void 0;
@@ -363,17 +390,13 @@ async function collectTests(ctx, filepath) {
363
390
  return getName(callee.tag);
364
391
  }
365
392
  if (callee.type === "MemberExpression") {
366
- const object = callee.object;
367
- if (object?.name?.startsWith("__vite_ssr_")) {
368
- return getName(callee.property);
393
+ if (callee.object?.type === "Identifier" && ["it", "test", "describe", "suite"].includes(callee.object.name)) {
394
+ return callee.object?.name;
369
395
  }
370
- return getName(object?.property);
371
- }
372
- if (callee.type === "SequenceExpression" && callee.expressions.length === 2) {
373
- const [e0, e1] = callee.expressions;
374
- if (e0.type === "Literal" && e0.value === 0) {
375
- return getName(e1);
396
+ if (callee.object?.name?.startsWith("__vite_ssr_")) {
397
+ return getName(callee.property);
376
398
  }
399
+ return getName(callee.object?.property);
377
400
  }
378
401
  return null;
379
402
  };
@@ -388,8 +411,8 @@ async function collectTests(ctx, filepath) {
388
411
  return;
389
412
  }
390
413
  const property = callee?.property?.name;
391
- const mode = !property || property === name ? "run" : property;
392
- if (mode === "each" || mode === "skipIf" || mode === "runIf" || mode === "for") {
414
+ let mode = !property || property === name ? "run" : property;
415
+ if (["each", "for", "skipIf", "runIf"].includes(mode)) {
393
416
  return;
394
417
  }
395
418
  let start;
@@ -404,10 +427,11 @@ async function collectTests(ctx, filepath) {
404
427
  const {
405
428
  arguments: [messageNode]
406
429
  } = node;
407
- if (!messageNode) {
408
- return;
430
+ const isQuoted = messageNode?.type === "Literal" || messageNode?.type === "TemplateLiteral";
431
+ const message = isQuoted ? request.code.slice(messageNode.start + 1, messageNode.end - 1) : request.code.slice(messageNode.start, messageNode.end);
432
+ if (mode === "skipIf" || mode === "runIf") {
433
+ mode = "skip";
409
434
  }
410
- const message = getNodeAsString(messageNode, request.code);
411
435
  definitions.push({
412
436
  start,
413
437
  end,
@@ -487,35 +511,6 @@ async function collectTests(ctx, filepath) {
487
511
  definitions
488
512
  };
489
513
  }
490
- function getNodeAsString(node, code) {
491
- if (node.type === "Literal") {
492
- return String(node.value);
493
- } else if (node.type === "Identifier") {
494
- return node.name;
495
- } else if (node.type === "TemplateLiteral") {
496
- return mergeTemplateLiteral(node, code);
497
- } else {
498
- return code.slice(node.start, node.end);
499
- }
500
- }
501
- function mergeTemplateLiteral(node, code) {
502
- let result = "";
503
- let expressionsIndex = 0;
504
- for (let quasisIndex = 0; quasisIndex < node.quasis.length; quasisIndex++) {
505
- result += node.quasis[quasisIndex].value.raw;
506
- if (expressionsIndex in node.expressions) {
507
- const expression = node.expressions[expressionsIndex];
508
- const string = expression.type === "Literal" ? expression.raw : getNodeAsString(expression, code);
509
- if (expression.type === "TemplateLiteral") {
510
- result += `\${\`${string}\`}`;
511
- } else {
512
- result += `\${${string}}`;
513
- }
514
- expressionsIndex++;
515
- }
516
- }
517
- return result;
518
- }
519
514
 
520
515
  const A=r=>r!==null&&typeof r=="object",a=(r,t)=>Object.assign(new Error(`[${r}]: ${t}`),{code:r}),_="ERR_INVALID_PACKAGE_CONFIG",E="ERR_INVALID_PACKAGE_TARGET",I$1="ERR_PACKAGE_PATH_NOT_EXPORTED",R$1=/^\d+$/,O=/^(\.{1,2}|node_modules)$/i,w=/\/|\\/;var h$1=(r=>(r.Export="exports",r.Import="imports",r))(h$1||{});const f=(r,t,e,o,c)=>{if(t==null)return [];if(typeof t=="string"){const[n,...i]=t.split(w);if(n===".."||i.some(l=>O.test(l)))throw a(E,`Invalid "${r}" target "${t}" defined in the package config`);return [c?t.replace(/\*/g,c):t]}if(Array.isArray(t))return t.flatMap(n=>f(r,n,e,o,c));if(A(t)){for(const n of Object.keys(t)){if(R$1.test(n))throw a(_,"Cannot contain numeric property keys");if(n==="default"||o.includes(n))return f(r,t[n],e,o,c)}return []}throw a(E,`Invalid "${r}" target "${t}"`)},s="*",m=(r,t)=>{const e=r.indexOf(s),o=t.indexOf(s);return e===o?t.length>r.length:o>e};function d(r,t){if(!t.includes(s)&&r.hasOwnProperty(t))return [t];let e,o;for(const c of Object.keys(r))if(c.includes(s)){const[n,i,l]=c.split(s);if(l===void 0&&t.startsWith(n)&&t.endsWith(i)){const g=t.slice(n.length,-i.length||void 0);g&&(!e||m(e,c))&&(e=c,o=g);}}return [e,o]}const p=r=>Object.keys(r).reduce((t,e)=>{const o=e===""||e[0]!==".";if(t===void 0||t===o)return o;throw a(_,'"exports" cannot contain some keys starting with "." and some not')},void 0),u=/^\w+:/,v=(r,t,e)=>{if(!r)throw new Error('"exports" is required');t=t===""?".":`./${t}`,(typeof r=="string"||Array.isArray(r)||A(r)&&p(r))&&(r={".":r});const[o,c]=d(r,t),n=f(h$1.Export,r[o],t,e,c);if(n.length===0)throw a(I$1,t==="."?'No "exports" main defined':`Package subpath '${t}' is not defined by "exports"`);for(const i of n)if(!i.startsWith("./")&&!u.test(i))throw a(E,`Invalid "exports" target "${i}" defined in the package config`);return n};
521
516
 
@@ -921,8 +916,15 @@ class Typechecker {
921
916
  getTestFiles() {
922
917
  return Object.values(this._tests || {}).map((i) => i.file);
923
918
  }
924
- getTestPacks() {
925
- return Object.values(this._tests || {}).map(({ file }) => getTasks(file)).flat().map((i) => [i.id, i.result, { typecheck: true }]);
919
+ getTestPacksAndEvents() {
920
+ const packs = [];
921
+ const events = [];
922
+ for (const { file } of Object.values(this._tests || {})) {
923
+ const result = convertTasksToEvents(file);
924
+ packs.push(...result.packs);
925
+ events.push(...result.events);
926
+ }
927
+ return { packs, events };
926
928
  }
927
929
  }
928
930
  function findGeneratedPosition(traceMap, { line, column, source }) {
@@ -952,59 +954,4 @@ function findGeneratedPosition(traceMap, { line, column, source }) {
952
954
  return { line: null, column: null };
953
955
  }
954
956
 
955
- class BaseSequencer {
956
- ctx;
957
- constructor(ctx) {
958
- this.ctx = ctx;
959
- }
960
- // async so it can be extended by other sequelizers
961
- async shard(files) {
962
- const { config } = this.ctx;
963
- const { index, count } = config.shard;
964
- const shardSize = Math.ceil(files.length / count);
965
- const shardStart = shardSize * (index - 1);
966
- const shardEnd = shardSize * index;
967
- return [...files].map((spec) => {
968
- const fullPath = resolve(slash(config.root), slash(spec.moduleId));
969
- const specPath = fullPath?.slice(config.root.length);
970
- return {
971
- spec,
972
- hash: hash("sha1", specPath, "hex")
973
- };
974
- }).sort((a, b) => a.hash < b.hash ? -1 : a.hash > b.hash ? 1 : 0).slice(shardStart, shardEnd).map(({ spec }) => spec);
975
- }
976
- // async so it can be extended by other sequelizers
977
- async sort(files) {
978
- const cache = this.ctx.cache;
979
- return [...files].sort((a, b) => {
980
- const keyA = `${a.project.name}:${relative(this.ctx.config.root, a.moduleId)}`;
981
- const keyB = `${b.project.name}:${relative(this.ctx.config.root, b.moduleId)}`;
982
- const aState = cache.getFileTestResults(keyA);
983
- const bState = cache.getFileTestResults(keyB);
984
- if (!aState || !bState) {
985
- const statsA = cache.getFileStats(keyA);
986
- const statsB = cache.getFileStats(keyB);
987
- if (!statsA || !statsB) {
988
- return !statsA && statsB ? -1 : !statsB && statsA ? 1 : 0;
989
- }
990
- return statsB.size - statsA.size;
991
- }
992
- if (aState.failed && !bState.failed) {
993
- return -1;
994
- }
995
- if (!aState.failed && bState.failed) {
996
- return 1;
997
- }
998
- return bState.duration - aState.duration;
999
- });
1000
- }
1001
- }
1002
-
1003
- class RandomSequencer extends BaseSequencer {
1004
- async sort(files) {
1005
- const { sequence } = this.ctx.config;
1006
- return shuffle(files, sequence.seed);
1007
- }
1008
- }
1009
-
1010
- export { BaseSequencer as B, RandomSequencer as R, TypeCheckError as T, Typechecker as a, isWindows as b, getOutputFile as g, hash as h, isTTY as i, wrapSerializableConfig as w };
957
+ export { TypeCheckError as T, Typechecker as a, isWindows as b, convertTasksToEvents as c, getOutputFile as g, hasFailedSnapshot as h, isTTY as i, wrapSerializableConfig as w };
@@ -195,4 +195,4 @@ var utils = /*#__PURE__*/Object.freeze({
195
195
  withLabel: withLabel
196
196
  });
197
197
 
198
- export { F_POINTER as F, formatTimeString as a, taskFail as b, F_RIGHT as c, divider as d, F_CHECK as e, formatProjectName as f, getStateSymbol as g, getStateString as h, formatTime as i, countTestErrors as j, F_TREE_NODE_END as k, F_TREE_NODE_MIDDLE as l, padSummaryTitle as p, renderSnapshotSummary as r, truncateString as t, utils as u, withLabel as w };
198
+ export { F_POINTER as F, formatProjectName as a, taskFail as b, F_RIGHT as c, divider as d, F_CHECK as e, formatTimeString as f, getStateSymbol as g, getStateString as h, formatTime as i, countTestErrors as j, F_TREE_NODE_END as k, F_TREE_NODE_MIDDLE as l, padSummaryTitle as p, renderSnapshotSummary as r, truncateString as t, utils as u, withLabel as w };
@@ -1,4 +1,4 @@
1
- import { I as InlineConfig } from './reporters.Dcdq51WE.js';
1
+ import { I as InlineConfig } from './reporters.Y8BYiXBN.js';
2
2
 
3
3
  type VitestInlineConfig = InlineConfig;
4
4
  declare module 'vite' {
@@ -1,5 +1,5 @@
1
1
  import { MessagePort } from 'node:worker_threads';
2
- import { C as ContextRPC } from './worker.Hz_LAzfd.js';
2
+ import { C as ContextRPC } from './worker.CIpff8Eg.js';
3
3
 
4
4
  interface WorkerContext extends ContextRPC {
5
5
  port: MessagePort;