diff --git a/docs/config/index.md b/docs/config/index.md index cb8b8eacc7ac..9b8322239046 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -372,9 +372,9 @@ Glob pattern of file paths to be ignored from triggering watch rerun. ### forceRerunTriggers - **Type**: `string[]` -- **Default:** `[]` +- **Default:** `['**/package.json/**', '**/vitest.config.*/**', '**/vite.config.*/**']` -Glob patter of file paths that will trigger the whole suite rerun. +Glob pattern of file paths that will trigger the whole suite rerun. When paired with the `--changed` argument will run the whole test suite if the trigger is found in the git diff. Useful if you are testing calling CLI commands, because Vite cannot construct a module graph: diff --git a/docs/guide/cli.md b/docs/guide/cli.md index e43fccc19775..7777795025b7 100644 --- a/docs/guide/cli.md +++ b/docs/guide/cli.md @@ -83,6 +83,8 @@ Clears cache folder. To run tests against changes made in the last commit, you can use `--changed HEAD~1`. You can also pass commit hash or branch name. + If paired with the `forceRerunTriggers` config option it will run the whole test suite if a match is found. + ### shard - **Type**: `string` diff --git a/packages/vitest/src/defaults.ts b/packages/vitest/src/defaults.ts index d757080c296a..71bd641ac6c6 100644 --- a/packages/vitest/src/defaults.ts +++ b/packages/vitest/src/defaults.ts @@ -62,7 +62,11 @@ const config = { hookTimeout: 10000, isolate: true, watchExclude: ['**/node_modules/**', '**/dist/**'], - forceRerunTriggers: [], + forceRerunTriggers: [ + '**/package.json/**', + '**/vitest.config.*/**', + '**/vite.config.*/**', + ], update: false, reporters: [], silent: false, diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index d31b0c1e1505..108d1a44126c 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -189,6 +189,10 @@ export class Vitest { if (!related) return tests + const forceRerunTriggers = this.config.forceRerunTriggers + if (forceRerunTriggers.length && mm(related, forceRerunTriggers).length) + return tests + // don't run anything if no related sources are found if (!related.length) return [] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index da25c0660e89..3acdc0234731 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -848,8 +848,10 @@ importers: test/related: specifiers: + execa: ^6.1.0 vitest: workspace:* devDependencies: + execa: 6.1.0 vitest: link:../../packages/vitest test/reporters: diff --git a/test/related/force-rerun.vitest.config.ts b/test/related/force-rerun.vitest.config.ts new file mode 100644 index 000000000000..024909c6a773 --- /dev/null +++ b/test/related/force-rerun.vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + include: ['tests/related.test.ts'], + forceRerunTriggers: ['**/rerun.temp/**'], + }, +}) diff --git a/test/related/package.json b/test/related/package.json index c063a9e6e04c..1d0653ebf985 100644 --- a/test/related/package.json +++ b/test/related/package.json @@ -2,9 +2,12 @@ "name": "@vitest/test-related", "private": true, "scripts": { - "test": "vitest related src/sourceA.ts --globals" + "test": "nr test:related && nr test:rerun", + "test:related": "vitest related src/sourceA.ts --globals --watch=false", + "test:rerun": "vitest run rerun" }, "devDependencies": { + "execa": "^6.1.0", "vitest": "workspace:*" } } diff --git a/test/related/tests/force-rerun.test.ts b/test/related/tests/force-rerun.test.ts new file mode 100644 index 000000000000..420c15269023 --- /dev/null +++ b/test/related/tests/force-rerun.test.ts @@ -0,0 +1,24 @@ +import { unlink, writeFile } from 'fs' +import { beforeEach, describe, expect, it } from 'vitest' +import { execa } from 'execa' + +const run = async () => await execa('vitest', ['run', '--changed', '--config', 'force-rerun.vitest.config.ts']) + +const fileName = 'rerun.temp' + +describe('forceRerunTrigger', () => { + beforeEach(async () => { + unlink(fileName, () => {}) + }) + + it('should run the whole test suite if file exists', async () => { + writeFile(fileName, '', () => {}) + const { stdout } = await run() + expect(stdout).toContain('1 passed') + }, 60_000) + + it('should run no tests if file does not exist', async () => { + const { stdout } = await run() + expect(stdout).toContain('No test files found, exiting with code 0') + }, 60_000) +})