Skip to content

Commit

Permalink
feat: add vi.resetModules (#1102)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Apr 6, 2022
1 parent c4a25ae commit eb13d34
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 4 deletions.
25 changes: 25 additions & 0 deletions docs/api/index.md
Expand Up @@ -1483,6 +1483,31 @@ Vitest provides utility functions to help you out through it's **vi** helper. Yo

Imports a module with all of its properties (including nested properties) mocked. Follows the same rules that [`vi.mock`](#vi-mock) follows. For the rules applied, see [algorithm](/guide/mocking#automocking-algorithm).

### vi.resetModules

- **Type**: `() => Vitest`

Resets modules registry by clearing cache of all modules. Might be useful to isolate modules where local state conflicts between tests.

```ts
import { vi } from 'vitest'

beforeAll(() => {
vi.resetModules()
})

test('change state', async() => {
const mod = await import('./some/path')
mod.changeLocalState('new value')
expect(mod.getlocalState()).toBe('new value')
})

test('module has old state', async() => {
const mod = await import('./some/path')
expect(mod.getlocalState()).toBe('old value')
})
```

### vi.restoreCurrentDate

- **Type**: `() => void`
Expand Down
6 changes: 6 additions & 0 deletions packages/vitest/src/integrations/vi.ts
Expand Up @@ -2,6 +2,7 @@

import { parseStacktrace } from '../utils/source-map'
import type { VitestMocker } from '../runtime/mocker'
import { resetModules } from '../utils'
import { FakeTimers } from './timers'
import type { EnhancedSpy, MaybeMocked, MaybeMockedDeep } from './spy'
import { fn, isMockFunction, spies, spyOn } from './spy'
Expand Down Expand Up @@ -210,6 +211,11 @@ class VitestUtils {

return this
}

public resetModules() {
resetModules()
return this
}
}

export const vitest = new VitestUtils()
Expand Down
8 changes: 4 additions & 4 deletions packages/vitest/src/runtime/entry.ts
@@ -1,6 +1,6 @@
import { promises as fs } from 'fs'
import type { BuiltinEnvironment, ResolvedConfig } from '../types'
import { getWorkerState } from '../utils'
import { getWorkerState, resetModules } from '../utils'
import { setupGlobalEnv, withEnv } from './setup'
import { startTests } from './run'

Expand All @@ -9,10 +9,10 @@ export async function run(files: string[], config: ResolvedConfig): Promise<void

const workerState = getWorkerState()

// reset mock state
workerState.mockMap.clear()

for (const file of files) {
workerState.mockMap.clear()
resetModules()

const code = await fs.readFile(file, 'utf-8')

const env = code.match(/@(?:vitest|jest)-environment\s+?([\w-]+)\b/)?.[1] || config.environment || 'node'
Expand Down
18 changes: 18 additions & 0 deletions packages/vitest/src/utils/index.ts
Expand Up @@ -2,6 +2,7 @@ import c from 'picocolors'
import { isPackageExists } from 'local-pkg'
import { resolve } from 'pathe'
import type { Suite, Task } from '../types'
import { getWorkerState } from '../utils/global'
import { getNames } from './tasks'

export * from './tasks'
Expand Down Expand Up @@ -32,6 +33,23 @@ export function partitionSuiteChildren(suite: Suite) {
return tasksGroups
}

export function resetModules() {
const modules = getWorkerState().moduleCache
const vitestPaths = [
// Vitest
/\/vitest\/dist\//,
// yarn's .store folder
/vitest-virtual-\w+\/dist/,
// cnpm
/@vitest\/dist/,
]
modules.forEach((_, path) => {
if (vitestPaths.some(re => re.test(path)))
return
modules.delete(path)
})
}

export function getFullName(task: Task) {
return getNames(task).join(c.dim(' > '))
}
Expand Down
16 changes: 16 additions & 0 deletions test/core/test/vi.spec.ts
Expand Up @@ -12,4 +12,20 @@ describe('testing vi utils', () => {
expect(window.IntersectionObserver).toBe(IntersectionObserverMock)
expect(IntersectionObserver).toBe(IntersectionObserverMock)
})

test('reseting modules', async() => {
const mod1 = await import('../src/env')
vi.resetModules()
const mod2 = await import('../src/env')
const mod3 = await import('../src/env')
expect(mod1).not.toBe(mod2)
expect(mod2).toBe(mod3)
})

test('reseting modules doesnt reset vitest', async() => {
const v1 = await import('vitest')
vi.resetModules()
const v2 = await import('vitest')
expect(v1).toBe(v2)
})
})

0 comments on commit eb13d34

Please sign in to comment.