diff --git a/README.md b/README.md
index e6431ffc6..050ceb9c3 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ Next generation testing framework powered by Vite.
- Components testing ([Vue](https://github.com/vitest-tests/browser-examples/tree/main/examples/vue), [React](https://github.com/vitest-tests/browser-examples/tree/main/examples/react), [Svelte](https://github.com/vitest-tests/browser-examples/tree/main/examples/svelte), [Lit](./examples/lit), [Marko](https://github.com/marko-js/examples/tree/master/examples/library-ts))
- Workers multi-threading via [Tinypool](https://github.com/tinylibs/tinypool) (a lightweight fork of [Piscina](https://github.com/piscinajs/piscina))
- Benchmarking support with [Tinybench](https://github.com/tinylibs/tinybench)
-- [Workspace](https://vitest.dev/guide/workspace) support
+- [Projects](https://vitest.dev/guide/projects) support
- [expect-type](https://github.com/mmkal/expect-type) for type-level testing
- ESM first, top level await
- Out-of-box TypeScript / JSX support
diff --git a/docs/.vitepress/components/FeaturesList.vue b/docs/.vitepress/components/FeaturesList.vue
index 81be1d95d..d77ef6232 100644
--- a/docs/.vitepress/components/FeaturesList.vue
+++ b/docs/.vitepress/components/FeaturesList.vue
@@ -13,7 +13,7 @@
Workers multi-threading via Tinypool
Benchmarking support with Tinybench
Filtering, timeouts, concurrent for suite and tests
- Workspace support
+ Projects support
Jest-compatible Snapshot
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
index 12f617a12..d1dfecc06 100644
--- a/docs/.vitepress/config.ts
+++ b/docs/.vitepress/config.ts
@@ -477,8 +477,8 @@ function guide(): DefaultTheme.SidebarItem[] {
link: '/guide/filtering',
},
{
- text: 'Workspace',
- link: '/guide/workspace',
+ text: 'Test Projects',
+ link: '/guide/projects',
},
{
text: 'Reporters',
diff --git a/docs/advanced/api/index.md b/docs/advanced/api/index.md
index 8e6ab4cdf..b1e8b1b14 100644
--- a/docs/advanced/api/index.md
+++ b/docs/advanced/api/index.md
@@ -119,7 +119,7 @@ If you pass down the config to the `startVitest` or `createVitest` APIs, Vitest
:::
::: warning
-The `resolveConfig` doesn't resolve the `workspace`. To resolve workspace configs, Vitest needs an established Vite server.
+The `resolveConfig` doesn't resolve `projects`. To resolve projects configs, Vitest needs an established Vite server.
Also note that `viteConfig.test` will not be fully resolved. If you need Vitest config, use `vitestConfig` instead.
:::
diff --git a/docs/advanced/api/plugin.md b/docs/advanced/api/plugin.md
index 6943b5500..039f9a9e1 100644
--- a/docs/advanced/api/plugin.md
+++ b/docs/advanced/api/plugin.md
@@ -53,7 +53,7 @@ Vitest re-exports all Vite type-only imports via a `Vite` namespace, which you c
```
:::
-Unlike [`reporter.onInit`](/advanced/api/reporters#oninit), this hooks runs early in Vitest lifecycle allowing you to make changes to configuration like `coverage` and `reporters`. A more notable change is that you can manipulate the global config from a [workspace project](/guide/workspace) if your plugin is defined in the project and not in the global config.
+Unlike [`reporter.onInit`](/advanced/api/reporters#oninit), this hooks runs early in Vitest lifecycle allowing you to make changes to configuration like `coverage` and `reporters`. A more notable change is that you can manipulate the global config from a [test project](/guide/projects) if your plugin is defined in the project and not in the global config.
## Context
@@ -107,7 +107,7 @@ const newProjects = await injectTestProjects({
```
::: warning Projects are Filtered
-Vitest filters projects during the config resolution, so if the user defined a filter, injected project might not be resolved unless it [matches the filter](./vitest#matchesprojectfilter). You can update the filter via the `vitest.config.project` option to always include your workspace project:
+Vitest filters projects during the config resolution, so if the user defined a filter, injected project might not be resolved unless it [matches the filter](./vitest#matchesprojectfilter). You can update the filter via the `vitest.config.project` option to always include your test project:
```ts
vitest.config.project.push('my-project-name')
diff --git a/docs/advanced/api/test-project.md b/docs/advanced/api/test-project.md
index 9cfc7d39e..d1a2f4f97 100644
--- a/docs/advanced/api/test-project.md
+++ b/docs/advanced/api/test-project.md
@@ -4,10 +4,8 @@ title: TestProject
# TestProject 3.0.0 {#testproject}
-- **Alias**: `WorkspaceProject` before 3.0.0
-
::: warning
-This guide describes the advanced Node.js API. If you just want to create a workspace, follow the ["Workspace"](/guide/workspace) guide.
+This guide describes the advanced Node.js API. If you just want to define projects, follow the ["Test Projects"](/guide/projects) guide.
:::
## name
@@ -26,28 +24,34 @@ vitest.projects.map(p => p.name) === [
'custom'
]
```
-```ts [vitest.workspace.js]
-export default [
- './packages/server', // has package.json with "@pkg/server"
- './utils', // doesn't have a package.json file
- {
- // doesn't customize the name
- test: {
- pool: 'threads',
- },
+```ts [vitest.config.js]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ './packages/server', // has package.json with "@pkg/server"
+ './utils', // doesn't have a package.json file
+ {
+ // doesn't customize the name
+ test: {
+ pool: 'threads',
+ },
+ },
+ {
+ // customized the name
+ test: {
+ name: 'custom',
+ },
+ },
+ ],
},
- {
- // customized the name
- test: {
- name: 'custom',
- },
- },
-]
+})
```
:::
::: info
-If the [root project](/advanced/api/vitest#getroottestproject) is not part of a user workspace, its `name` will not be resolved.
+If the [root project](/advanced/api/vitest#getroottestproject) is not part of user projects, its `name` will not be resolved.
:::
## vitest
@@ -279,7 +283,7 @@ dynamicExample !== staticExample // ✅
:::
::: info
-Internally, Vitest uses this method to import global setups, custom coverage providers, workspace file, and custom reporters, meaning all of them share the same module graph as long as they belong to the same Vite server.
+Internally, Vitest uses this method to import global setups, custom coverage providers and custom reporters, meaning all of them share the same module graph as long as they belong to the same Vite server.
:::
## onTestsRerun
diff --git a/docs/advanced/api/vitest.md b/docs/advanced/api/vitest.md
index 5933d6371..4db4337db 100644
--- a/docs/advanced/api/vitest.md
+++ b/docs/advanced/api/vitest.md
@@ -64,7 +64,7 @@ Benchmark mode calls `bench` functions and throws an error, when it encounters `
## config
-The root (or global) config. If workspace feature is enabled, projects will reference this as `globalConfig`.
+The root (or global) config. If projects are defined, they will reference this as `globalConfig`.
::: warning
This is Vitest config, it doesn't extend _Vite_ config. It only has resolved values from the `test` property.
@@ -101,9 +101,9 @@ Cache manager that stores information about latest test results and test file st
## projects
-An array of [test projects](/advanced/api/test-project) that belong to the user's workspace. If the user did not specify a custom workspace, the workspace will only have a [root project](#getrootproject).
+An array of [test projects](/advanced/api/test-project) that belong to user's projects. If the user did not specify a them, this array will only contain a [root project](#getrootproject).
-Vitest will ensure that there is always at least one project in the workspace. If the user specifies a non-existent `--project` name, Vitest will throw an error.
+Vitest will ensure that there is always at least one project in this array. If the user specifies a non-existent `--project` name, Vitest will throw an error before this array is defined.
## getRootProject
@@ -111,7 +111,7 @@ Vitest will ensure that there is always at least one project in the workspace. I
function getRootProject(): TestProject
```
-This returns the root test project. The root project generally doesn't run any tests and is not included in `vitest.projects` unless the user explicitly includes the root config in their workspace, or the workspace is not defined at all.
+This returns the root test project. The root project generally doesn't run any tests and is not included in `vitest.projects` unless the user explicitly includes the root config in their configuration, or projects are not defined at all.
The primary goal of the root project is to setup the global config. In fact, `rootProject.config` references `rootProject.globalConfig` and `vitest.config` directly:
@@ -433,7 +433,7 @@ dynamicExample !== staticExample // ✅
:::
::: info
-Internally, Vitest uses this method to import global setups, custom coverage providers, workspace file, and custom reporters, meaning all of them share the same module graph as long as they belong to the same Vite server.
+Internally, Vitest uses this method to import global setups, custom coverage providers, and custom reporters, meaning all of them share the same module graph as long as they belong to the same Vite server.
:::
## close
diff --git a/docs/advanced/pool.md b/docs/advanced/pool.md
index 35b0cfeeb..0485164bd 100644
--- a/docs/advanced/pool.md
+++ b/docs/advanced/pool.md
@@ -31,12 +31,12 @@ export default defineConfig({
})
```
-If you need to run tests in different pools, use the [workspace](/guide/workspace) feature:
+If you need to run tests in different pools, use the [`projects`](/guide/projects) feature:
```ts [vitest.config.ts]
export default defineConfig({
test: {
- workspace: [
+ projects: [
{
extends: true,
test: {
@@ -48,10 +48,6 @@ export default defineConfig({
})
```
-::: info
-The `workspace` field was introduced in Vitest 3. To define a workspace in [Vitest 2](https://v2.vitest.dev/), create a separate `vitest.workspace.ts` file.
-:::
-
## API
The file specified in `pool` option should export a function (can be async) that accepts `Vitest` interface as its first option. This function needs to return an object matching `ProcessPool` interface:
@@ -69,7 +65,7 @@ export interface ProcessPool {
The function is called only once (unless the server config was updated), and it's generally a good idea to initialize everything you need for tests inside that function and reuse it when `runTests` is called.
-Vitest calls `runTest` when new tests are scheduled to run. It will not call it if `files` is empty. The first argument is an array of [TestSpecifications](/advanced/api/test-specification). Files are sorted using [`sequencer`](/config/#sequence-sequencer) before `runTests` is called. It's possible (but unlikely) to have the same file twice, but it will always have a different project - this is implemented via [`vitest.workspace.ts`](/guide/workspace) configuration.
+Vitest calls `runTest` when new tests are scheduled to run. It will not call it if `files` is empty. The first argument is an array of [TestSpecifications](/advanced/api/test-specification). Files are sorted using [`sequencer`](/config/#sequence-sequencer) before `runTests` is called. It's possible (but unlikely) to have the same file twice, but it will always have a different project - this is implemented via [`projects`](/guide/projects) configuration.
Vitest will wait until `runTests` is executed before finishing a run (i.e., it will emit [`onFinished`](/advanced/reporters) only after `runTests` is resolved).
diff --git a/docs/advanced/runner.md b/docs/advanced/runner.md
index 9ff366a94..5fbd5a5f2 100644
--- a/docs/advanced/runner.md
+++ b/docs/advanced/runner.md
@@ -164,7 +164,7 @@ interface File extends Suite {
*/
filepath: string
/**
- * The name of the workspace project the file belongs to.
+ * The name of the test project the file belongs to.
*/
projectName: string | undefined
/**
diff --git a/docs/blog/vitest-3.md b/docs/blog/vitest-3.md
index 25c27a508..455f6589f 100644
--- a/docs/blog/vitest-3.md
+++ b/docs/blog/vitest-3.md
@@ -72,7 +72,7 @@ You can follow the design process in [#7069](https://github.com/vitest-dev/vites
## Inline Workspace
-Rejoice! No more separate files to define your [workspace](/guide/workspace) - specify an array of projects using the `workspace` field in your `vitest.config` file:
+Rejoice! No more separate files to define your [workspace](/guide/projects) - specify an array of projects using the `workspace` field in your `vitest.config` file:
```jsx
import { defineConfig } from 'vitest/config'
diff --git a/docs/config/index.md b/docs/config/index.md
index 2512097f5..dfe225fc4 100644
--- a/docs/config/index.md
+++ b/docs/config/index.md
@@ -106,7 +106,7 @@ export default defineConfig({
Since Vitest uses Vite config, you can also use any configuration option from [Vite](https://vitejs.dev/config/). For example, `define` to define global variables, or `resolve.alias` to define aliases - these options should be defined on the top level, _not_ within a `test` property.
-Configuration options that are not supported inside a [workspace](/guide/workspace) project config have sign next to them. This means they can only be set in the root Vitest config.
+Configuration options that are not supported inside a [project](/guide/projects) config have sign next to them. This means they can only be set in the root Vitest config.
:::
### include
@@ -588,7 +588,7 @@ These options are passed down to `setup` method of current [`environment`](#envi
- **Default:** `[]`
::: danger DEPRECATED
-This API was deprecated in Vitest 3. Use [workspace](/guide/workspace) to define different configurations instead.
+This API was deprecated in Vitest 3. Use [projects](/guide/projects) to define different configurations instead.
```ts
export default defineConfig({
@@ -596,7 +596,7 @@ export default defineConfig({
environmentMatchGlobs: [ // [!code --]
['./*.jsdom.test.ts', 'jsdom'], // [!code --]
], // [!code --]
- workspace: [ // [!code ++]
+ projects: [ // [!code ++]
{ // [!code ++]
extends: true, // [!code ++]
test: { // [!code ++]
@@ -635,7 +635,7 @@ export default defineConfig({
- **Default:** `[]`
::: danger DEPRECATED
-This API was deprecated in Vitest 3. Use [workspace](/guide/workspace) to define different configurations instead:
+This API was deprecated in Vitest 3. Use [projects](/guide/projects) to define different configurations instead:
```ts
export default defineConfig({
@@ -643,7 +643,7 @@ export default defineConfig({
poolMatchGlobs: [ // [!code --]
['./*.threads.test.ts', 'threads'], // [!code --]
], // [!code --]
- workspace: [ // [!code ++]
+ projects: [ // [!code ++]
{ // [!code ++]
test: { // [!code ++]
extends: true, // [!code ++]
@@ -724,7 +724,7 @@ export default defineConfig({
```
::: warning
-Returned files should be either absolute or relative to the root. Note that this is a global option, and it cannot be used inside of [project](/guide/workspace) configs.
+Returned files should be either absolute or relative to the root. Note that this is a global option, and it cannot be used inside of [project](/guide/projects) configs.
:::
### root
@@ -2436,14 +2436,25 @@ Tells fake timers to clear "native" (i.e. not fake) timers by delegating to thei
### workspace {#workspace}
-- **Type:** `string | TestProjectConfiguration`
+::: danger DEPRECATED
+This options is deprecated and will be removed in the next major. Please, use [`projects`](#projects) instead.
+:::
+
+- **Type:** `string | TestProjectConfiguration[]`
- **CLI:** `--workspace=./file.js`
- **Default:** `vitest.{workspace,projects}.{js,ts,json}` close to the config file or root
-Path to a [workspace](/guide/workspace) config file relative to [root](#root).
+Path to a [workspace](/guide/projects) config file relative to [root](#root).
Since Vitest 3, you can also define the workspace array in the root config. If the `workspace` is defined in the config manually, Vitest will ignore the `vitest.workspace` file in the root.
+### projects {#projects}
+
+- **Type:** `TestProjectConfiguration[]`
+- **Default:** `[]`
+
+An array of [projects](/guide/projects).
+
### isolate
- **Type:** `boolean`
diff --git a/docs/guide/browser/commands.md b/docs/guide/browser/commands.md
index 01478320c..c28cff3de 100644
--- a/docs/guide/browser/commands.md
+++ b/docs/guide/browser/commands.md
@@ -11,7 +11,7 @@ Command is a function that invokes another function on the server and passes dow
### Files Handling
-You can use the `readFile`, `writeFile`, and `removeFile` APIs to handle files in your browser tests. Since Vitest 3.2, all paths are resolved relative to the [project](/guide/workspace) root (which is `process.cwd()`, unless overriden manually). Previously, paths were resolved relative to the test file.
+You can use the `readFile`, `writeFile`, and `removeFile` APIs to handle files in your browser tests. Since Vitest 3.2, all paths are resolved relative to the [project](/guide/projects) root (which is `process.cwd()`, unless overriden manually). Previously, paths were resolved relative to the test file.
By default, Vitest uses `utf-8` encoding but you can override it with options.
diff --git a/docs/guide/browser/index.md b/docs/guide/browser/index.md
index cf1d5806a..2ce7499b3 100644
--- a/docs/guide/browser/index.md
+++ b/docs/guide/browser/index.md
@@ -8,7 +8,7 @@ outline: deep
This page provides information about the experimental browser mode feature in the Vitest API, which allows you to run your tests in the browser natively, providing access to browser globals like window and document. This feature is currently under development, and APIs may change in the future.
::: tip
-If you are looking for documentation for `expect`, `vi` or any general API like workspaces or type testing, refer to the ["Getting Started" guide](/guide/).
+If you are looking for documentation for `expect`, `vi` or any general API like test projects or type testing, refer to the ["Getting Started" guide](/guide/).
:::
@@ -209,44 +209,48 @@ export default defineConfig({
```
:::
-If you need to run some tests using Node-based runner, you can define a [workspace](/guide/workspace) file with separate configurations for different testing strategies:
+If you need to run some tests using Node-based runner, you can define a [`projects`](/guide/projects) option with separate configurations for different testing strategies:
-{#workspace-config}
+{#projects-config}
-```ts [vitest.workspace.ts]
-import { defineWorkspace } from 'vitest/config'
+```ts [vitest.config.ts]
+import { defineConfig } from 'vitest/config'
-export default defineWorkspace([
- {
- test: {
- // an example of file based convention,
- // you don't have to follow it
- include: [
- 'tests/unit/**/*.{test,spec}.ts',
- 'tests/**/*.unit.{test,spec}.ts',
- ],
- name: 'unit',
- environment: 'node',
- },
- },
- {
- test: {
- // an example of file based convention,
- // you don't have to follow it
- include: [
- 'tests/browser/**/*.{test,spec}.ts',
- 'tests/**/*.browser.{test,spec}.ts',
- ],
- name: 'browser',
- browser: {
- enabled: true,
- instances: [
- { browser: 'chromium' },
- ],
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ test: {
+ // an example of file based convention,
+ // you don't have to follow it
+ include: [
+ 'tests/unit/**/*.{test,spec}.ts',
+ 'tests/**/*.unit.{test,spec}.ts',
+ ],
+ name: 'unit',
+ environment: 'node',
+ },
},
- },
+ {
+ test: {
+ // an example of file based convention,
+ // you don't have to follow it
+ include: [
+ 'tests/browser/**/*.{test,spec}.ts',
+ 'tests/**/*.browser.{test,spec}.ts',
+ ],
+ name: 'browser',
+ browser: {
+ enabled: true,
+ instances: [
+ { browser: 'chromium' },
+ ],
+ },
+ },
+ },
+ ],
},
-])
+})
```
## Browser Option Types
diff --git a/docs/guide/browser/multiple-setups.md b/docs/guide/browser/multiple-setups.md
index 5d572ee88..811227f30 100644
--- a/docs/guide/browser/multiple-setups.md
+++ b/docs/guide/browser/multiple-setups.md
@@ -2,7 +2,7 @@
Since Vitest 3, you can specify several different browser setups using the new [`browser.instances`](/guide/browser/config#browser-instances) option.
-The main advantage of using the `browser.instances` over the [workspace](/guide/workspace) is improved caching. Every project will use the same Vite server meaning the file transform and [dependency pre-bundling](https://vite.dev/guide/dep-pre-bundling.html) has to happen only once.
+The main advantage of using the `browser.instances` over the [test projects](/guide/projects) is improved caching. Every project will use the same Vite server meaning the file transform and [dependency pre-bundling](https://vite.dev/guide/dep-pre-bundling.html) has to happen only once.
## Several Browsers
diff --git a/docs/guide/cli-generated.md b/docs/guide/cli-generated.md
index 172c980c7..8db3e449f 100644
--- a/docs/guide/cli-generated.md
+++ b/docs/guide/cli-generated.md
@@ -291,7 +291,7 @@ Override Vite mode (default: `test` or `benchmark`)
- **CLI:** `--workspace `
- **Config:** [workspace](/config/#workspace)
-Path to a workspace configuration file
+[deprecated] Path to a workspace configuration file
### isolate
@@ -360,7 +360,7 @@ Set to true to exit if port is already in use, instead of automatically trying t
- **CLI:** `--browser.provider `
- **Config:** [browser.provider](/guide/browser/config#browser-provider)
-Provider used to run browser tests. Some browsers are only available for specific providers. Can be "webdriverio", "playwright", "preview", or the path to a custom provider. Visit [`browser.provider`](https://vitest.dev/config/#browser-provider) for more information (default: `"preview"`)
+Provider used to run browser tests. Some browsers are only available for specific providers. Can be "webdriverio", "playwright", "preview", or the path to a custom provider. Visit [`browser.provider`](https://vitest.dev/guide/browser/config.html#browser-provider) for more information (default: `"preview"`)
### browser.providerOptions
diff --git a/docs/guide/environment.md b/docs/guide/environment.md
index 878ed48c0..53cf4e3d4 100644
--- a/docs/guide/environment.md
+++ b/docs/guide/environment.md
@@ -22,7 +22,7 @@ The `require` of CSS and assets inside the external dependencies are resolved au
::: warning
"Environments" exist only when running tests in Node.js.
-`browser` is not considered an environment in Vitest. If you wish to run part of your tests using [Browser Mode](/guide/browser/), you can create a [workspace project](/guide/browser/#workspace-config).
+`browser` is not considered an environment in Vitest. If you wish to run part of your tests using [Browser Mode](/guide/browser/), you can create a [test project](/guide/browser/#projects-config).
:::
## Environments for Specific Files
diff --git a/docs/guide/index.md b/docs/guide/index.md
index 5aee7d032..92bac46af 100644
--- a/docs/guide/index.md
+++ b/docs/guide/index.md
@@ -175,17 +175,17 @@ export default defineConfig({
However, we recommend using the same file for both Vite and Vitest, instead of creating two separate files.
:::
-## Workspaces Support
+## Projects Support
-Run different project configurations inside the same project with [Vitest Workspaces](/guide/workspace). You can define a list of files and folders that define your workspace in `vitest.config` file.
+Run different project configurations inside the same project with [Test Projects](/guide/projects). You can define a list of files and folders that define your projects in `vitest.config` file.
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: [
- // you can use a list of glob patterns to define your workspaces
+ projects: [
+ // you can use a list of glob patterns to define your projects
// Vitest expects a list of config files
// or directories where there is a config file
'packages/*',
@@ -261,7 +261,7 @@ Learn more about [IDE Integrations](/guide/ide)
| `sveltekit` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/sveltekit) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/sveltekit?initialPath=__vitest__/) |
| `profiling` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/profiling) | Not Available |
| `typecheck` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/typecheck) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/typecheck?initialPath=__vitest__/) |
-| `workspace` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/workspace) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/workspace?initialPath=__vitest__/) |
+| `projects` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/projects) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/projects?initialPath=__vitest__/) |
## Projects using Vitest
diff --git a/docs/guide/workspace.md b/docs/guide/projects.md
similarity index 52%
rename from docs/guide/workspace.md
rename to docs/guide/projects.md
index 1980bc0e9..2f14d642f 100644
--- a/docs/guide/workspace.md
+++ b/docs/guide/projects.md
@@ -1,92 +1,75 @@
---
-title: Workspace | Guide
+title: Test Projects | Guide
---
-# Workspace
+# Test Projects
::: tip Sample Project
-[GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/workspace) - [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/workspace?initialPath=__vitest__/)
+[GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/projects) - [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/projects?initialPath=__vitest__/)
:::
+::: warning
+This feature is also known as a `workspace`. The `workspace` is deprecated since 3.2 and replaced with the `projects` configuration. They are functionally the same.
+:::
+
Vitest provides a way to define multiple project configurations within a single Vitest process. This feature is particularly useful for monorepo setups but can also be used to run tests with different configurations, such as `resolve.alias`, `plugins`, or `test.browser` and more.
-## Defining a Workspace
+## Defining Projects
-Since Vitest 3, you can define a workspace in your root [config](/config/). In this case, Vitest will ignore the `vitest.workspace` file in the root, if one exists.
+You can define projects in your root [config](/config/):
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: ['packages/*'],
+ projects: ['packages/*'],
},
})
```
-If you are using an older version, a workspace must include `vitest.workspace` or `vitest.projects` file in its root directory (located in the same folder as your root configuration file or working directory if it doesn't exist). Note that `projects` is just an alias and does not change the behavior or semantics of this feature. Vitest supports `ts`, `js`, and `json` extensions for this file.
+Project configurations are inlined configs, files, or glob patterns referencing your projects. For example, if you have a folder named `packages` that contains your projects, you can define an array in your root Vitest config:
-::: tip NAMING
-Please note that this feature is named `workspace`, not `workspaces` (without an "s" at the end).
-:::
-
-A workspace is a list of inlined configs, files, or glob patterns referencing your projects. For example, if you have a folder named `packages` that contains your projects, you can either create a workspace file or define an array in the root config:
-
-:::code-group
-```ts [vitest.config.ts 3.0.0]
+```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: ['packages/*'],
+ projects: ['packages/*'],
},
})
```
-```ts [vitest.workspace.ts]
-export default [
- 'packages/*'
-]
-```
-:::
-Vitest will treat every folder in `packages` as a separate project even if it doesn't have a config file inside. If this glob pattern matches any file it will be considered a Vitest config even if it doesn't have a `vitest` in its name.
+Vitest will treat every folder in `packages` as a separate project even if it doesn't have a config file inside. If this glob pattern matches _any file_, it will be considered a Vitest config even if it doesn't have a `vitest` in its name or has an obscure file extension.
::: warning
-Vitest does not treat the root `vitest.config` file as a workspace project unless it is explicitly specified in the workspace configuration. Consequently, the root configuration will only influence global options such as `reporters` and `coverage`. Note that Vitest will always run certain plugin hooks, like `apply`, `config`, `configResolved` or `configureServer`, specified in the root config file. Vitest also uses the same plugins to execute global setups, workspace files and custom coverage provider.
+Vitest does not treat the root `vitest.config` file as a project unless it is explicitly specified in the configuration. Consequently, the root configuration will only influence global options such as `reporters` and `coverage`. Note that Vitest will always run certain plugin hooks, like `apply`, `config`, `configResolved` or `configureServer`, specified in the root config file. Vitest also uses the same plugins to execute global setups and custom coverage provider.
:::
You can also reference projects with their config files:
-:::code-group
-```ts [vitest.config.ts 3.0.0]
+```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: ['packages/*/vitest.config.{e2e,unit}.ts'],
+ projects: ['packages/*/vitest.config.{e2e,unit}.ts'],
},
})
```
-```ts [vitest.workspace.ts]
-export default [
- 'packages/*/vitest.config.{e2e,unit}.ts'
-]
-```
-:::
This pattern will only include projects with a `vitest.config` file that contains `e2e` or `unit` before the extension.
-You can also define projects using inline configuration. The workspace configuration supports both syntaxes simultaneously.
+You can also define projects using inline configuration. The configuration supports both syntaxes simultaneously.
-:::code-group
-```ts [vitest.config.ts 3.0.0]
+```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: [
+ projects: [
// matches every folder and file inside the `packages` folder
'packages/*',
{
@@ -111,47 +94,12 @@ export default defineConfig({
}
})
```
-```ts [vitest.workspace.ts]
-import { defineWorkspace } from 'vitest/config'
-
-// defineWorkspace provides a nice type hinting DX
-export default defineWorkspace([
- // matches every folder and file inside the `packages` folder
- 'packages/*',
- {
- // add "extends" to merge two configs together
- extends: './vite.config.js',
- test: {
- include: ['tests/**/*.{browser}.test.{ts,js}'],
- // it is recommended to define a name when using inline configs
- name: 'happy-dom',
- environment: 'happy-dom',
- }
- },
- {
- test: {
- include: ['tests/**/*.{node}.test.{ts,js}'],
- name: 'node',
- environment: 'node',
- }
- }
-])
-```
-:::
::: warning
All projects must have unique names; otherwise, Vitest will throw an error. If a name is not provided in the inline configuration, Vitest will assign a number. For project configurations defined with glob syntax, Vitest will default to using the "name" property in the nearest `package.json` file or, if none exists, the folder name.
:::
-If you do not use inline configurations, you can create a small JSON file in your root directory or just specify it in the root config:
-
-```json [vitest.workspace.json]
-[
- "packages/*"
-]
-```
-
-Workspace projects do not support all configuration properties. For better type safety, use the `defineProject` method instead of `defineConfig` within project configuration files:
+Projects do not support all configuration properties. For better type safety, use the `defineProject` method instead of `defineConfig` within project configuration files:
```ts twoslash [packages/a/vitest.config.ts]
// @errors: 2769
@@ -169,7 +117,7 @@ export default defineProject({
## Running tests
-To run tests inside the workspace, define a script in your root `package.json`:
+To run tests, define a script in your root `package.json`:
```json [package.json]
{
@@ -233,7 +181,7 @@ bun run test --project e2e --project unit
## Configuration
-None of the configuration options are inherited from the root-level config file, even if the workspace is defined inside that config and not in a separate `vitest.workspace` file. You can create a shared config file and merge it with the project config yourself:
+None of the configuration options are inherited from the root-level config file. You can create a shared config file and merge it with the project config yourself:
```ts [packages/a/vitest.config.ts]
import { defineProject, mergeConfig } from 'vitest/config'
@@ -249,10 +197,9 @@ export default mergeConfig(
)
```
-Additionally, at the `defineWorkspace` level, you can use the `extends` option to inherit from your root-level configuration. All options will be merged.
+Additionally, you can use the `extends` option to inherit from your root-level configuration. All options will be merged.
-::: code-group
-```ts [vitest.config.ts 3.0.0]
+```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
@@ -260,7 +207,7 @@ export default defineConfig({
plugins: [react()],
test: {
pool: 'threads',
- workspace: [
+ projects: [
{
// will inherit options from this config like plugins and pool
extends: true,
@@ -282,32 +229,11 @@ export default defineConfig({
},
})
```
-```ts [vitest.workspace.ts]
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- {
- extends: './vitest.config.ts',
- test: {
- name: 'unit',
- include: ['**/*.unit.test.ts'],
- },
- },
- {
- extends: './vitest.config.ts',
- test: {
- name: 'integration',
- include: ['**/*.integration.test.ts'],
- },
- },
-])
-```
-:::
::: danger Unsupported Options
Some of the configuration options are not allowed in a project config. Most notably:
-- `coverage`: coverage is done for the whole workspace
+- `coverage`: coverage is done for the whole process
- `reporters`: only root-level reporters can be supported
- `resolveSnapshotPath`: only root-level resolver is respected
- all other options that don't affect test runners
diff --git a/docs/guide/test-context.md b/docs/guide/test-context.md
index 6e8ba9fdf..0594f10fb 100644
--- a/docs/guide/test-context.md
+++ b/docs/guide/test-context.md
@@ -232,7 +232,7 @@ test('works correctly')
#### Default fixture
-Since Vitest 3, you can provide different values in different [projects](/guide/workspace). To enable this feature, pass down `{ injected: true }` to the options. If the key is not specified in the [project configuration](/config/#provide), then the default value will be used.
+Since Vitest 3, you can provide different values in different [projects](/guide/projects). To enable this feature, pass down `{ injected: true }` to the options. If the key is not specified in the [project configuration](/config/#provide), then the default value will be used.
:::code-group
```ts [fixtures.test.ts]
@@ -253,32 +253,36 @@ test('works correctly', ({ url }) => {
// url is "/empty" in "project-empty"
})
```
-```ts [vitest.workspace.ts]
-import { defineWorkspace } from 'vitest/config'
+```ts [vitest.config.ts]
+import { defineConfig } from 'vitest/config'
-export default defineWorkspace([
- {
- test: {
- name: 'project-new',
- },
- },
- {
- test: {
- name: 'project-full',
- provide: {
- url: '/full',
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ test: {
+ name: 'project-new',
+ },
},
- },
- },
- {
- test: {
- name: 'project-empty',
- provide: {
- url: '/empty',
+ {
+ test: {
+ name: 'project-full',
+ provide: {
+ url: '/full',
+ },
+ },
},
- },
+ {
+ test: {
+ name: 'project-empty',
+ provide: {
+ url: '/empty',
+ },
+ },
+ },
+ ],
},
-])
+})
```
:::
diff --git a/examples/workspace/package.json b/examples/projects/package.json
similarity index 94%
rename from examples/workspace/package.json
rename to examples/projects/package.json
index 6eb6ab559..55cca402b 100644
--- a/examples/workspace/package.json
+++ b/examples/projects/package.json
@@ -1,5 +1,5 @@
{
- "name": "@vitest/example-workspace",
+ "name": "@vitest/example-projects",
"type": "module",
"private": true,
"license": "MIT",
diff --git a/examples/workspace/packages/client/components/Link.tsx b/examples/projects/packages/client/components/Link.tsx
similarity index 100%
rename from examples/workspace/packages/client/components/Link.tsx
rename to examples/projects/packages/client/components/Link.tsx
diff --git a/examples/workspace/packages/client/test/basic.test.tsx b/examples/projects/packages/client/test/basic.test.tsx
similarity index 93%
rename from examples/workspace/packages/client/test/basic.test.tsx
rename to examples/projects/packages/client/test/basic.test.tsx
index c3f05697b..3554c265a 100644
--- a/examples/workspace/packages/client/test/basic.test.tsx
+++ b/examples/projects/packages/client/test/basic.test.tsx
@@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'
import { userEvent } from '@testing-library/user-event'
import React from 'react'
import { expect, test } from 'vitest'
-import Link from '../components/Link.jsx'
+import Link from '../components/Link.js'
test('Link changes the state when hovered', async () => {
render(
diff --git a/examples/workspace/packages/client/tsconfig.json b/examples/projects/packages/client/tsconfig.json
similarity index 100%
rename from examples/workspace/packages/client/tsconfig.json
rename to examples/projects/packages/client/tsconfig.json
diff --git a/examples/workspace/packages/client/vitest.config.ts b/examples/projects/packages/client/vitest.config.ts
similarity index 100%
rename from examples/workspace/packages/client/vitest.config.ts
rename to examples/projects/packages/client/vitest.config.ts
diff --git a/examples/workspace/packages/client/vitest.setup.ts b/examples/projects/packages/client/vitest.setup.ts
similarity index 100%
rename from examples/workspace/packages/client/vitest.setup.ts
rename to examples/projects/packages/client/vitest.setup.ts
diff --git a/examples/workspace/packages/server/mockData.ts b/examples/projects/packages/server/mockData.ts
similarity index 100%
rename from examples/workspace/packages/server/mockData.ts
rename to examples/projects/packages/server/mockData.ts
diff --git a/examples/workspace/packages/server/src/app.ts b/examples/projects/packages/server/src/app.ts
similarity index 85%
rename from examples/workspace/packages/server/src/app.ts
rename to examples/projects/packages/server/src/app.ts
index 7e0a3cf2f..dceafa3ce 100644
--- a/examples/workspace/packages/server/src/app.ts
+++ b/examples/projects/packages/server/src/app.ts
@@ -1,6 +1,6 @@
import type { FastifyInstance } from 'fastify'
import Fastify from 'fastify'
-import { usersData } from '../mockData'
+import { usersData } from '../mockData.js'
const app: FastifyInstance = Fastify({
logger: process.env.NODE_ENV === 'development',
diff --git a/examples/workspace/packages/server/src/index.ts b/examples/projects/packages/server/src/index.ts
similarity index 84%
rename from examples/workspace/packages/server/src/index.ts
rename to examples/projects/packages/server/src/index.ts
index 0ef6d1e56..0c51507ac 100644
--- a/examples/workspace/packages/server/src/index.ts
+++ b/examples/projects/packages/server/src/index.ts
@@ -1,4 +1,4 @@
-import app from './app'
+import app from './app.js'
async function start() {
try {
diff --git a/examples/workspace/packages/server/test/app.test.ts b/examples/projects/packages/server/test/app.test.ts
similarity index 93%
rename from examples/workspace/packages/server/test/app.test.ts
rename to examples/projects/packages/server/test/app.test.ts
index e2a4549ff..e97afe11c 100644
--- a/examples/workspace/packages/server/test/app.test.ts
+++ b/examples/projects/packages/server/test/app.test.ts
@@ -1,8 +1,8 @@
import supertest from 'supertest'
import { afterAll, expect, test } from 'vitest'
-import { usersData } from '../mockData'
-import app from '../src/app'
+import { usersData } from '../mockData.js'
+import app from '../src/app.js'
test('with HTTP injection', async () => {
const response = await app.inject({
diff --git a/examples/workspace/tsconfig.json b/examples/projects/tsconfig.json
similarity index 100%
rename from examples/workspace/tsconfig.json
rename to examples/projects/tsconfig.json
diff --git a/examples/projects/vitest.config.ts b/examples/projects/vitest.config.ts
new file mode 100644
index 000000000..45eba4084
--- /dev/null
+++ b/examples/projects/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: ['packages/*'],
+ },
+})
diff --git a/examples/workspace/vitest.workspace.ts b/examples/workspace/vitest.workspace.ts
deleted file mode 100644
index b18a56c5a..000000000
--- a/examples/workspace/vitest.workspace.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- 'packages/*',
-])
diff --git a/netlify.toml b/netlify.toml
index 51c192bc0..a4caf901f 100755
--- a/netlify.toml
+++ b/netlify.toml
@@ -25,6 +25,16 @@ from = "/config/file"
to = "/config/"
status = 301
+[[redirects]]
+from = "/guide/workspace"
+to = "/guide/projects"
+status = 301
+
+[[redirects]]
+from = "/guide/workspace.html"
+to = "/guide/projects"
+status = 301
+
[[headers]]
for = "/manifest.webmanifest"
diff --git a/packages/vitest/src/node/cli/cli-config.ts b/packages/vitest/src/node/cli/cli-config.ts
index 101ff4e6f..6bfc79658 100644
--- a/packages/vitest/src/node/cli/cli-config.ts
+++ b/packages/vitest/src/node/cli/cli-config.ts
@@ -332,7 +332,7 @@ export const cliOptionsConfig: VitestCLIOptions = {
argument: '',
},
workspace: {
- description: 'Path to a workspace configuration file',
+ description: '[deprecated] Path to a workspace configuration file',
argument: '',
normalize: true,
},
@@ -863,6 +863,7 @@ export const cliOptionsConfig: VitestCLIOptions = {
json: null,
provide: null,
filesOnly: null,
+ projects: null,
watchTriggerPatterns: null,
}
diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts
index 515e4e690..33717bb13 100644
--- a/packages/vitest/src/node/core.ts
+++ b/packages/vitest/src/node/core.ts
@@ -15,7 +15,7 @@ import { promises as fs } from 'node:fs'
import { getTasks, hasFailed } from '@vitest/runner/utils'
import { SnapshotManager } from '@vitest/snapshot/manager'
import { noop, toArray } from '@vitest/utils'
-import { dirname, join, normalize, relative } from 'pathe'
+import { dirname, join, normalize, relative, resolve } from 'pathe'
import { ViteNodeRunner } from 'vite-node/client'
import { ViteNodeServer } from 'vite-node/server'
import { version } from '../../package.json' with { type: 'json' }
@@ -33,6 +33,7 @@ import { Logger } from './logger'
import { VitestPackageInstaller } from './packageInstaller'
import { createPool } from './pool'
import { TestProject } from './project'
+import { getDefaultTestProject, resolveBrowserProjects, resolveProjects } from './projects/resolveProjects'
import { BlobReporter, readBlobs } from './reporters/blob'
import { HangingProcessReporter } from './reporters/hanging-process'
import { createBenchmarkReporters, createReporters } from './reporters/utils'
@@ -40,7 +41,6 @@ import { VitestSpecifications } from './specifications'
import { StateManager } from './state'
import { TestRun } from './test-run'
import { VitestWatcher } from './watcher'
-import { getDefaultTestProject, resolveBrowserWorkspace, resolveWorkspace } from './workspace/resolveWorkspace'
const WATCHER_DEBOUNCE = 100
@@ -274,7 +274,7 @@ export class Vitest {
}
catch { }
- const projects = await this.resolveWorkspace(cliOptions)
+ const projects = await this.resolveProjects(cliOptions)
this.resolvedProjects = projects
this.projects = projects
@@ -325,15 +325,15 @@ export class Vitest {
*/
private injectTestProject = async (config: TestProjectConfiguration | TestProjectConfiguration[]): Promise => {
const currentNames = new Set(this.projects.map(p => p.name))
- const workspace = await resolveWorkspace(
+ const projects = await resolveProjects(
this,
this._options,
undefined,
Array.isArray(config) ? config : [config],
currentNames,
)
- this.projects.push(...workspace)
- return workspace
+ this.projects.push(...projects)
+ return projects
}
/**
@@ -423,11 +423,30 @@ export class Vitest {
return join(configDir, workspaceConfigName)
}
- private async resolveWorkspace(cliOptions: UserConfig): Promise {
+ private async resolveProjects(cliOptions: UserConfig): Promise {
const names = new Set()
+ if (this.config.projects) {
+ if (typeof this.config.workspace !== 'undefined') {
+ this.logger.warn(
+ 'Both `config.projects` and `config.workspace` are defined. Ignoring the `workspace` option.',
+ )
+ }
+
+ return resolveProjects(
+ this,
+ cliOptions,
+ undefined,
+ this.config.projects,
+ names,
+ )
+ }
+
if (Array.isArray(this.config.workspace)) {
- return resolveWorkspace(
+ this.logger.deprecate(
+ 'The `workspace` option is deprecated and will be removed in the next major. To hide this warning, rename `workspace` option to `projects`.',
+ )
+ return resolveProjects(
this,
cliOptions,
undefined,
@@ -448,9 +467,17 @@ export class Vitest {
if (!project) {
return []
}
- return resolveBrowserWorkspace(this, new Set([project.name]), [project])
+ return resolveBrowserProjects(this, new Set([project.name]), [project])
}
+ const configFile = this.vite.config.configFile
+ ? resolve(this.vite.config.root, this.vite.config.configFile)
+ : 'the root config file'
+
+ this.logger.deprecate(
+ `The workspace file is deprecated and will be removed in the next major. Please, use the \`projects\` field in ${configFile} instead.`,
+ )
+
const workspaceModule = await this.import<{
default: ReturnType
}>(workspaceConfigPath)
@@ -459,7 +486,7 @@ export class Vitest {
throw new TypeError(`Workspace config file "${workspaceConfigPath}" must export a default array of project paths.`)
}
- return resolveWorkspace(
+ return resolveProjects(
this,
cliOptions,
workspaceConfigPath,
diff --git a/packages/vitest/src/node/logger.ts b/packages/vitest/src/node/logger.ts
index 81c94f376..119ef54c0 100644
--- a/packages/vitest/src/node/logger.ts
+++ b/packages/vitest/src/node/logger.ts
@@ -110,6 +110,10 @@ export class Logger {
printError(err, this.ctx, this, options)
}
+ deprecate(message: string): void {
+ this.log(c.bold(c.bgYellow(' DEPRECATED ')), c.yellow(message))
+ }
+
clearHighlightCache(filename?: string): void {
if (filename) {
this._highlights.delete(filename)
diff --git a/packages/vitest/src/node/pool.ts b/packages/vitest/src/node/pool.ts
index 73a96a82b..e2a8f5742 100644
--- a/packages/vitest/src/node/pool.ts
+++ b/packages/vitest/src/node/pool.ts
@@ -70,7 +70,7 @@ export function getFilePoolName(project: TestProject, file: string): Pool {
for (const [glob, pool] of project.config.poolMatchGlobs) {
if ((pool as Pool) === 'browser') {
throw new Error(
- 'Since Vitest 0.31.0 "browser" pool is not supported in "poolMatchGlobs". You can create a workspace to run some of your tests in browser in parallel. Read more: https://vitest.dev/guide/workspace',
+ 'Since Vitest 0.31.0 "browser" pool is not supported in "poolMatchGlobs". You can create a project to run some of your tests in browser in parallel. Read more: https://vitest.dev/guide/projects',
)
}
if (mm.isMatch(file, glob, { cwd: project.config.root })) {
diff --git a/packages/vitest/src/node/workspace/resolveWorkspace.ts b/packages/vitest/src/node/projects/resolveProjects.ts
similarity index 91%
rename from packages/vitest/src/node/workspace/resolveWorkspace.ts
rename to packages/vitest/src/node/projects/resolveProjects.ts
index e9676f470..81637dbf8 100644
--- a/packages/vitest/src/node/workspace/resolveWorkspace.ts
+++ b/packages/vitest/src/node/projects/resolveProjects.ts
@@ -14,17 +14,17 @@ import { VitestFilteredOutProjectError } from '../errors'
import { initializeProject, TestProject } from '../project'
import { withLabel } from '../reporters/renderers/utils'
-export async function resolveWorkspace(
+export async function resolveProjects(
vitest: Vitest,
cliOptions: UserConfig,
workspaceConfigPath: string | undefined,
- workspaceDefinition: TestProjectConfiguration[],
+ projectsDefinition: TestProjectConfiguration[],
names: Set,
): Promise {
const { configFiles, projectConfigs, nonConfigDirectories } = await resolveTestProjectConfigs(
vitest,
workspaceConfigPath,
- workspaceDefinition,
+ projectsDefinition,
)
// cli options that affect the project config,
@@ -109,7 +109,7 @@ export async function resolveWorkspace(
[
'No projects were found. Make sure your configuration is correct. ',
vitest.config.project.length ? `The filter matched no projects: ${vitest.config.project.join(', ')}. ` : '',
- `The workspace: ${JSON.stringify(workspaceDefinition, null, 4)}.`,
+ `The projects definition: ${JSON.stringify(projectsDefinition, null, 4)}.`,
].join(''),
)
}
@@ -135,7 +135,7 @@ export async function resolveWorkspace(
if (errors.length) {
throw new AggregateError(
errors,
- 'Failed to initialize projects. There were errors during workspace setup. See below for more details.',
+ 'Failed to initialize projects. There were errors during projects setup. See below for more details.',
)
}
@@ -157,16 +157,16 @@ export async function resolveWorkspace(
' is not unique.',
duplicate?.vite.config.configFile ? ` The project is already defined by "${relative(vitest.config.root, duplicate.vite.config.configFile)}".` : '',
filesError,
- 'All projects in a workspace should have unique names. Make sure your configuration is correct.',
+ 'All projects should have unique names. Make sure your configuration is correct.',
].join(''))
}
names.add(name)
}
- return resolveBrowserWorkspace(vitest, names, resolvedProjects)
+ return resolveBrowserProjects(vitest, names, resolvedProjects)
}
-export async function resolveBrowserWorkspace(
+export async function resolveBrowserProjects(
vitest: Vitest,
names: Set,
resolvedProjects: TestProject[],
@@ -184,7 +184,7 @@ export async function resolveBrowserWorkspace(
browser,
name: project.name ? `${project.name} (${browser})` : browser,
})
- console.warn(
+ vitest.logger.warn(
withLabel(
'yellow',
'Vitest',
@@ -237,7 +237,7 @@ export async function resolveBrowserWorkspace(
[
`Cannot define a nested project for a ${browser} browser. The project name "${name}" was already defined. `,
'If you have multiple instances for the same browser, make sure to define a custom "name". ',
- 'All projects in a workspace should have unique names. Make sure your configuration is correct.',
+ 'All projects should have unique names. Make sure your configuration is correct.',
].join(''),
)
}
@@ -322,21 +322,21 @@ function cloneConfig(project: TestProject, { browser, ...config }: BrowserInstan
async function resolveTestProjectConfigs(
vitest: Vitest,
workspaceConfigPath: string | undefined,
- workspaceDefinition: TestProjectConfiguration[],
+ projectsDefinition: TestProjectConfiguration[],
) {
// project configurations that were specified directly
const projectsOptions: (UserWorkspaceConfig & { extends?: true | string })[] = []
// custom config files that were specified directly or resolved from a directory
- const workspaceConfigFiles: string[] = []
+ const projectsConfigFiles: string[] = []
// custom glob matches that should be resolved as directories or config files
- const workspaceGlobMatches: string[] = []
+ const projectsGlobMatches: string[] = []
// directories that don't have a config file inside, but should be treated as projects
const nonConfigProjectDirectories: string[] = []
- for (const definition of workspaceDefinition) {
+ for (const definition of projectsDefinition) {
if (typeof definition === 'string') {
const stringOption = definition.replace('', vitest.config.root)
// if the string doesn't contain a glob, we can resolve it directly
@@ -345,23 +345,23 @@ async function resolveTestProjectConfigs(
const file = resolve(vitest.config.root, stringOption)
if (!existsSync(file)) {
- const relativeWorkSpaceConfigPath = workspaceConfigPath
+ const relativeWorkspaceConfigPath = workspaceConfigPath
? relative(vitest.config.root, workspaceConfigPath)
: undefined
- const note = workspaceConfigPath ? `Workspace config file "${relativeWorkSpaceConfigPath}"` : 'Inline workspace'
+ const note = workspaceConfigPath ? `Workspace config file "${relativeWorkspaceConfigPath}"` : 'Projects definition'
throw new Error(`${note} references a non-existing file or a directory: ${file}`)
}
const stats = await fs.stat(file)
// user can specify a config file directly
if (stats.isFile()) {
- workspaceConfigFiles.push(file)
+ projectsConfigFiles.push(file)
}
// user can specify a directory that should be used as a project
else if (stats.isDirectory()) {
const configFile = await resolveDirectoryConfig(file)
if (configFile) {
- workspaceConfigFiles.push(configFile)
+ projectsConfigFiles.push(configFile)
}
else {
const directory = file[file.length - 1] === '/' ? file : `${file}/`
@@ -376,7 +376,7 @@ async function resolveTestProjectConfigs(
// if the string is a glob pattern, resolve it later
// ['./packages/*']
else {
- workspaceGlobMatches.push(stringOption)
+ projectsGlobMatches.push(stringOption)
}
}
// if the config is inlined, we can resolve it immediately
@@ -394,7 +394,7 @@ async function resolveTestProjectConfigs(
}
}
- if (workspaceGlobMatches.length) {
+ if (projectsGlobMatches.length) {
const globOptions: GlobOptions = {
absolute: true,
dot: true,
@@ -410,27 +410,27 @@ async function resolveTestProjectConfigs(
],
}
- const workspacesFs = await glob(workspaceGlobMatches, globOptions)
+ const projectsFs = await glob(projectsGlobMatches, globOptions)
- await Promise.all(workspacesFs.map(async (path) => {
+ await Promise.all(projectsFs.map(async (path) => {
// directories are allowed with a glob like `packages/*`
// in this case every directory is treated as a project
if (path.endsWith('/')) {
const configFile = await resolveDirectoryConfig(path)
if (configFile) {
- workspaceConfigFiles.push(configFile)
+ projectsConfigFiles.push(configFile)
}
else {
nonConfigProjectDirectories.push(path)
}
}
else {
- workspaceConfigFiles.push(path)
+ projectsConfigFiles.push(path)
}
}))
}
- const projectConfigFiles = Array.from(new Set(workspaceConfigFiles))
+ const projectConfigFiles = Array.from(new Set(projectsConfigFiles))
return {
projectConfigs: projectsOptions,
diff --git a/packages/vitest/src/node/reporters/basic.ts b/packages/vitest/src/node/reporters/basic.ts
index 107e6b990..9d6f4a5d5 100644
--- a/packages/vitest/src/node/reporters/basic.ts
+++ b/packages/vitest/src/node/reporters/basic.ts
@@ -1,6 +1,5 @@
import type { File } from '@vitest/runner'
import type { Vitest } from '../core'
-import c from 'tinyrainbow'
import { BaseReporter } from './base'
export class BasicReporter extends BaseReporter {
@@ -12,11 +11,11 @@ export class BasicReporter extends BaseReporter {
onInit(ctx: Vitest): void {
super.onInit(ctx)
- ctx.logger.log(c.bold(c.bgYellow(' DEPRECATED ')), c.yellow(
+ ctx.logger.deprecate(
`'basic' reporter is deprecated and will be removed in Vitest v3.\n`
+ `Remove 'basic' from 'reporters' option. To match 'basic' reporter 100%, use configuration:\n${
JSON.stringify({ test: { reporters: [['default', { summary: false }]] } }, null, 2)}`,
- ))
+ )
}
reportSummary(files: File[], errors: unknown[]): void {
diff --git a/packages/vitest/src/node/types/config.ts b/packages/vitest/src/node/types/config.ts
index e2f9eba84..588cf1932 100644
--- a/packages/vitest/src/node/types/config.ts
+++ b/packages/vitest/src/node/types/config.ts
@@ -320,7 +320,7 @@ export interface InlineConfig {
*
* Format: [glob, environment-name]
*
- * @deprecated use [`workspace`](https://vitest.dev/config/#environmentmatchglobs) instead
+ * @deprecated use [`projects`](https://vitest.dev/config/#projects) instead
* @default []
* @example [
* // all tests in tests/dom will run in jsdom
@@ -377,7 +377,7 @@ export interface InlineConfig {
*
* Format: [glob, pool-name]
*
- * @deprecated use [`workspace`](https://vitest.dev/config/#poolmatchglobs) instead
+ * @deprecated use [`projects`](https://vitest.dev/config/#projects) instead
* @default []
* @example [
* // all tests in "forks" directory will run using "poolOptions.forks" API
@@ -388,8 +388,14 @@ export interface InlineConfig {
*/
poolMatchGlobs?: [string, Exclude][]
+ /**
+ * Options for projects
+ */
+ projects?: TestProjectConfiguration[]
+
/**
* Path to a workspace configuration file
+ * @deprecated use `projects` instead
*/
workspace?: string | TestProjectConfiguration[]
diff --git a/packages/vitest/src/public/config.ts b/packages/vitest/src/public/config.ts
index 90c648b11..fe2d0191e 100644
--- a/packages/vitest/src/public/config.ts
+++ b/packages/vitest/src/public/config.ts
@@ -66,6 +66,9 @@ export function defineProject(config: UserProjectConfigExport): UserProjectConfi
return config
}
+/**
+ * @deprecated use the `projects` field in the root config instead
+ */
export function defineWorkspace(config: TestProjectConfiguration[]): TestProjectConfiguration[] {
return config
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e96c49b84..7174b890a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -382,25 +382,7 @@ importers:
specifier: workspace:*
version: link:../../packages/vitest
- examples/typecheck:
- devDependencies:
- '@types/node':
- specifier: ^20.17.30
- version: 20.17.30
- '@vitest/ui':
- specifier: workspace:*
- version: link:../../packages/ui
- typescript:
- specifier: ^5.8.3
- version: 5.8.3
- vite:
- specifier: ^6.2.0
- version: 6.2.0(@types/node@20.17.30)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0)
- vitest:
- specifier: workspace:*
- version: link:../../packages/vitest
-
- examples/workspace:
+ examples/projects:
devDependencies:
'@testing-library/jest-dom':
specifier: ^6.6.3
@@ -442,6 +424,24 @@ importers:
specifier: workspace:*
version: link:../../packages/vitest
+ examples/typecheck:
+ devDependencies:
+ '@types/node':
+ specifier: ^20.17.30
+ version: 20.17.30
+ '@vitest/ui':
+ specifier: workspace:*
+ version: link:../../packages/ui
+ typescript:
+ specifier: ^5.8.3
+ version: 5.8.3
+ vite:
+ specifier: ^6.2.0
+ version: 6.2.0(@types/node@20.17.30)(jiti@2.4.2)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0)
+ vitest:
+ specifier: workspace:*
+ version: link:../../packages/vitest
+
packages/browser:
dependencies:
'@testing-library/dom':
@@ -5476,9 +5476,6 @@ packages:
resolution: {integrity: sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- decimal.js@10.4.3:
- resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
-
decimal.js@10.5.0:
resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==}
@@ -8768,10 +8765,6 @@ packages:
tr46@1.0.1:
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
- tr46@5.0.0:
- resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
- engines: {node: '>=18'}
-
tr46@5.1.0:
resolution: {integrity: sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==}
engines: {node: '>=18'}
@@ -9342,10 +9335,6 @@ packages:
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
engines: {node: '>=18'}
- whatwg-url@14.1.0:
- resolution: {integrity: sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==}
- engines: {node: '>=18'}
-
whatwg-url@14.2.0:
resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
engines: {node: '>=18'}
@@ -11891,24 +11880,24 @@ snapshots:
'@types/babel__core@7.20.5':
dependencies:
- '@babel/parser': 7.26.2
- '@babel/types': 7.26.0
+ '@babel/parser': 7.27.0
+ '@babel/types': 7.27.0
'@types/babel__generator': 7.6.6
'@types/babel__template': 7.4.3
'@types/babel__traverse': 7.20.3
'@types/babel__generator@7.6.6':
dependencies:
- '@babel/types': 7.26.0
+ '@babel/types': 7.27.0
'@types/babel__template@7.4.3':
dependencies:
- '@babel/parser': 7.26.2
- '@babel/types': 7.26.0
+ '@babel/parser': 7.27.0
+ '@babel/types': 7.27.0
'@types/babel__traverse@7.20.3':
dependencies:
- '@babel/types': 7.26.0
+ '@babel/types': 7.27.0
'@types/braces@3.0.1': {}
@@ -13652,8 +13641,6 @@ snapshots:
decamelize@6.0.0: {}
- decimal.js@10.4.3: {}
-
decimal.js@10.5.0: {}
decode-bmp@0.2.1:
@@ -15435,7 +15422,7 @@ snapshots:
dependencies:
cssstyle: 4.2.1
data-urls: 5.0.0
- decimal.js: 10.4.3
+ decimal.js: 10.5.0
form-data: 4.0.1
html-encoding-sniffer: 4.0.0
http-proxy-agent: 7.0.2
@@ -15451,7 +15438,7 @@ snapshots:
webidl-conversions: 7.0.0
whatwg-encoding: 3.1.1
whatwg-mimetype: 4.0.0
- whatwg-url: 14.1.0
+ whatwg-url: 14.2.0
ws: 8.18.1
xml-name-validator: 5.0.0
transitivePeerDependencies:
@@ -17679,10 +17666,6 @@ snapshots:
dependencies:
punycode: 2.3.1
- tr46@5.0.0:
- dependencies:
- punycode: 2.3.1
-
tr46@5.1.0:
dependencies:
punycode: 2.3.1
@@ -18389,11 +18372,6 @@ snapshots:
whatwg-mimetype@4.0.0: {}
- whatwg-url@14.1.0:
- dependencies:
- tr46: 5.0.0
- webidl-conversions: 7.0.0
-
whatwg-url@14.2.0:
dependencies:
tr46: 5.1.0
diff --git a/test/browser/fixtures/inspect/vitest.config.with-workspace.ts b/test/browser/fixtures/inspect/vitest.config.with-workspace.ts
index ee91b8bcd..ec6d2c097 100644
--- a/test/browser/fixtures/inspect/vitest.config.with-workspace.ts
+++ b/test/browser/fixtures/inspect/vitest.config.with-workspace.ts
@@ -5,7 +5,7 @@ export default defineConfig({
test: {
watch: false,
- workspace: [
+ projects: [
{
test: {
name: "Browser in workspace",
diff --git a/test/browser/test/commands.test.ts b/test/browser/test/commands.test.ts
index 246bf0ae1..0276e0d30 100644
--- a/test/browser/test/commands.test.ts
+++ b/test/browser/test/commands.test.ts
@@ -13,10 +13,10 @@ it('can manipulate files', async () => {
catch (err) {
expect(err.message).toMatch(`ENOENT: no such file or directory, open`)
if (server.platform === 'win32') {
- expect(err.message).toMatch('test\\browser\\test\\test.txt')
+ expect(err.message).toMatch('test\\browser\\test.txt')
}
else {
- expect(err.message).toMatch('test/browser/test/test.txt')
+ expect(err.message).toMatch('test/browser/test.txt')
}
}
@@ -34,10 +34,10 @@ it('can manipulate files', async () => {
catch (err) {
expect(err.message).toMatch(`ENOENT: no such file or directory, open`)
if (server.platform === 'win32') {
- expect(err.message).toMatch('test\\browser\\test\\test.txt')
+ expect(err.message).toMatch('test\\browser\\test.txt')
}
else {
- expect(err.message).toMatch('test/browser/test/test.txt')
+ expect(err.message).toMatch('test/browser/test.txt')
}
}
})
diff --git a/test/cli/fixtures/browser-multiple/vitest.config.ts b/test/cli/fixtures/browser-multiple/vitest.config.ts
new file mode 100644
index 000000000..e3e49a772
--- /dev/null
+++ b/test/cli/fixtures/browser-multiple/vitest.config.ts
@@ -0,0 +1,37 @@
+import { resolve } from 'pathe';
+import { defineConfig, defineWorkspace } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ cacheDir: resolve(import.meta.dirname, 'basic-1'),
+ test: {
+ name: 'basic-1',
+ dir: import.meta.dirname,
+ include: ['./basic.test.js'],
+ browser: {
+ enabled: true,
+ instances: [{ browser: 'chromium' }],
+ provider: 'playwright',
+ headless: true,
+ }
+ }
+ },
+ {
+ cacheDir: resolve(import.meta.dirname, 'basic-2'),
+ test: {
+ name: 'basic-2',
+ dir: import.meta.dirname,
+ include: ['./basic.test.js'],
+ browser: {
+ enabled: true,
+ instances: [{ browser: 'chromium' }],
+ provider: 'playwright',
+ headless: true,
+ }
+ }
+ },
+ ],
+ },
+})
\ No newline at end of file
diff --git a/test/cli/fixtures/browser-multiple/vitest.workspace.ts b/test/cli/fixtures/browser-multiple/vitest.workspace.ts
deleted file mode 100644
index a1d3ec0be..000000000
--- a/test/cli/fixtures/browser-multiple/vitest.workspace.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { resolve } from 'pathe';
-import { defineWorkspace } from 'vitest/config';
-
-export default defineWorkspace([
- {
- cacheDir: resolve(import.meta.dirname, 'basic-1'),
- test: {
- name: 'basic-1',
- dir: import.meta.dirname,
- include: ['./basic.test.js'],
- browser: {
- enabled: true,
- instances: [{ browser: 'chromium' }],
- provider: 'playwright',
- headless: true,
- }
- }
- },
- {
- cacheDir: resolve(import.meta.dirname, 'basic-2'),
- test: {
- name: 'basic-2',
- dir: import.meta.dirname,
- include: ['./basic.test.js'],
- browser: {
- enabled: true,
- instances: [{ browser: 'chromium' }],
- provider: 'playwright',
- headless: true,
- }
- }
- },
-])
\ No newline at end of file
diff --git a/test/cli/fixtures/config-loader/vitest.config.ts b/test/cli/fixtures/config-loader/vitest.config.ts
index 44880bd59..6cf7af8b2 100644
--- a/test/cli/fixtures/config-loader/vitest.config.ts
+++ b/test/cli/fixtures/config-loader/vitest.config.ts
@@ -3,7 +3,7 @@ import "@vitest/test-dep-linked/ts";
export default defineConfig({
test: {
- workspace: [
+ projects: [
"browser/vitest.config.ts",
"node/vitest.config.ts",
],
diff --git a/test/cli/fixtures/custom-pool/vitest.config.ts b/test/cli/fixtures/custom-pool/vitest.config.ts
index 337e88923..3ab828ea5 100644
--- a/test/cli/fixtures/custom-pool/vitest.config.ts
+++ b/test/cli/fixtures/custom-pool/vitest.config.ts
@@ -8,7 +8,7 @@ export default defineConfig({
array: [1, 2, 3],
},
},
- workspace: [
+ projects: [
{
extends: true,
test: {
diff --git a/test/cli/fixtures/git-changed/workspace/vitest.config.mjs b/test/cli/fixtures/git-changed/workspace/vitest.config.mjs
index b1c6ea436..98ae6016a 100644
--- a/test/cli/fixtures/git-changed/workspace/vitest.config.mjs
+++ b/test/cli/fixtures/git-changed/workspace/vitest.config.mjs
@@ -1 +1,9 @@
-export default {}
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ "packages/*/vitest.config.mjs",
+ ]
+ },
+})
diff --git a/test/cli/fixtures/git-changed/workspace/vitest.workspace.js b/test/cli/fixtures/git-changed/workspace/vitest.workspace.js
deleted file mode 100644
index f63e728f9..000000000
--- a/test/cli/fixtures/git-changed/workspace/vitest.workspace.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default [
- "packages/*/vitest.config.mjs",
-];
diff --git a/test/cli/test/browser-multiple.test.ts b/test/cli/test/browser-multiple.test.ts
index a98eb9f77..48ed85ac9 100644
--- a/test/cli/test/browser-multiple.test.ts
+++ b/test/cli/test/browser-multiple.test.ts
@@ -6,14 +6,12 @@ import { runVitest } from '../../test-utils'
it('automatically assigns the port', async () => {
const root = resolve(import.meta.dirname, '../fixtures/browser-multiple')
- const workspace = resolve(import.meta.dirname, '../fixtures/browser-multiple/vitest.workspace.ts')
const spy = vi.spyOn(console, 'log')
onTestFinished(() => spy.mockRestore())
let ctx: Vitest
let urls: (string | undefined)[] = []
const { stderr } = await runVitest({
root,
- workspace,
dir: root,
watch: false,
reporters: [
diff --git a/test/config/fixtures/mixed-environments/vitest.config.ts b/test/config/fixtures/mixed-environments/vitest.config.ts
index 117a67645..a099082e0 100644
--- a/test/config/fixtures/mixed-environments/vitest.config.ts
+++ b/test/config/fixtures/mixed-environments/vitest.config.ts
@@ -1,5 +1,25 @@
import { defineConfig } from 'vitest/config'
+import { resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = resolve(__filename, '..')
export default defineConfig({
- test: {},
+ test: {
+ projects: [
+ {
+ test: {
+ name: 'Project #1',
+ root: resolve(__dirname, './project'),
+ },
+ },
+ {
+ test: {
+ name: 'Project #2',
+ root: resolve(__dirname, './project'),
+ },
+ },
+ ]
+ },
})
diff --git a/test/config/fixtures/mixed-environments/vitest.workspace.ts b/test/config/fixtures/mixed-environments/vitest.workspace.ts
deleted file mode 100644
index c88592f94..000000000
--- a/test/config/fixtures/mixed-environments/vitest.workspace.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { resolve } from 'node:path'
-import { fileURLToPath } from 'node:url'
-import { defineWorkspace } from 'vitest/config'
-
-const __filename = fileURLToPath(import.meta.url)
-const __dirname = resolve(__filename, '..')
-
-export default defineWorkspace([
- {
- test: {
- name: 'Project #1',
- root: resolve(__dirname, './project'),
- },
- },
- {
- test: {
- name: 'Project #2',
- root: resolve(__dirname, './project'),
- },
- },
-])
diff --git a/test/config/fixtures/no-browser-workspace/vitest.config.ts b/test/config/fixtures/no-browser-workspace/vitest.config.ts
index 6e5dcfe47..5e498dac4 100644
--- a/test/config/fixtures/no-browser-workspace/vitest.config.ts
+++ b/test/config/fixtures/no-browser-workspace/vitest.config.ts
@@ -2,7 +2,7 @@ import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
- workspace: [
+ projects: [
{
test: {
name: 'unit',
diff --git a/test/config/fixtures/project/vitest.config.ts b/test/config/fixtures/project/vitest.config.ts
index cc579dcc1..4514ff57a 100644
--- a/test/config/fixtures/project/vitest.config.ts
+++ b/test/config/fixtures/project/vitest.config.ts
@@ -1,3 +1,9 @@
import { defineConfig } from "vitest/config";
-export default defineConfig({})
+export default defineConfig({
+ test: {
+ projects: [
+ 'packages/*'
+ ]
+ }
+})
diff --git a/test/config/fixtures/project/vitest.workspace.ts b/test/config/fixtures/project/vitest.workspace.ts
deleted file mode 100644
index ab1d8a7a7..000000000
--- a/test/config/fixtures/project/vitest.workspace.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export default [
- 'packages/*'
-]
diff --git a/test/config/fixtures/snapshot-path-context/vitest.config.ts b/test/config/fixtures/snapshot-path-context/vitest.config.ts
index a03d2b41c..7320a5019 100644
--- a/test/config/fixtures/snapshot-path-context/vitest.config.ts
+++ b/test/config/fixtures/snapshot-path-context/vitest.config.ts
@@ -11,5 +11,21 @@ export default defineConfig({
basename(path) + extension
);
},
+ projects: [
+ {
+ extends: './vitest.config.ts',
+ test: {
+ name: 'project1',
+ root: import.meta.dirname,
+ }
+ },
+ {
+ extends: './vitest.config.ts',
+ test: {
+ name: 'project2',
+ root: import.meta.dirname,
+ }
+ }
+ ],
},
});
diff --git a/test/config/fixtures/snapshot-path-context/vitest.workspace.ts b/test/config/fixtures/snapshot-path-context/vitest.workspace.ts
deleted file mode 100644
index 30764821b..000000000
--- a/test/config/fixtures/snapshot-path-context/vitest.workspace.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- {
- extends: './vitest.config.ts',
- test: {
- name: 'project1',
- root: import.meta.dirname,
- }
- },
- {
- extends: './vitest.config.ts',
- test: {
- name: 'project2',
- root: import.meta.dirname,
- }
- }
-])
diff --git a/test/config/fixtures/workspace-flags/vitest.config.js b/test/config/fixtures/workspace-flags/vitest.config.js
new file mode 100644
index 000000000..b6542eea8
--- /dev/null
+++ b/test/config/fixtures/workspace-flags/vitest.config.js
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: ['projects'],
+ },
+})
\ No newline at end of file
diff --git a/test/config/fixtures/workspace-flags/vitest.workspace.js b/test/config/fixtures/workspace-flags/vitest.workspace.js
deleted file mode 100644
index 47d013c1f..000000000
--- a/test/config/fixtures/workspace-flags/vitest.workspace.js
+++ /dev/null
@@ -1 +0,0 @@
-export default ['projects']
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/config-extends/vitest.config.ts b/test/config/fixtures/workspace/config-extends/vitest.config.ts
index 8f3374e7c..4f62c6567 100644
--- a/test/config/fixtures/workspace/config-extends/vitest.config.ts
+++ b/test/config/fixtures/workspace/config-extends/vitest.config.ts
@@ -17,7 +17,7 @@ export default defineConfig({
},
],
test: {
- workspace: [
+ projects: [
{
extends: true,
test: {
diff --git a/test/config/fixtures/workspace/config-import-analysis/vitest.config.ts b/test/config/fixtures/workspace/config-import-analysis/vitest.config.ts
new file mode 100644
index 000000000..efbb3cb64
--- /dev/null
+++ b/test/config/fixtures/workspace/config-import-analysis/vitest.config.ts
@@ -0,0 +1,11 @@
+import { defineConfig } from 'vitest/config'
+import depAsJs from "./dep.js"
+
+export default defineConfig({
+ test: {
+ projects: [
+ "./packages/*",
+ ...depAsJs,
+ ],
+ }
+})
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/config-import-analysis/vitest.workspace.ts b/test/config/fixtures/workspace/config-import-analysis/vitest.workspace.ts
deleted file mode 100644
index 33419dd9b..000000000
--- a/test/config/fixtures/workspace/config-import-analysis/vitest.workspace.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import depAsJs from "./dep.js"
-
-export default [
- "./packages/*",
- ...depAsJs,
-]
diff --git a/test/config/fixtures/workspace/invalid-duplicate-configs/vitest.config.ts b/test/config/fixtures/workspace/invalid-duplicate-configs/vitest.config.ts
new file mode 100644
index 000000000..342854162
--- /dev/null
+++ b/test/config/fixtures/workspace/invalid-duplicate-configs/vitest.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ './vitest1.config.js',
+ './vitest2.config.js',
+ ],
+ }
+})
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/invalid-duplicate-configs/vitest.workspace.ts b/test/config/fixtures/workspace/invalid-duplicate-configs/vitest.workspace.ts
deleted file mode 100644
index 1aae3649d..000000000
--- a/test/config/fixtures/workspace/invalid-duplicate-configs/vitest.workspace.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- './vitest1.config.js',
- './vitest2.config.js',
-])
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/invalid-duplicate-inline/vitest.config.ts b/test/config/fixtures/workspace/invalid-duplicate-inline/vitest.config.ts
new file mode 100644
index 000000000..7e756fc30
--- /dev/null
+++ b/test/config/fixtures/workspace/invalid-duplicate-inline/vitest.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ test: {
+ name: 'test',
+ },
+ },
+ {
+ test: {
+ name: 'test',
+ },
+ },
+ ]
+ }
+})
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/invalid-duplicate-inline/vitest.workspace.ts b/test/config/fixtures/workspace/invalid-duplicate-inline/vitest.workspace.ts
deleted file mode 100644
index 5ac17ebfa..000000000
--- a/test/config/fixtures/workspace/invalid-duplicate-inline/vitest.workspace.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- {
- test: {
- name: 'test',
- },
- },
- {
- test: {
- name: 'test',
- },
- },
-])
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/invalid-non-existing-config/vitest.config.ts b/test/config/fixtures/workspace/invalid-non-existing-config/vitest.config.ts
new file mode 100644
index 000000000..b685b4101
--- /dev/null
+++ b/test/config/fixtures/workspace/invalid-non-existing-config/vitest.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ './vitest.config.js'
+ ],
+ },
+})
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/invalid-non-existing-config/vitest.workspace.ts b/test/config/fixtures/workspace/invalid-non-existing-config/vitest.workspace.ts
deleted file mode 100644
index abfecd280..000000000
--- a/test/config/fixtures/workspace/invalid-non-existing-config/vitest.workspace.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- './vitest.config.js'
-])
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/negated/vitest.config.ts b/test/config/fixtures/workspace/negated/vitest.config.ts
new file mode 100644
index 000000000..79fa0efd5
--- /dev/null
+++ b/test/config/fixtures/workspace/negated/vitest.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ projects: [
+ 'packages/*',
+ '!packages/b'
+ ],
+ },
+})
diff --git a/test/config/fixtures/workspace/negated/vitest.workspace.ts b/test/config/fixtures/workspace/negated/vitest.workspace.ts
deleted file mode 100644
index 131aeb64b..000000000
--- a/test/config/fixtures/workspace/negated/vitest.workspace.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- 'packages/*',
- '!packages/b'
-]
diff --git a/test/config/fixtures/workspace/several-configs/vitest.config.ts b/test/config/fixtures/workspace/several-configs/vitest.config.ts
new file mode 100644
index 000000000..10119df40
--- /dev/null
+++ b/test/config/fixtures/workspace/several-configs/vitest.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ './test/*.config.*.ts',
+ ],
+ },
+})
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/several-configs/vitest.workspace.ts b/test/config/fixtures/workspace/several-configs/vitest.workspace.ts
deleted file mode 100644
index 1efaf00d4..000000000
--- a/test/config/fixtures/workspace/several-configs/vitest.workspace.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export default [
- './test/*.config.*.ts'
-]
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/several-folders/vitest.config.ts b/test/config/fixtures/workspace/several-folders/vitest.config.ts
new file mode 100644
index 000000000..ccdd6814a
--- /dev/null
+++ b/test/config/fixtures/workspace/several-folders/vitest.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ projects: [
+ 'projects/*',
+ 'apps/*'
+ ],
+ },
+})
\ No newline at end of file
diff --git a/test/config/fixtures/workspace/several-folders/vitest.workspace.ts b/test/config/fixtures/workspace/several-folders/vitest.workspace.ts
deleted file mode 100644
index ab04316f2..000000000
--- a/test/config/fixtures/workspace/several-folders/vitest.workspace.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- 'projects/*',
- 'apps/*'
-]
\ No newline at end of file
diff --git a/test/config/test/browser-configs.test.ts b/test/config/test/browser-configs.test.ts
index a9113914c..34533d0b3 100644
--- a/test/config/test/browser-configs.test.ts
+++ b/test/config/test/browser-configs.test.ts
@@ -68,7 +68,7 @@ test('filters projects with a wildcard', async () => {
test('assignes names as browsers in a custom project', async () => {
const { projects } = await vitest({
- workspace: [
+ projects: [
{
test: {
name: 'custom',
@@ -207,7 +207,7 @@ test('coverage provider v8 works correctly in browser mode if instances are filt
test('coverage provider v8 works correctly in workspaced browser mode if instances are filtered', async () => {
const { projects } = await vitest({
project: 'browser (chromium)',
- workspace: [
+ projects: [
{
test: {
name: 'browser',
@@ -236,7 +236,7 @@ test('coverage provider v8 works correctly in workspaced browser mode if instanc
test('filter for the global browser project includes all browser instances', async () => {
const { projects } = await vitest({
project: 'myproject',
- workspace: [
+ projects: [
{
test: {
name: 'myproject',
@@ -275,7 +275,7 @@ test('can enable browser-cli options for multi-project workspace', async () => {
},
},
{
- workspace: [
+ projects: [
{
test: {
name: 'unit',
@@ -373,7 +373,7 @@ function getCliConfig(options: UserConfig, cli: string[], fs: TestFsStructure =
describe('[e2e] workspace configs are affected by the CLI options', () => {
test('UI is not enabled by default in headless config', async () => {
const vitest = await getCliConfig({
- workspace: [
+ projects: [
{
test: {
name: 'unit',
@@ -426,7 +426,7 @@ describe('[e2e] workspace configs are affected by the CLI options', () => {
test('CLI options correctly override inline workspace options', async () => {
const vitest = await getCliConfig({
- workspace: [
+ projects: [
{
test: {
name: 'unit',
@@ -481,7 +481,7 @@ describe('[e2e] workspace configs are affected by the CLI options', () => {
test('CLI options correctly override config file workspace options', async () => {
const vitest = await getCliConfig(
{
- workspace: [
+ projects: [
{
test: {
name: 'unit',
diff --git a/test/config/test/configureVitest.test.ts b/test/config/test/configureVitest.test.ts
index 41bd27a4f..a17ef21f7 100644
--- a/test/config/test/configureVitest.test.ts
+++ b/test/config/test/configureVitest.test.ts
@@ -30,7 +30,7 @@ test('can change global configuration', async () => {
test('can change the project and the global configurations', async () => {
const v = await vitest({}, {
- workspace: [
+ projects: [
{
plugins: [
{
@@ -59,7 +59,7 @@ test('plugin is not called if the project is filtered out', async () => {
const { projects } = await vitest({
project: 'project-2',
}, {
- workspace: [
+ projects: [
{
test: {
name: 'project-1',
@@ -113,7 +113,7 @@ test('injected plugin is filtered by the --project filter', async () => {
let newWorkspace: TestProject[] = []
const { projects } = await vitest({
project: 'project-1',
- workspace: [
+ projects: [
{
test: {
name: 'project-1',
@@ -143,7 +143,7 @@ test('injected plugin is not filtered by the --project filter when it\'s overrid
let newWorkspace: TestProject[] = []
const { projects } = await vitest({
project: 'project-1',
- workspace: [
+ projects: [
{
test: {
name: 'project-1',
@@ -174,7 +174,7 @@ test('injected plugin is not filtered by the --project filter when it\'s overrid
test('adding a plugin with existing name throws and error', async () => {
await expect(() => vitest({
- workspace: [
+ projects: [
{
test: {
name: 'project-1',
@@ -194,10 +194,10 @@ test('adding a plugin with existing name throws and error', async () => {
},
],
}),
- ).rejects.toThrowError('Project name "project-1" is not unique. All projects in a workspace should have unique names. Make sure your configuration is correct.')
+ ).rejects.toThrowError('Project name "project-1" is not unique. All projects should have unique names. Make sure your configuration is correct.')
await expect(() => vitest({
- workspace: [
+ projects: [
{
plugins: [
{
@@ -219,10 +219,10 @@ test('adding a plugin with existing name throws and error', async () => {
},
],
}),
- ).rejects.toThrowError('Project name "project-1" is not unique. All projects in a workspace should have unique names. Make sure your configuration is correct.')
+ ).rejects.toThrowError('Project name "project-1" is not unique. All projects should have unique names. Make sure your configuration is correct.')
await expect(() => vitest({
- workspace: [
+ projects: [
{
plugins: [
{
@@ -246,5 +246,5 @@ test('adding a plugin with existing name throws and error', async () => {
},
],
}),
- ).rejects.toThrowError('Project name "project-1" is not unique. All projects in a workspace should have unique names. Make sure your configuration is correct.')
+ ).rejects.toThrowError('Project name "project-1" is not unique. All projects should have unique names. Make sure your configuration is correct.')
})
diff --git a/test/config/test/failures.test.ts b/test/config/test/failures.test.ts
index c0f561042..ed8217c1f 100644
--- a/test/config/test/failures.test.ts
+++ b/test/config/test/failures.test.ts
@@ -476,7 +476,7 @@ test('browser.instances throws an error if no custom name is provided', async ()
},
},
})
- expect(stderr).toMatch('Cannot define a nested project for a firefox browser. The project name "firefox" was already defined. If you have multiple instances for the same browser, make sure to define a custom "name". All projects in a workspace should have unique names. Make sure your configuration is correct.')
+ expect(stderr).toMatch('Cannot define a nested project for a firefox browser. The project name "firefox" was already defined. If you have multiple instances for the same browser, make sure to define a custom "name". All projects should have unique names. Make sure your configuration is correct.')
})
test('browser.instances throws an error if no custom name is provided, but the config name is inherited', async () => {
@@ -491,12 +491,12 @@ test('browser.instances throws an error if no custom name is provided, but the c
],
},
})
- expect(stderr).toMatch('Cannot define a nested project for a firefox browser. The project name "custom (firefox)" was already defined. If you have multiple instances for the same browser, make sure to define a custom "name". All projects in a workspace should have unique names. Make sure your configuration is correct.')
+ expect(stderr).toMatch('Cannot define a nested project for a firefox browser. The project name "custom (firefox)" was already defined. If you have multiple instances for the same browser, make sure to define a custom "name". All projects should have unique names. Make sure your configuration is correct.')
})
test('throws an error if name conflicts with a workspace name', async () => {
const { stderr } = await runVitest({
- workspace: [
+ projects: [
{ test: { name: '1 (firefox)' } },
{
test: {
@@ -511,7 +511,7 @@ test('throws an error if name conflicts with a workspace name', async () => {
},
],
})
- expect(stderr).toMatch('Cannot define a nested project for a firefox browser. The project name "1 (firefox)" was already defined. If you have multiple instances for the same browser, make sure to define a custom "name". All projects in a workspace should have unique names. Make sure your configuration is correct.')
+ expect(stderr).toMatch('Cannot define a nested project for a firefox browser. The project name "1 (firefox)" was already defined. If you have multiple instances for the same browser, make sure to define a custom "name". All projects should have unique names. Make sure your configuration is correct.')
})
test('throws an error if several browsers are headed in nonTTY mode', async () => {
diff --git a/test/config/test/workspace.test.ts b/test/config/test/projects.test.ts
similarity index 79%
rename from test/config/test/workspace.test.ts
rename to test/config/test/projects.test.ts
index 1e1e190a7..c91fe361a 100644
--- a/test/config/test/workspace.test.ts
+++ b/test/config/test/projects.test.ts
@@ -15,7 +15,6 @@ it('correctly runs workspace tests when workspace config path is specified', asy
it('runs the workspace if there are several vitest config files', async () => {
const { stderr, stdout } = await runVitest({
root: 'fixtures/workspace/several-configs',
- workspace: './fixtures/workspace/several-configs/vitest.workspace.ts',
})
expect(stderr).toBe('')
expect(stdout).toContain('workspace/several-configs')
@@ -28,7 +27,6 @@ it('runs the workspace if there are several vitest config files', async () => {
it('correctly resolves workspace projects with a several folder globs', async () => {
const { stderr, stdout } = await runVitest({
root: 'fixtures/workspace/several-folders',
- workspace: './fixtures/workspace/several-folders/vitest.workspace.ts',
})
expect(stderr).toBe('')
expect(stdout).toContain('test - a')
@@ -38,7 +36,6 @@ it('correctly resolves workspace projects with a several folder globs', async ()
it('supports glob negation pattern', async () => {
const { stderr, stdout } = await runVitest({
root: 'fixtures/workspace/negated',
- workspace: './fixtures/workspace/negated/vitest.workspace.ts',
})
expect(stderr).toBe('')
expect(stdout).toContain('test - a')
@@ -49,7 +46,6 @@ it('supports glob negation pattern', async () => {
it('fails if project names are identical with a nice error message', async () => {
const { stderr } = await runVitest({
root: 'fixtures/workspace/invalid-duplicate-configs',
- workspace: './fixtures/workspace/invalid-duplicate-configs/vitest.workspace.ts',
}, [], 'test', {}, { fails: true })
expect(stderr).toContain(
`Project name "test" from "vitest2.config.js" is not unique. The project is already defined by "vitest1.config.js".
@@ -58,34 +54,31 @@ Your config matched these files:
- vitest1.config.js
- vitest2.config.js
-All projects in a workspace should have unique names. Make sure your configuration is correct.`,
+All projects should have unique names. Make sure your configuration is correct.`,
)
})
it('fails if project names are identical inside the inline config', async () => {
const { stderr } = await runVitest({
root: 'fixtures/workspace/invalid-duplicate-inline',
- workspace: './fixtures/workspace/invalid-duplicate-inline/vitest.workspace.ts',
}, [], 'test', {}, { fails: true })
expect(stderr).toContain(
- 'Project name "test" is not unique. All projects in a workspace should have unique names. Make sure your configuration is correct.',
+ 'Project name "test" is not unique. All projects should have unique names. Make sure your configuration is correct.',
)
})
it('fails if referenced file doesnt exist', async () => {
const { stderr } = await runVitest({
root: 'fixtures/workspace/invalid-non-existing-config',
- workspace: './fixtures/workspace/invalid-non-existing-config/vitest.workspace.ts',
}, [], 'test', {}, { fails: true })
expect(stderr).toContain(
- `Workspace config file "vitest.workspace.ts" references a non-existing file or a directory: ${resolve('fixtures/workspace/invalid-non-existing-config/vitest.config.js')}`,
+ `Projects definition references a non-existing file or a directory: ${resolve('fixtures/workspace/invalid-non-existing-config/vitest.config.js')}`,
)
})
it('vite import analysis is applied when loading workspace config', async () => {
const { stderr, stdout } = await runVitest({
root: 'fixtures/workspace/config-import-analysis',
- workspace: './fixtures/workspace/config-import-analysis/vitest.workspace.ts',
})
expect(stderr).toBe('')
expect(stdout).toContain('test - a')
@@ -97,7 +90,7 @@ it('can define inline workspace config programmatically', async () => {
env: {
TEST_ROOT: '1',
},
- workspace: [
+ projects: [
{
extends: true,
test: {
@@ -137,9 +130,9 @@ it('correctly inherits the root config', async () => {
it('fails if workspace is empty', async () => {
const { stderr } = await runVitest({
- workspace: [],
+ projects: [],
})
- expect(stderr).toContain('No projects were found. Make sure your configuration is correct. The workspace: [].')
+ expect(stderr).toContain('No projects were found. Make sure your configuration is correct. The projects definition: [].')
})
it('fails if workspace is filtered by the project', async () => {
@@ -147,11 +140,11 @@ it('fails if workspace is filtered by the project', async () => {
project: 'non-existing',
root: 'fixtures/workspace/config-empty',
config: './vitest.config.js',
- workspace: [
+ projects: [
'./vitest.config.js',
],
})
- expect(stderr).toContain(`No projects were found. Make sure your configuration is correct. The filter matched no projects: non-existing. The workspace: [
+ expect(stderr).toContain(`No projects were found. Make sure your configuration is correct. The filter matched no projects: non-existing. The projects definition: [
"./vitest.config.js"
].`)
})
diff --git a/test/core/vite.config.ts b/test/core/vite.config.ts
index 27dc7e604..a1bc6fed9 100644
--- a/test/core/vite.config.ts
+++ b/test/core/vite.config.ts
@@ -1,3 +1,5 @@
+import type { LabelColor } from 'vitest'
+import type { Pool } from 'vitest/node'
import { basename, dirname, join, resolve } from 'pathe'
import { defaultExclude, defineConfig } from 'vitest/config'
@@ -135,5 +137,20 @@ export default defineConfig({
return false
}
},
+ projects: [
+ project('threads', 'red'),
+ project('forks', 'green'),
+ project('vmThreads', 'blue'),
+ ],
},
})
+
+function project(pool: Pool, color: LabelColor) {
+ return {
+ extends: './vite.config.ts',
+ test: {
+ name: { label: pool, color },
+ pool,
+ },
+ }
+}
diff --git a/test/core/vitest.workspace.ts b/test/core/vitest.workspace.ts
deleted file mode 100644
index d53534d82..000000000
--- a/test/core/vitest.workspace.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- {
- extends: './vite.config.ts',
- test: {
- name: { label: 'threads', color: 'red' },
- pool: 'threads',
- },
- },
- {
- extends: './vite.config.ts',
- test: {
- name: { label: 'forks', color: 'green' },
- pool: 'forks',
- },
- },
- {
- extends: './vite.config.ts',
- test: {
- name: { label: 'vmThreads', color: 'blue' },
- pool: 'vmThreads',
- },
- },
-])
diff --git a/test/reporters/fixtures/better-testsuite-name/vitest.config.ts b/test/reporters/fixtures/better-testsuite-name/vitest.config.ts
index abed6b211..07c483f57 100644
--- a/test/reporters/fixtures/better-testsuite-name/vitest.config.ts
+++ b/test/reporters/fixtures/better-testsuite-name/vitest.config.ts
@@ -1,3 +1,7 @@
import { defineConfig } from 'vitest/config'
-export default defineConfig({})
+export default defineConfig({
+ test: {
+ projects: ['space-1', 'space-2'],
+ },
+})
diff --git a/test/reporters/fixtures/better-testsuite-name/vitest.workspace.ts b/test/reporters/fixtures/better-testsuite-name/vitest.workspace.ts
deleted file mode 100644
index 5e8b04b6b..000000000
--- a/test/reporters/fixtures/better-testsuite-name/vitest.workspace.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { defineWorkspace } from "vitest/config";
-
-export default defineWorkspace(['space-1', 'space-2'])
diff --git a/test/snapshots/test/fixtures/workspace/vitest.config.ts b/test/snapshots/test/fixtures/workspace/vitest.config.ts
new file mode 100644
index 000000000..d8625728b
--- /dev/null
+++ b/test/snapshots/test/fixtures/workspace/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig, defineWorkspace } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: ['packages/*'],
+ },
+})
diff --git a/test/snapshots/test/fixtures/workspace/vitest.workspace.ts b/test/snapshots/test/fixtures/workspace/vitest.workspace.ts
deleted file mode 100644
index b18a56c5a..000000000
--- a/test/snapshots/test/fixtures/workspace/vitest.workspace.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- 'packages/*',
-])
diff --git a/test/snapshots/test/snapshots.test.ts b/test/snapshots/test/snapshots.test.ts
index 1f07adf0d..f5e8b6123 100644
--- a/test/snapshots/test/snapshots.test.ts
+++ b/test/snapshots/test/snapshots.test.ts
@@ -23,7 +23,6 @@ test('--update works for workspace project', async () => {
const { stdout, exitCode } = await runVitest({
update: true,
root: 'test/fixtures/workspace',
- workspace: 'vitest.workspace.ts',
})
expect.soft(stdout).include('Snapshots 1 updated')
expect.soft(exitCode).toBe(0)
diff --git a/test/watch/test/change-project.test.ts b/test/watch/test/change-project.test.ts
index d38ee1544..64ed0373c 100644
--- a/test/watch/test/change-project.test.ts
+++ b/test/watch/test/change-project.test.ts
@@ -10,7 +10,7 @@ test('reruns tests when config changes', async () => {
export default {
test: {
- workspace: [
+ projects: [
'./project-1',
'./project-2',
],
diff --git a/test/workspaces-browser/vitest.config.ts b/test/workspaces-browser/vitest.config.ts
index 12cb29f9a..42166585d 100644
--- a/test/workspaces-browser/vitest.config.ts
+++ b/test/workspaces-browser/vitest.config.ts
@@ -11,5 +11,28 @@ export default defineConfig({
reporters: ['default', 'json'],
outputFile: './results.json',
globalSetup: './globalTest.ts',
+ projects: [
+ './space_*/*.config.ts',
+ {
+ test: {
+ name: 'space_browser_inline',
+ root: './space_browser_inline',
+ browser: {
+ enabled: true,
+ instances: [{ browser: process.env.BROWSER || 'chromium' }],
+ headless: true,
+ provider: process.env.PROVIDER || 'playwright',
+ },
+ alias: {
+ 'test-alias-from-vitest': new URL('./space_browser_inline/test-alias-to.ts', import.meta.url).pathname,
+ },
+ },
+ resolve: {
+ alias: {
+ 'test-alias-from-vite': new URL('./space_browser_inline/test-alias-to.ts', import.meta.url).pathname,
+ },
+ },
+ },
+ ],
},
})
diff --git a/test/workspaces-browser/vitest.workspace.ts b/test/workspaces-browser/vitest.workspace.ts
deleted file mode 100644
index f7736c2b3..000000000
--- a/test/workspaces-browser/vitest.workspace.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- './space_*/*.config.ts',
- {
- test: {
- name: 'space_browser_inline',
- root: './space_browser_inline',
- browser: {
- enabled: true,
- instances: [{ browser: process.env.BROWSER || 'chromium' }],
- headless: true,
- provider: process.env.PROVIDER || 'playwright',
- },
- alias: {
- 'test-alias-from-vitest': new URL('./space_browser_inline/test-alias-to.ts', import.meta.url).pathname,
- },
- },
- resolve: {
- alias: {
- 'test-alias-from-vite': new URL('./space_browser_inline/test-alias-to.ts', import.meta.url).pathname,
- },
- },
- },
-])
diff --git a/test/workspaces/space_3/vite.config.ts b/test/workspaces/space_3/vite.config.ts
index 824596396..1f7926b93 100644
--- a/test/workspaces/space_3/vite.config.ts
+++ b/test/workspaces/space_3/vite.config.ts
@@ -5,7 +5,7 @@ export default defineConfig({
{
name: 'throw-error',
config() {
- throw new Error('This file should not initiate a workspace project.')
+ throw new Error('This file should not initiate a test project.')
},
},
],
diff --git a/test/workspaces/vitest.config.ts b/test/workspaces/vitest.config.ts
index d6bbb3a1a..953ea057f 100644
--- a/test/workspaces/vitest.config.ts
+++ b/test/workspaces/vitest.config.ts
@@ -1,3 +1,6 @@
+import type { Vite } from 'vitest/node'
+import remapping from '@ampproject/remapping'
+import MagicString from 'magic-string'
import { defineConfig } from 'vitest/config'
import { cwdPlugin } from './cwdPlugin.js'
@@ -19,5 +22,161 @@ export default defineConfig({
provide: {
globalConfigValue: true,
},
+ projects: [
+
+ 'space_2',
+ './space_*/vitest.config.ts',
+ './space_1/*.config.ts',
+ async () => ({
+ test: {
+ name: 'happy-dom',
+ root: './space_shared',
+ environment: 'happy-dom',
+ setupFiles: ['./setup.jsdom.ts'],
+ provide: {
+ providedConfigValue: 'actual config value',
+ },
+ },
+ }),
+ Promise.resolve({
+ test: {
+ name: 'node',
+ root: './space_shared',
+ environment: 'node',
+ setupFiles: ['./setup.node.ts'],
+ },
+ }),
+
+ // Projects testing pool and poolOptions
+ {
+ test: {
+ name: 'Threads pool',
+ include: [
+ './space-pools/threads.test.ts',
+ './space-pools/multi-worker.test.ts',
+ './space-pools/isolate.test.ts',
+ ],
+ pool: 'threads',
+ },
+ },
+ {
+ test: {
+ name: 'Single thread pool',
+ include: [
+ './space-pools/threads.test.ts',
+ './space-pools/single-worker.test.ts',
+ ],
+ pool: 'threads',
+ poolOptions: { threads: { singleThread: true } },
+ },
+ },
+ {
+ test: {
+ name: 'Non-isolated thread pool #1',
+ include: [
+ './space-pools/threads.test.ts',
+ './space-pools/no-isolate.test.ts',
+ ],
+ pool: 'threads',
+ poolOptions: { threads: { isolate: false } },
+ },
+ },
+ {
+ test: {
+ name: 'Non-isolated thread pool #2',
+ include: [
+ './space-pools/threads.test.ts',
+ './space-pools/no-isolate.test.ts',
+ ],
+ pool: 'threads',
+ isolate: false,
+ },
+ },
+ {
+ test: {
+ name: 'Forks pool',
+ include: [
+ './space-pools/forks.test.ts',
+ './space-pools/multi-worker.test.ts',
+ './space-pools/isolate.test.ts',
+ ],
+ pool: 'forks',
+ },
+ },
+ {
+ test: {
+ name: 'Single fork pool',
+ include: [
+ './space-pools/forks.test.ts',
+ './space-pools/single-worker.test.ts',
+ ],
+ pool: 'forks',
+ poolOptions: { forks: { singleFork: true } },
+ },
+ },
+ {
+ test: {
+ name: 'Non-isolated fork pool #1',
+ include: [
+ './space-pools/forks.test.ts',
+ './space-pools/no-isolate.test.ts',
+ ],
+ pool: 'forks',
+ poolOptions: { forks: { isolate: false } },
+ },
+ },
+ {
+ test: {
+ name: 'Non-isolated fork pool #2',
+ include: [
+ './space-pools/forks.test.ts',
+ './space-pools/no-isolate.test.ts',
+ ],
+ pool: 'forks',
+ isolate: false,
+ },
+ },
+
+ // These two projects run on same environment but still transform
+ // a single file differently due to Vite plugins
+ {
+ plugins: [customPlugin(0)],
+ test: {
+ name: 'Project with custom plugin #1',
+ environment: 'node',
+ include: ['./space-multi-transform/test/project-1.test.ts'],
+ },
+ },
+ {
+ plugins: [customPlugin(15)],
+ test: {
+ name: 'Project with custom plugin #2',
+ environment: 'node',
+ include: ['./space-multi-transform/test/project-2.test.ts'],
+ },
+ },
+ ],
},
})
+
+function customPlugin(offset: number): Vite.Plugin {
+ return {
+ name: 'vitest-custom-multi-transform',
+ enforce: 'pre',
+ transform(code, id) {
+ if (id.includes('space-multi-transform/src/multi-transform.ts')) {
+ const padding = '\n*****'.repeat(offset)
+
+ const transformed = new MagicString(code)
+ transformed.replace('\'default-padding\'', `\`${padding}\``)
+
+ const map = remapping(
+ [transformed.generateMap({ hires: true }), this.getCombinedSourcemap() as any],
+ () => null,
+ ) as any
+
+ return { code: transformed.toString(), map }
+ }
+ },
+ }
+}
diff --git a/test/workspaces/vitest.workspace.ts b/test/workspaces/vitest.workspace.ts
deleted file mode 100644
index 077de9814..000000000
--- a/test/workspaces/vitest.workspace.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-import type { Plugin } from 'vite'
-import remapping from '@ampproject/remapping'
-import MagicString from 'magic-string'
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- 'space_2',
- './space_*/vitest.config.ts',
- './space_1/*.config.ts',
- async () => ({
- test: {
- name: 'happy-dom',
- root: './space_shared',
- environment: 'happy-dom',
- setupFiles: ['./setup.jsdom.ts'],
- provide: {
- providedConfigValue: 'actual config value',
- },
- },
- }),
- Promise.resolve({
- test: {
- name: 'node',
- root: './space_shared',
- environment: 'node',
- setupFiles: ['./setup.node.ts'],
- },
- }),
-
- // Projects testing pool and poolOptions
- {
- test: {
- name: 'Threads pool',
- include: [
- './space-pools/threads.test.ts',
- './space-pools/multi-worker.test.ts',
- './space-pools/isolate.test.ts',
- ],
- pool: 'threads',
- },
- },
- {
- test: {
- name: 'Single thread pool',
- include: [
- './space-pools/threads.test.ts',
- './space-pools/single-worker.test.ts',
- ],
- pool: 'threads',
- poolOptions: { threads: { singleThread: true } },
- },
- },
- {
- test: {
- name: 'Non-isolated thread pool #1',
- include: [
- './space-pools/threads.test.ts',
- './space-pools/no-isolate.test.ts',
- ],
- pool: 'threads',
- poolOptions: { threads: { isolate: false } },
- },
- },
- {
- test: {
- name: 'Non-isolated thread pool #2',
- include: [
- './space-pools/threads.test.ts',
- './space-pools/no-isolate.test.ts',
- ],
- pool: 'threads',
- isolate: false,
- },
- },
- {
- test: {
- name: 'Forks pool',
- include: [
- './space-pools/forks.test.ts',
- './space-pools/multi-worker.test.ts',
- './space-pools/isolate.test.ts',
- ],
- pool: 'forks',
- },
- },
- {
- test: {
- name: 'Single fork pool',
- include: [
- './space-pools/forks.test.ts',
- './space-pools/single-worker.test.ts',
- ],
- pool: 'forks',
- poolOptions: { forks: { singleFork: true } },
- },
- },
- {
- test: {
- name: 'Non-isolated fork pool #1',
- include: [
- './space-pools/forks.test.ts',
- './space-pools/no-isolate.test.ts',
- ],
- pool: 'forks',
- poolOptions: { forks: { isolate: false } },
- },
- },
- {
- test: {
- name: 'Non-isolated fork pool #2',
- include: [
- './space-pools/forks.test.ts',
- './space-pools/no-isolate.test.ts',
- ],
- pool: 'forks',
- isolate: false,
- },
- },
-
- // These two projects run on same environment but still transform
- // a single file differently due to Vite plugins
- {
- plugins: [customPlugin(0)],
- test: {
- name: 'Project with custom plugin #1',
- environment: 'node',
- include: ['./space-multi-transform/test/project-1.test.ts'],
- },
- },
- {
- plugins: [customPlugin(15)],
- test: {
- name: 'Project with custom plugin #2',
- environment: 'node',
- include: ['./space-multi-transform/test/project-2.test.ts'],
- },
- },
-])
-
-function customPlugin(offset: number): Plugin {
- return {
- name: 'vitest-custom-multi-transform',
- enforce: 'pre',
- transform(code, id) {
- if (id.includes('space-multi-transform/src/multi-transform.ts')) {
- const padding = '\n*****'.repeat(offset)
-
- const transformed = new MagicString(code)
- transformed.replace('\'default-padding\'', `\`${padding}\``)
-
- const map = remapping(
- [transformed.generateMap({ hires: true }), this.getCombinedSourcemap() as any],
- () => null,
- ) as any
-
- return { code: transformed.toString(), map }
- }
- },
- }
-}