vitest 3.0.2 → 3.0.4

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 (31) hide show
  1. package/dist/browser.d.ts +1 -1
  2. package/dist/chunks/{base.gZAre3Yy.js → base.wKnmhRYd.js} +1 -1
  3. package/dist/chunks/{cac.CHB7MTUk.js → cac.DYBkNWP6.js} +4 -4
  4. package/dist/chunks/{cli-api.B7hOUwun.js → cli-api.Ci-9Ccnz.js} +180 -72
  5. package/dist/chunks/{creator.B8v1wNyQ.js → creator.fUJbheb8.js} +2 -2
  6. package/dist/chunks/{execute.4vt3NSmG.js → execute.PoofJYS5.js} +2 -1
  7. package/dist/chunks/{index.Bh7wTRhh.js → index.B57_6XMC.js} +7 -7
  8. package/dist/chunks/{index.DfqWks-F.js → index.NxxmQyK2.js} +7 -7
  9. package/dist/chunks/{index.DyQPL4DO.js → index.vId0fl99.js} +24 -4
  10. package/dist/chunks/{reporters.Y8BYiXBN.d.ts → reporters.0x019-V2.d.ts} +4 -3
  11. package/dist/chunks/{resolveConfig.DATSOo7x.js → resolveConfig.DkmB2h7h.js} +53 -20
  12. package/dist/chunks/{typechecker.ChNaIV36.js → typechecker.CdcjdhoT.js} +17 -11
  13. package/dist/chunks/{vite.CQ0dHgkN.d.ts → vite.DiG-KbRF.d.ts} +1 -1
  14. package/dist/chunks/{vm.CUw7ChSp.js → vm.DXDoSHPT.js} +1 -1
  15. package/dist/cli.js +1 -1
  16. package/dist/config.d.ts +3 -3
  17. package/dist/coverage.d.ts +1 -1
  18. package/dist/coverage.js +2 -2
  19. package/dist/execute.d.ts +1 -1
  20. package/dist/execute.js +1 -1
  21. package/dist/index.d.ts +3 -3
  22. package/dist/node.d.ts +5 -5
  23. package/dist/node.js +10 -11
  24. package/dist/reporters.d.ts +1 -1
  25. package/dist/reporters.js +2 -2
  26. package/dist/workers/forks.js +2 -2
  27. package/dist/workers/threads.js +2 -2
  28. package/dist/workers/vmForks.js +2 -2
  29. package/dist/workers/vmThreads.js +2 -2
  30. package/dist/workers.js +3 -3
  31. package/package.json +19 -15
package/dist/browser.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as CoverageProvider, c as CoverageProviderModule } from './chunks/reporters.Y8BYiXBN.js';
1
+ import { b as CoverageProvider, c as CoverageProviderModule } from './chunks/reporters.0x019-V2.js';
2
2
  import { a as SerializedCoverageConfig, S as SerializedConfig } from './chunks/config.BRtC-JeT.js';
3
3
  import * as spy$1 from '@vitest/spy';
4
4
  import * as _vitest_utils_diff from '@vitest/utils/diff';
@@ -1,5 +1,5 @@
1
1
  import { ModuleCacheMap } from 'vite-node/client';
2
- import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.4vt3NSmG.js';
2
+ import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.PoofJYS5.js';
3
3
  import { p as provideWorkerState } from './utils.C8RiOc4B.js';
4
4
 
5
5
  let _viteNode;
