From 3fbd62516ea76d41b448f6e74a2784605e1fb5e1 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 11 Mar 2025 15:04:08 +0100 Subject: [PATCH 1/3] feat(vitest): allow conditional context.skip(boolean) --- docs/api/index.md | 12 ++++++++++++ packages/runner/src/context.ts | 12 ++++++++++-- packages/runner/src/types/tasks.ts | 5 ++++- test/cli/fixtures/fails/skip-conditional.test.ts | 11 +++++++++++ test/cli/test/__snapshots__/fails.test.ts.snap | 2 ++ test/reporters/fixtures/default/a.test.ts | 14 ++++++++++++++ test/reporters/tests/default.test.ts | 10 ++++++---- 7 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 test/cli/fixtures/fails/skip-conditional.test.ts diff --git a/docs/api/index.md b/docs/api/index.md index 729ca7576b3d..5536f5271b57 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -129,6 +129,18 @@ test('skipped test', (context) => { }) ``` +Since Vitest 3.1, if the condition is unknonwn, you can provide it to the `skip` method as the first arguments: + +```ts +import { assert, test } from 'vitest' + +test('skipped test', (context) => { + context.skip(Math.random() < 0.5, 'optional message') + // Test skipped, no error + assert.equal(Math.sqrt(4), 3) +}) +``` + ### test.skipIf - **Alias:** `it.skipIf` diff --git a/packages/runner/src/context.ts b/packages/runner/src/context.ts index 8c08d3f15db5..8cb383653f5b 100644 --- a/packages/runner/src/context.ts +++ b/packages/runner/src/context.ts @@ -104,10 +104,18 @@ export function createTestContext( context.task = test - context.skip = (note?: string) => { + context.skip = (condition?: boolean | string, note?: string): never => { + if (typeof condition === 'boolean' && !condition) { + // do nothing + return undefined as never + } test.result ??= { state: 'skip' } test.result.pending = true - throw new PendingError('test is skipped; abort execution', test, note) + throw new PendingError( + 'test is skipped; abort execution', + test, + typeof condition === 'string' ? condition : note, + ) } context.onTestFailed = (handler, timeout) => { diff --git a/packages/runner/src/types/tasks.ts b/packages/runner/src/types/tasks.ts index 1a27d9632507..4b3819144dc6 100644 --- a/packages/runner/src/types/tasks.ts +++ b/packages/runner/src/types/tasks.ts @@ -658,7 +658,10 @@ export interface TestContext { * Mark tests as skipped. All execution after this call will be skipped. * This function throws an error, so make sure you are not catching it accidentally. */ - skip: (note?: string) => never + skip: { + (note?: string): never + (condition: boolean, note?: string): void + } } /** diff --git a/test/cli/fixtures/fails/skip-conditional.test.ts b/test/cli/fixtures/fails/skip-conditional.test.ts new file mode 100644 index 000000000000..6431f6c4ff01 --- /dev/null +++ b/test/cli/fixtures/fails/skip-conditional.test.ts @@ -0,0 +1,11 @@ +import { expect, it } from 'vitest'; + +it('skips correctly', (t) => { + t.skip(true) + expect.unreachable() +}) + +it('doesnt skip correctly', (t) => { + t.skip(false) + throw new Error('doesnt skip') +}) diff --git a/test/cli/test/__snapshots__/fails.test.ts.snap b/test/cli/test/__snapshots__/fails.test.ts.snap index 5864f8e17f68..d784425a9b72 100644 --- a/test/cli/test/__snapshots__/fails.test.ts.snap +++ b/test/cli/test/__snapshots__/fails.test.ts.snap @@ -74,6 +74,8 @@ Error: expect.poll(assertion).toBe() was not awaited. This assertion is asynchro exports[`should fail primitive-error.test.ts 1`] = `"Unknown Error: 42"`; +exports[`should fail skip-conditional.test.ts 1`] = `"Error: doesnt skip"`; + exports[`should fail snapshot-with-not.test.ts 1`] = ` "Error: toThrowErrorMatchingInlineSnapshot cannot be used with "not" Error: toThrowErrorMatchingSnapshot cannot be used with "not" diff --git a/test/reporters/fixtures/default/a.test.ts b/test/reporters/fixtures/default/a.test.ts index 16cabf106810..8f60d69aee9d 100644 --- a/test/reporters/fixtures/default/a.test.ts +++ b/test/reporters/fixtures/default/a.test.ts @@ -24,3 +24,17 @@ describe('a failed', () => { }) }) }) + +describe('a skipped', () => { + test('skipped with note', (t) => { + t.skip('reason') + }) + + test('condition', (t) => { + t.skip(true) + }) + + test('condition with note', (t) => { + t.skip(true, 'note') + }) +}) diff --git a/test/reporters/tests/default.test.ts b/test/reporters/tests/default.test.ts index 4075d1620764..b78a7ed1dad8 100644 --- a/test/reporters/tests/default.test.ts +++ b/test/reporters/tests/default.test.ts @@ -67,10 +67,12 @@ describe('default reporter', async () => { reporters: 'none', }) - expect(stdout).contain('✓ a passed > a1 test') - expect(stdout).contain('✓ a passed > nested a > nested a3 test') - expect(stdout).contain('× a failed > a failed test') - expect(stdout).contain('nested a failed 1 test') + expect(stdout).toContain('✓ a passed > a1 test') + expect(stdout).toContain('✓ a passed > nested a > nested a3 test') + expect(stdout).toContain('× a failed > a failed test') + expect(stdout).toContain('nested a failed 1 test') + expect(stdout).toContain('[note]') + expect(stdout).toContain('[reason]') }) test('rerun should undo', async () => { From d34f96303b011c8ce12a717afe69004e00ba9716 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 11 Mar 2025 15:13:57 +0100 Subject: [PATCH 2/3] test: fix test --- test/reporters/tests/junit.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/reporters/tests/junit.test.ts b/test/reporters/tests/junit.test.ts index c4cf2d431e0a..dd5310b055fe 100644 --- a/test/reporters/tests/junit.test.ts +++ b/test/reporters/tests/junit.test.ts @@ -120,8 +120,8 @@ test('options.classname changes classname property', async () => { // All classname attributes should have the custom value expect(xml.match(/ { From 3dcf6f9fa9ba8ce3d944f79fd8ed10fb14cddd06 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Tue, 11 Mar 2025 17:19:23 +0100 Subject: [PATCH 3/3] Update packages/runner/src/context.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ari Perkkiö --- packages/runner/src/context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runner/src/context.ts b/packages/runner/src/context.ts index 8cb383653f5b..a816fcc96be2 100644 --- a/packages/runner/src/context.ts +++ b/packages/runner/src/context.ts @@ -105,7 +105,7 @@ export function createTestContext( context.task = test context.skip = (condition?: boolean | string, note?: string): never => { - if (typeof condition === 'boolean' && !condition) { + if (condition === false) { // do nothing return undefined as never }