diff --git a/packages/vitest/src/index.ts b/packages/vitest/src/index.ts index b951f9c3964b..3406920122f2 100644 --- a/packages/vitest/src/index.ts +++ b/packages/vitest/src/index.ts @@ -5,7 +5,7 @@ import type { Constructable, InlineConfig } from './types' export { suite, test, describe, it } from './runtime/suite' export * from './runtime/hooks' -export { runOnce } from './integrations/run-once' +export { runOnce, isFirstRun } from './integrations/run-once' export * from './integrations/chai' export * from './integrations/jest-mock' export * from './integrations/vi' diff --git a/packages/vitest/src/integrations/run-once.ts b/packages/vitest/src/integrations/run-once.ts index 379e76e6df41..52e391a47d04 100644 --- a/packages/vitest/src/integrations/run-once.ts +++ b/packages/vitest/src/integrations/run-once.ts @@ -1,4 +1,3 @@ -import type { Awaitable } from '../types' import { getWorkerState } from '../utils' const filesCount = new Map() @@ -12,18 +11,36 @@ const cache = new Map() * * @experimental */ -export async function runOnce(fn: (() => Awaitable), key?: string): Promise { +export function runOnce(fn: (() => T), key?: string): T { + const filepath = getWorkerState().filepath || '__unknown_files__' + if (!key) { - const filepath = getWorkerState().filepath || '__unknown_files__' filesCount.set(filepath, (filesCount.get(filepath) || 0) + 1) - const count = filesCount.get(filepath)! - key = `${filepath}:${count}` + key = String(filesCount.get(filepath)!) } - if (!cache.has(key)) - cache.set(key, fn()) + const id = `${filepath}:${key}` + + if (!cache.has(id)) + cache.set(id, fn()) - return await cache.get(key) + return cache.get(id) +} + +/** + * Get a boolean indicates whether the task is running in the first time. + * Could only be `false` in watch mode. + * + * Currently only works with `isolate: false` + * + * @experimental + */ +export function isFirstRun() { + let firstRun = false + runOnce(() => { + firstRun = true + }, '__vitest_first_run__') + return firstRun } /** diff --git a/test/run-once/test/run-once.test.ts b/test/run-once/test/run-once.test.ts index 5f80bc7cab20..55319c775992 100644 --- a/test/run-once/test/run-once.test.ts +++ b/test/run-once/test/run-once.test.ts @@ -1,8 +1,8 @@ -import { expect, it, runOnce } from 'vitest' +import { expect, isFirstRun, it, runOnce } from 'vitest' let dummy = 0 -const one = await runOnce(() => { +const one = runOnce(() => { dummy += 1 return 1 }) @@ -12,10 +12,15 @@ const two = await runOnce(async() => { return 2 }) -it('run once', async() => { +it('runOnce', async() => { expect(one).toBe(1) expect(two).toBe(2) // edit the file to trigger the hmr and dummy should be 0 expect(dummy).toBe(2) }) + +it('isFirstRun', () => { + // edit the file and this will fail + expect(isFirstRun()).toBe(true) +})