Skip to content

Commit

Permalink
feat: new setupOnce utils (#967)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Mar 17, 2022
1 parent 96517f5 commit 8a25a78
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 9 deletions.
3 changes: 2 additions & 1 deletion packages/vitest/src/index.ts
Expand Up @@ -3,8 +3,9 @@ import type { MatcherState, MatchersObject } from './integrations/chai/types'
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 * from './integrations/chai'
export * from './integrations/jest-mock'
export * from './integrations/vi'
Expand Down
34 changes: 34 additions & 0 deletions packages/vitest/src/integrations/run-once.ts
@@ -0,0 +1,34 @@
import type { Awaitable } from '../types'
import { getWorkerState } from '../utils'

const filesCount = new Map<string, number>()
const cache = new Map<string, any>()

/**
* This utils allows computational intensive tasks to only be ran once
* across test reruns to improve the watch mode performance.
*
* Currently only works with `isolate: false`
*
* @experimental
*/
export async function runOnce<T>(fn: (() => Awaitable<T>), key?: string): Promise<T> {
if (!key) {
const filepath = getWorkerState().filepath || '__unknown_files__'
filesCount.set(filepath, (filesCount.get(filepath) || 0) + 1)
const count = filesCount.get(filepath)!
key = `${filepath}:${count}`
}

if (!cache.has(key))
cache.set(key, fn())

return await cache.get(key)
}

/**
* @internal
*/
export function resetRunOnceCounter() {
filesCount.clear()
}
3 changes: 3 additions & 0 deletions packages/vitest/src/runtime/setup.ts
Expand Up @@ -4,10 +4,13 @@ import { environments } from '../integrations/env'
import type { ResolvedConfig } from '../types'
import { getWorkerState, toArray } from '../utils'
import * as VitestIndex from '../index'
import { resetRunOnceCounter } from '../integrations/run-once'
import { rpc } from './rpc'

let globalSetup = false
export async function setupGlobalEnv(config: ResolvedConfig) {
resetRunOnceCounter()

Object.defineProperty(globalThis, '__vitest_index__', {
value: VitestIndex,
enumerable: false,
Expand Down
20 changes: 13 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion test/core/vitest.config.ts
Expand Up @@ -38,7 +38,6 @@ export default defineConfig({
},
test: {
testTimeout: 2000,
// threads: false,
setupFiles: [
'./test/setup.ts',
],
Expand Down
11 changes: 11 additions & 0 deletions test/run-once/package.json
@@ -0,0 +1,11 @@
{
"name": "@vitest/test-run-once",
"private": true,
"scripts": {
"test": "vitest",
"coverage": "vitest run --coverage"
},
"devDependencies": {
"vitest": "workspace:*"
}
}
21 changes: 21 additions & 0 deletions test/run-once/test/run-once.test.ts
@@ -0,0 +1,21 @@
import { expect, it, runOnce } from 'vitest'

let dummy = 0

const one = await runOnce(() => {
dummy += 1
return 1
})

const two = await runOnce(async() => {
dummy += 1
return 2
})

it('run once', 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)
})
7 changes: 7 additions & 0 deletions test/run-once/vitest.config.ts
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'

export default defineConfig({
test: {
isolate: false,
},
})

0 comments on commit 8a25a78

Please sign in to comment.