@@ -618,7 +618,7 @@ class CAC extends EventEmitter {
618
618
 
619
619
  const cac = (name = "") => new CAC(name);
620
620
 
621
- var version = "3.0.2";
621
+ var version = "3.0.4";
622
622
 
623
623
  const apiConfig = (port) => ({
624
624
  port: {
@@ -1567,7 +1567,7 @@ async function start(mode, cliFilters, options) {
1567
1567
  } catch {
1568
1568
  }
1569
1569
  try {
1570
- const { startVitest } = await import('./cli-api.B7hOUwun.js').then(function (n) { return n.f; });
1570
+ const { startVitest } = await import('./cli-api.Ci-9Ccnz.js').then(function (n) { return n.f; });
1571
1571
  const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1572
1572
  if (!ctx.shouldKeepServer()) {
1573
1573
  await ctx.exit();
@@ -1589,7 +1589,7 @@ async function init(project) {
1589
1589
  console.error(new Error('Only the "browser" project is supported. Use "vitest init browser" to create a new project.'));
1590
1590
  process.exit(1);
1591
1591
  }
1592
- const { create } = await import('./creator.B8v1wNyQ.js');
1592
+ const { create } = await import('./creator.fUJbheb8.js');
1593
1593
  await create();
1594
1594
  }
1595
1595
  async function collect(mode, cliFilters, options) {
@@ -1598,7 +1598,7 @@ async function collect(mode, cliFilters, options) {
1598
1598
  } catch {
1599
1599
  }
1600
1600
  try {
1601
- const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.B7hOUwun.js').then(function (n) { return n.f; });
1601
+ const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.Ci-9Ccnz.js').then(function (n) { return n.f; });
1602
1602
  const ctx = await prepareVitest(mode, {
1603
1603
  ...normalizeCliOptions(cliFilters, options),
1604
1604
  watch: false,
@@ -1,18 +1,19 @@
1
1
  import { existsSync, promises, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
2
2
  import { extname, normalize, relative, dirname, resolve, join, basename, isAbsolute } from 'pathe';
3
3
  import { g as getCoverageProvider, C as CoverageProviderMap } from './coverage.BWeNbfBa.js';
4
- import a, { resolve as resolve$1 } from 'node:path';
4
+ import p, { resolve as resolve$1 } from 'node:path';
5
5
  import { noop, isPrimitive, createDefer, highlight, toArray, deepMerge, nanoid, slash, deepClone, notNullish } from '@vitest/utils';
6
- import { f as findUp, p as prompt } from './index.Bh7wTRhh.js';
6
+ import { f as findUp, p as prompt } from './index.B57_6XMC.js';
7
+ import * as vite from 'vite';
7
8
  import { searchForWorkspaceRoot, version, createServer, mergeConfig } from 'vite';
8
9
  import { A as API_PATH, c as configFiles, a as defaultBrowserPort, w as workspacesFiles, d as defaultPort } from './constants.fzPh7AOq.js';
9
10
  import { generateFileHash, createFileTask, limitConcurrency, hasFailed, getTasks, getTests } from '@vitest/runner/utils';
10
11
  import { SnapshotManager } from '@vitest/snapshot/manager';
11
12
  import { ViteNodeRunner } from 'vite-node/client';
12
13
  import { ViteNodeServer } from 'vite-node/server';
13
- import { v as version$1 } from './cac.CHB7MTUk.js';
14
+ import { v as version$1 } from './cac.DYBkNWP6.js';
14
15
  import { c as createBirpc } from './index.TH3f4LSA.js';
15
- import { s as stringify, p as parse, g as printError, h as generateCodeFrame, R as ReportersMap, b as BenchmarkReportsMap, i as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.DyQPL4DO.js';
16
+ import { s as stringify, p as parse, g as printError, h as generateCodeFrame, R as ReportersMap, b as BenchmarkReportsMap, i as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.vId0fl99.js';
16
17
  import require$$0$2 from 'stream';
17
18
  import require$$0 from 'zlib';
18
19
  import require$$0$1 from 'buffer';
@@ -26,8 +27,8 @@ import require$$7 from 'url';
26
27
  import { g as getDefaultExportFromCjs, c as commonjsGlobal } from './_commonjsHelpers.BFTU3MAI.js';
27
28
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
28
29
  import { distDir, rootDir } from '../path.js';
29
- import { R as RandomSequencer, i as isPackageExists, e as requireMicromatch, h as hash, V as VitestCache, f as configDefaults, g as getFilePoolName, j as isBrowserEnabled, m as mm, a as resolveConfig, k as groupBy, w as wildcardPatternToRegExp, l as createPool, b as resolveApiServerConfig, s as stdout } from './resolveConfig.DATSOo7x.js';
30
- import { i as isTTY, b as isWindows, c as convertTasksToEvents } from './typechecker.ChNaIV36.js';
30
+ import { R as RandomSequencer, i as isPackageExists, e as requireMicromatch, h as hash, V as VitestCache, f as configDefaults, g as getFilePoolName, j as isBrowserEnabled, m as mm, a as resolveConfig, k as groupBy, w as wildcardPatternToRegExp, l as createPool, b as resolveApiServerConfig, s as stdout } from './resolveConfig.DkmB2h7h.js';
31
+ import { i as isTTY, b as isWindows, c as convertTasksToEvents } from './typechecker.CdcjdhoT.js';
31
32
  import { Console } from 'node:console';
32
33
  import c from 'tinyrainbow';
33
34
  import { a as formatProjectName, w as withLabel, d as divider } from './utils.DJWL04yX.js';
@@ -5123,6 +5124,12 @@ class RangeLocationFilterProvidedError extends Error {
5123
5124
  super(`Found "-" in location filter ${filter}. Note that range location filters are not supported. Consider specifying the exact line numbers of your tests.`);
5124
5125
  }
5125
5126
  }
5127
+ class VitestFilteredOutProjectError extends Error {
5128
+ code = "VITEST_FILTERED_OUT_PROJECT";
5129
+ constructor() {
5130
+ super("VITEST_FILTERED_OUT_PROJECT");
5131
+ }
5132
+ }
5126
5133
 
5127
5134
  const HIGHLIGHT_SUPPORTED_EXTS = new Set(
5128
5135
  ["js", "ts"].flatMap((lang) => [
@@ -5442,7 +5449,7 @@ class VitestPackageInstaller {
5442
5449
  if (!isTTY) {
5443
5450
  return false;
5444
5451
  }
5445
- const prompts = await import('./index.Bh7wTRhh.js').then(function (n) { return n.i; });
5452
+ const prompts = await import('./index.B57_6XMC.js').then(function (n) { return n.i; });
5446
5453
  const { install } = await prompts.default({
5447
5454
  type: "confirm",
5448
5455
  name: "install",
@@ -5450,7 +5457,7 @@ class VitestPackageInstaller {
5450
5457
  });
5451
5458
  if (install) {
5452
5459
  const packageName = version ? `${dependency}@${version}` : dependency;
5453
- await (await import('./index.DfqWks-F.js')).installPackage(packageName, { dev: true });
5460
+ await (await import('./index.NxxmQyK2.js')).installPackage(packageName, { dev: true });
5454
5461
  process.stderr.write(
5455
5462
  c.yellow(
5456
5463
  `
@@ -9693,6 +9700,24 @@ function resolveFsAllow(projectRoot, rootConfigFile) {
9693
9700
  rootDir
9694
9701
  ];
9695
9702
  }
9703
+ function getDefaultResolveOptions() {
9704
+ return {
9705
+ // by default Vite resolves `module` field, which is not always a native ESM module
9706
+ // setting this option can bypass that and fallback to cjs version
9707
+ mainFields: [],
9708
+ // same for `module` condition and Vite 5 doesn't even allow excluding it,
9709
+ // but now it's possible since Vite 6.
9710
+ conditions: getDefaultServerConditions()
9711
+ };
9712
+ }
9713
+ function getDefaultServerConditions() {
9714
+ const viteMajor = Number(version.split(".")[0]);
9715
+ if (viteMajor >= 6) {
9716
+ const conditions = vite.defaultServerConditions;
9717
+ return conditions.filter((c) => c !== "module");
9718
+ }
9719
+ return ["node"];
9720
+ }
9696
9721
 
9697
9722
  function VitestOptimizer() {
9698
9723
  return {
@@ -9813,14 +9838,32 @@ function WorkspaceVitestPlugin(project, options) {
9813
9838
  name = options.workspacePath.toString();
9814
9839
  }
9815
9840
  }
9841
+ const workspaceNames = [name];
9842
+ if (viteConfig.test?.browser?.enabled) {
9843
+ if (viteConfig.test.browser.name) {
9844
+ const browser = viteConfig.test.browser.name;
9845
+ workspaceNames.push(name ? `${name} (${browser})` : browser);
9846
+ }
9847
+ viteConfig.test.browser.instances?.forEach((instance) => {
9848
+ instance.name ??= name ? `${name} (${instance.browser})` : instance.browser;
9849
+ workspaceNames.push(instance.name);
9850
+ });
9851
+ }
9852
+ const filters = project.vitest.config.project;
9853
+ if (filters.length) {
9854
+ const hasProject = workspaceNames.some((name2) => {
9855
+ return project.vitest._matchesProjectFilter(name2);
9856
+ });
9857
+ if (!hasProject) {
9858
+ throw new VitestFilteredOutProjectError();
9859
+ }
9860
+ }
9861
+ const resolveOptions = getDefaultResolveOptions();
9816
9862
  const config = {
9817
9863
  root,
9818
9864
  resolve: {
9819
- // by default Vite resolves `module` field, which not always a native ESM module
9820
- // setting this option can bypass that and fallback to cjs version
9821
- mainFields: [],
9822
- alias: testConfig.alias,
9823
- conditions: ["node"]
9865
+ ...resolveOptions,
9866
+ alias: testConfig.alias
9824
9867
  },
9825
9868
  esbuild: viteConfig.esbuild === false ? false : {
9826
9869
  // Lowest target Vitest supports is Node18
@@ -9841,7 +9884,7 @@ function WorkspaceVitestPlugin(project, options) {
9841
9884
  fs: {
9842
9885
  allow: resolveFsAllow(
9843
9886
  project.vitest.config.root,
9844
- project.vitest.server.config.configFile
9887
+ project.vitest.vite.config.configFile
9845
9888
  )
9846
9889
  }
9847
9890
  },
@@ -9849,12 +9892,7 @@ function WorkspaceVitestPlugin(project, options) {
9849
9892
  // @ts-ignore Vite 6 compat
9850
9893
  environments: {
9851
9894
  ssr: {
9852
- resolve: {
9853
- // by default Vite resolves `module` field, which not always a native ESM module
9854
- // setting this option can bypass that and fallback to cjs version
9855
- mainFields: [],
9856
- conditions: ["node"]
9857
- }
9895
+ resolve: resolveOptions
9858
9896
  }
9859
9897
  },
9860
9898
  test: {
@@ -9878,7 +9916,7 @@ function WorkspaceVitestPlugin(project, options) {
9878
9916
  }
9879
9917
  }
9880
9918
  config.customLogger = createViteLogger(
9881
- project.logger,
9919
+ project.vitest.logger,
9882
9920
  viteConfig.logLevel || "warn",
9883
9921
  {
9884
9922
  allowClearScreen: false
@@ -10288,7 +10326,7 @@ class TestProject {
10288
10326
  ignore: exclude
10289
10327
  };
10290
10328
  const files = await fg(include, globOptions);
10291
- return files.map((file) => slash(a.resolve(cwd, file)));
10329
+ return files.map((file) => slash(p.resolve(cwd, file)));
10292
10330
  }
10293
10331
  /**
10294
10332
  * Test if a file matches the test globs. This does the actual glob matching if the test is not cached, unlike `isCachedTestFile`.
@@ -10418,13 +10456,12 @@ class TestProject {
10418
10456
  /** @internal */
10419
10457
  async _configureServer(options, server) {
10420
10458
  this._config = resolveConfig(
10421
- this.vitest.mode,
10459
+ this.vitest,
10422
10460
  {
10423
10461
  ...options,
10424
10462
  coverage: this.vitest.config.coverage
10425
10463
  },
10426
- server.config,
10427
- this.vitest.logger
10464
+ server.config
10428
10465
  );
10429
10466
  for (const _providedKey in this.config.provide) {
10430
10467
  const providedKey = _providedKey;
@@ -11726,7 +11763,10 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
11726
11763
  });
11727
11764
  for (const path of fileProjects) {
11728
11765
  if (vitest.vite.config.configFile === path) {
11729
- projectPromises.push(Promise.resolve(vitest._ensureRootProject()));
11766
+ const project = getDefaultTestProject(vitest);
11767
+ if (project) {
11768
+ projectPromises.push(Promise.resolve(project));
11769
+ }
11730
11770
  continue;
11731
11771
  }
11732
11772
  const configFile = path.endsWith("/") ? false : path;
@@ -11740,10 +11780,34 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
11740
11780
  );
11741
11781
  }
11742
11782
  if (!projectPromises.length) {
11743
- return resolveBrowserWorkspace(vitest, /* @__PURE__ */ new Set(), [vitest._ensureRootProject()]);
11783
+ throw new Error(
11784
+ [
11785
+ "No projects were found. Make sure your configuration is correct. ",
11786
+ vitest.config.project.length ? `The filter matched no projects: ${vitest.config.project.join(", ")}. ` : "",
11787
+ `The workspace: ${JSON.stringify(workspaceDefinition, null, 4)}.`
11788
+ ].join("")
11789
+ );
11744
11790
  }
11745
- const resolvedProjects = await Promise.all(projectPromises);
11791
+ const resolvedProjectsPromises = await Promise.allSettled(projectPromises);
11746
11792
  const names = /* @__PURE__ */ new Set();
11793
+ const errors = [];
11794
+ const resolvedProjects = [];
11795
+ for (const result of resolvedProjectsPromises) {
11796
+ if (result.status === "rejected") {
11797
+ if (result.reason instanceof VitestFilteredOutProjectError) {
11798
+ continue;
11799
+ }
11800
+ errors.push(result.reason);
11801
+ } else {
11802
+ resolvedProjects.push(result.value);
11803
+ }
11804
+ }
11805
+ if (errors.length) {
11806
+ throw new AggregateError(
11807
+ errors,
11808
+ "Failed to initialize projects. There were errors during workspace setup. See below for more details."
11809
+ );
11810
+ }
11747
11811
  for (const project of resolvedProjects) {
11748
11812
  const name = project.name;
11749
11813
  if (names.has(name)) {
@@ -11767,15 +11831,18 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
11767
11831
  return resolveBrowserWorkspace(vitest, names, resolvedProjects);
11768
11832
  }
11769
11833
  async function resolveBrowserWorkspace(vitest, names, resolvedProjects) {
11770
- const filters = toArray(vitest.config.project).map((s) => wildcardPatternToRegExp(s));
11771
11834
  const removeProjects = /* @__PURE__ */ new Set();
11772
11835
  resolvedProjects.forEach((project) => {
11773
11836
  if (!project.config.browser.enabled) {
11774
11837
  return;
11775
11838
  }
11776
- const configs = project.config.browser.instances || [];
11777
- if (configs.length === 0) {
11778
- configs.push({ browser: project.config.browser.name });
11839
+ const instances = project.config.browser.instances || [];
11840
+ if (instances.length === 0) {
11841
+ const browser = project.config.browser.name;
11842
+ instances.push({
11843
+ browser,
11844
+ name: project.name ? `${project.name} (${browser})` : browser
11845
+ });
11779
11846
  console.warn(
11780
11847
  withLabel(
11781
11848
  "yellow",
@@ -11791,12 +11858,12 @@ async function resolveBrowserWorkspace(vitest, names, resolvedProjects) {
11791
11858
  );
11792
11859
  }
11793
11860
  const originalName = project.config.name;
11794
- const filteredConfigs = !filters.length ? configs : configs.filter((config) => {
11795
- const browser = config.browser;
11796
- const newName = config.name || (originalName ? `${originalName} (${browser})` : browser);
11797
- return filters.some((pattern) => pattern.test(newName));
11861
+ const filteredInstances = !vitest._projectFilters.length || vitest._matchesProjectFilter(originalName) ? instances : instances.filter((instance) => {
11862
+ const newName = instance.name;
11863
+ return vitest._matchesProjectFilter(newName);
11798
11864
  });
11799
- if (!filteredConfigs.length) {
11865
+ if (!filteredInstances.length) {
11866
+ removeProjects.add(project);
11800
11867
  return;
11801
11868
  }
11802
11869
  if (project.config.browser.providerOptions) {
@@ -11804,7 +11871,7 @@ async function resolveBrowserWorkspace(vitest, names, resolvedProjects) {
11804
11871
  withLabel("yellow", "Vitest", `"providerOptions"${originalName ? ` in "${originalName}" project` : ""} is ignored because it's overriden by the configs. To hide this warning, remove the "providerOptions" property from the browser configuration.`)
11805
11872
  );
11806
11873
  }
11807
- filteredConfigs.forEach((config, index) => {
11874
+ filteredInstances.forEach((config, index) => {
11808
11875
  const browser = config.browser;
11809
11876
  if (!browser) {
11810
11877
  const nth = index + 1;
@@ -11812,19 +11879,21 @@ async function resolveBrowserWorkspace(vitest, names, resolvedProjects) {
11812
11879
  throw new Error(`The browser configuration must have a "browser" property. The ${nth}${ending} item in "browser.instances" doesn't have it. Make sure your${originalName ? ` "${originalName}"` : ""} configuration is correct.`);
11813
11880
  }
11814
11881
  const name = config.name;
11815
- const newName = name || (originalName ? `${originalName} (${browser})` : browser);
11816
- if (names.has(newName)) {
11882
+ if (name == null) {
11883
+ throw new Error(`The browser configuration must have a "name" property. This is a bug in Vitest. Please, open a new issue with reproduction`);
11884
+ }
11885
+ if (names.has(name)) {
11817
11886
  throw new Error(
11818
11887
  [
11819
- `Cannot define a nested project for a ${browser} browser. The project name "${newName}" was already defined. `,
11888
+ `Cannot define a nested project for a ${browser} browser. The project name "${name}" was already defined. `,
11820
11889
  'If you have multiple instances for the same browser, make sure to define a custom "name". ',
11821
11890
  "All projects in a workspace should have unique names. Make sure your configuration is correct."
11822
11891
  ].join("")
11823
11892
  );
11824
11893
  }
11825
- names.add(newName);
11894
+ names.add(name);
11826
11895
  const clonedConfig = cloneConfig(project, config);
11827
- clonedConfig.name = newName;
11896
+ clonedConfig.name = name;
11828
11897
  const clone = TestProject._cloneBrowserProject(project, clonedConfig);
11829
11898
  resolvedProjects.push(clone);
11830
11899
  });
@@ -11842,7 +11911,7 @@ async function resolveBrowserWorkspace(vitest, names, resolvedProjects) {
11842
11911
  if (!isTTY) {
11843
11912
  throw new Error(`${message} Please, filter projects with --browser=name or --project=name flag or run tests with "headless: true" option.`);
11844
11913
  }
11845
- const prompts = await import('./index.Bh7wTRhh.js').then(function (n) { return n.i; });
11914
+ const prompts = await import('./index.B57_6XMC.js').then(function (n) { return n.i; });
11846
11915
  const { projectName } = await prompts.default({
11847
11916
  type: "select",
11848
11917
  name: "projectName",
@@ -11983,6 +12052,29 @@ async function resolveDirectoryConfig(directory) {
11983
12052
  }
11984
12053
  return null;
11985
12054
  }
12055
+ function getDefaultTestProject(vitest) {
12056
+ const filter = vitest.config.project;
12057
+ const project = vitest._ensureRootProject();
12058
+ if (!filter.length) {
12059
+ return project;
12060
+ }
12061
+ const hasProjects = getPotentialProjectNames(project).some(
12062
+ (p) => vitest._matchesProjectFilter(p)
12063
+ );
12064
+ if (hasProjects) {
12065
+ return project;
12066
+ }
12067
+ return null;
12068
+ }
12069
+ function getPotentialProjectNames(project) {
12070
+ const names = [project.name];
12071
+ if (project.config.browser.instances) {
12072
+ names.push(...project.config.browser.instances.map((i) => i.name));
12073
+ } else if (project.config.browser.name) {
12074
+ names.push(project.config.browser.name);
12075
+ }
12076
+ return names;
12077
+ }
11986
12078
 
11987
12079
  const WATCHER_DEBOUNCE = 100;
11988
12080
  class Vitest {
@@ -12040,7 +12132,10 @@ class Vitest {
12040
12132
  isCancelling = false;
12041
12133
  /** @internal */
12042
12134
  coreWorkspaceProject;
12043
- /** @internal */
12135
+ /**
12136
+ * @internal
12137
+ * @deprecated
12138
+ */
12044
12139
  resolvedProjects = [];
12045
12140
  /** @internal */
12046
12141
  _browserLastPort = defaultBrowserPort;
@@ -12056,6 +12151,8 @@ class Vitest {
12056
12151
  runner = undefined;
12057
12152
  /** @internal */
12058
12153
  _testRun = undefined;
12154
+ /** @internal */
12155
+ _projectFilters = [];
12059
12156
  isFirstRun = true;
12060
12157
  restartsCount = 0;
12061
12158
  specifications;
@@ -12143,8 +12240,9 @@ class Vitest {
12143
12240
  this.coreWorkspaceProject = undefined;
12144
12241
  this.specifications.clearCache();
12145
12242
  this._onUserTestsRerun = [];
12146
- const resolved = resolveConfig(this.mode, options, server.config, this.logger);
12243
+ this._projectFilters = toArray(options.project || []).map((project) => wildcardPatternToRegExp(project));
12147
12244
  this._vite = server;
12245
+ const resolved = resolveConfig(this, options, server.config);
12148
12246
  this._config = resolved;
12149
12247
  this._state = new StateManager();
12150
12248
  this._cache = new VitestCache(this.version);
@@ -12192,14 +12290,8 @@ class Vitest {
12192
12290
  const projects = await this.resolveWorkspace(cliOptions);
12193
12291
  this.resolvedProjects = projects;
12194
12292
  this.projects = projects;
12195
- const filters = toArray(resolved.project).map((s) => wildcardPatternToRegExp(s));
12196
- if (filters.length > 0) {
12197
- this.projects = this.projects.filter(
12198
- (p) => filters.some((pattern) => pattern.test(p.name))
12199
- );
12200
- if (!this.projects.length) {
12201
- throw new Error(`No projects matched the filter "${toArray(resolved.project).join('", "')}".`);
12202
- }
12293
+ if (!this.projects.length) {
12294
+ throw new Error(`No projects matched the filter "${toArray(resolved.project).join('", "')}".`);
12203
12295
  }
12204
12296
  if (!this.coreWorkspaceProject) {
12205
12297
  this.coreWorkspaceProject = TestProject._createBasicProject(this);
@@ -12291,7 +12383,11 @@ class Vitest {
12291
12383
  const workspaceConfigPath = await this.resolveWorkspaceConfigPath();
12292
12384
  this._workspaceConfigPath = workspaceConfigPath;
12293
12385
  if (!workspaceConfigPath) {
12294
- return resolveBrowserWorkspace(this, /* @__PURE__ */ new Set(), [this._ensureRootProject()]);
12386
+ const project = getDefaultTestProject(this);
12387
+ if (!project) {
12388
+ return [];
12389
+ }
12390
+ return resolveBrowserWorkspace(this, /* @__PURE__ */ new Set(), [project]);
12295
12391
  }
12296
12392
  const workspaceModule = await this.import(workspaceConfigPath);
12297
12393
  if (!workspaceModule.default || !Array.isArray(workspaceModule.default)) {
@@ -12644,13 +12740,13 @@ class Vitest {
12644
12740
  /** @internal */
12645
12741
  async changeProjectName(pattern) {
12646
12742
  if (pattern === "") {
12647
- delete this.configOverride.project;
12743
+ this.configOverride.project = undefined;
12744
+ this._projectFilters = [];
12648
12745
  } else {
12649
- this.configOverride.project = pattern;
12746
+ this.configOverride.project = [pattern];
12747
+ this._projectFilters = [wildcardPatternToRegExp(pattern)];
12650
12748
  }
12651
- this.projects = this.resolvedProjects.filter((p) => p.name === pattern);
12652
- const files = (await this.globTestSpecifications()).map((spec) => spec.moduleId);
12653
- await this.rerunFiles(files, "change project filter", pattern === "");
12749
+ await this.vite.restart();
12654
12750
  }
12655
12751
  /** @internal */
12656
12752
  async changeNamePattern(pattern, files = this.state.getFilepaths(), trigger) {
@@ -12958,6 +13054,16 @@ class Vitest {
12958
13054
  onAfterSetServer(fn) {
12959
13055
  this._onSetServer.push(fn);
12960
13056
  }
13057
+ /**
13058
+ * Check if the project with a given name should be included.
13059
+ * @internal
13060
+ */
13061
+ _matchesProjectFilter(name) {
13062
+ if (!this._projectFilters.length) {
13063
+ return true;
13064
+ }
13065
+ return this._projectFilters.some((filter) => filter.test(name));
13066
+ }
12961
13067
  }
12962
13068
  function assert(condition, property, name = property) {
12963
13069
  if (!condition) {
@@ -12995,6 +13101,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
12995
13101
  if (testConfig.ui && testConfig.open) {
12996
13102
  open = testConfig.uiBase ?? "/__vitest__/";
12997
13103
  }
13104
+ const resolveOptions = getDefaultResolveOptions();
12998
13105
  const config = {
12999
13106
  root: viteConfig.test?.root || options.root,
13000
13107
  esbuild: viteConfig.esbuild === false ? false : {
@@ -13005,11 +13112,8 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
13005
13112
  legalComments: "inline"
13006
13113
  },
13007
13114
  resolve: {
13008
- // by default Vite resolves `module` field, which not always a native ESM module
13009
- // setting this option can bypass that and fallback to cjs version
13010
- mainFields: [],
13011
- alias: testConfig.alias,
13012
- conditions: ["node"]
13115
+ ...resolveOptions,
13116
+ alias: testConfig.alias
13013
13117
  },
13014
13118
  server: {
13015
13119
  ...testConfig.api,
@@ -13034,12 +13138,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
13034
13138
  // @ts-ignore Vite 6 compat
13035
13139
  environments: {
13036
13140
  ssr: {
13037
- resolve: {
13038
- // by default Vite resolves `module` field, which not always a native ESM module
13039
- // setting this option can bypass that and fallback to cjs version
13040
- mainFields: [],
13041
- conditions: ["node"]
13042
- }
13141
+ resolve: resolveOptions
13043
13142
  }
13044
13143
  },
13045
13144
  test: {
@@ -13055,6 +13154,9 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
13055
13154
  deps: testConfig.deps ?? viteConfig.test?.deps
13056
13155
  }
13057
13156
  };
13157
+ if (ctx.configOverride.project) {
13158
+ options.project = ctx.configOverride.project;
13159
+ }
13058
13160
  config.customLogger = createViteLogger(
13059
13161
  ctx.logger,
13060
13162
  viteConfig.logLevel || "warn",
@@ -13125,6 +13227,12 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
13125
13227
  enumerable: false,
13126
13228
  configurable: true
13127
13229
  });
13230
+ const originalName = options.name;
13231
+ if (options.browser?.enabled && options.browser?.instances) {
13232
+ options.browser.instances.forEach((instance) => {
13233
+ instance.name ??= originalName ? `${originalName} (${instance.browser})` : instance.browser;
13234
+ });
13235
+ }
13128
13236
  },
13129
13237
  configureServer: {
13130
13238
  // runs after vite:import-analysis as it relies on `server` instance on Vite 5
@@ -13471,7 +13579,7 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout2) {
13471
13579
  name: "filter",
13472
13580
  type: "text",
13473
13581
  message: "Input a single project name",
13474
- initial: toArray(ctx.configOverride.project)[0] || ""
13582
+ initial: ctx.config.project[0] || ""
13475
13583
  }
13476
13584
  ]);
13477
13585
  on();
@@ -1,8 +1,8 @@
1
1
  import { existsSync, writeFileSync, readFileSync } from 'node:fs';
2
2
  import { mkdir, writeFile } from 'node:fs/promises';
3
3
  import { resolve, dirname, relative } from 'node:path';
4
- import { detectPackageManager, installPackage } from './index.DfqWks-F.js';
5
- import { p as prompt, f as findUp } from './index.Bh7wTRhh.js';
4
+ import { detectPackageManager, installPackage } from './index.NxxmQyK2.js';
5
+ import { p as prompt, f as findUp } from './index.B57_6XMC.js';
6
6
  import { x } from 'tinyexec';
7
7
  import c from 'tinyrainbow';
8
8
  import { c as configFiles } from './constants.fzPh7AOq.js';
@@ -21,7 +21,7 @@ function normalizeWindowsPath(input = "") {
21
21
  const _UNC_REGEX = /^[/\\]{2}/;
22
22
  const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
23
23
  const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
24
- const _EXTNAME_RE = /.(\.[^./]+)$/;
24
+ const _EXTNAME_RE = /.(\.[^./]+|\.)$/;
25
25
  const normalize = function(path) {
26
26
  if (path.length === 0) {
27
27
  return ".";
@@ -160,6 +160,7 @@ const isAbsolute = function(p) {
160
160
  return _IS_ABSOLUTE_RE.test(p);
161
161
  };
162
162
  const extname = function(p) {
163
+ if (p === "..") return "";
163
164
  const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
164
165
  return match && match[1] || "";
165
166
  };
@@ -1,4 +1,4 @@
1
- import a from 'node:path';
1
+ import p from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import process$1 from 'node:process';
4
4
  import { promises } from 'node:fs';
@@ -237,7 +237,7 @@ async function locatePath(
237
237
 
238
238
  return pLocate(paths, async path_ => {
239
239
  try {
240
- const stat = await statFunction(a.resolve(cwd, path_));
240
+ const stat = await statFunction(p.resolve(cwd, path_));
241
241
  return matchType(type, stat);
242
242
  } catch {
243
243
  return false;
@@ -250,9 +250,9 @@ const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath)
250
250
  const findUpStop = Symbol('findUpStop');
251
251
 
252
252
  async function findUpMultiple(name, options = {}) {
253
- let directory = a.resolve(toPath(options.cwd) || '');
254
- const {root} = a.parse(directory);
255
- const stopAt = a.resolve(directory, options.stopAt || root);
253
+ let directory = p.resolve(toPath(options.cwd) || '');
254
+ const {root} = p.parse(directory);
255
+ const stopAt = p.resolve(directory, options.stopAt || root);
256
256
  const limit = options.limit || Number.POSITIVE_INFINITY;
257
257
  const paths = [name].flat();
258
258
 
@@ -280,14 +280,14 @@ async function findUpMultiple(name, options = {}) {
280
280
  }
281
281
 
282
282
  if (foundPath) {
283
- matches.push(a.resolve(directory, foundPath));
283
+ matches.push(p.resolve(directory, foundPath));
284
284
  }
285
285
 
286
286
  if (directory === stopAt || matches.length >= limit) {
287
287
  break;
288
288
  }
289
289
 
290
- directory = a.dirname(directory);
290
+ directory = p.dirname(directory);
291
291
  }
292
292
 
293
293
  return matches;