fix(mocker): hoist vi.mock() for vite-plus/test imports (#10489) · vitest-dev/vitest@8837664 (original) (raw)

Original file line number Diff line number Diff line change
@@ -83,6 +83,12 @@ const regexpHoistable
83 83 = /\b(?:vi|vitest)\s*\.\s*(?:mock
84 84 const hashbangRE = /^#!.*\n/
85 85
86 +// Public redistributions of Vitest that re-export its mocking API (`vi`)
87 +// verbatim under their own specifier. Imports from these are treated as the
88 +// hoisted module so `vi.mock()` is hoisted for e.g.
89 +// `import { vi } from 'vite-plus/test'`, exactly as it is for `vitest`.
90 +const REDISTRIBUTED_HOISTED_MODULES = ['vite-plus/test']
91 +
86 92 // this is a fork of Vite SSR transform
87 93 export function hoistMocks(
88 94 code: string,
@@ -141,8 +147,9 @@ export function hoistMocks(
141 147 ) {
142 148 const source = importNode.source.value as string
143 149 // always hoist vitest import to top of the file, so
144 -// "vi" helpers can access it
145 -if (hoistedModule === source) {
150 +// "vi" helpers can access it. Vitest redistributions that re-export the
151 +// mocking API under their own specifier are recognized the same way.
152 +if (hoistedModule === source |
146 153 hoistedModuleImported = true
147 154 return
148 155 }
Original file line number Diff line number Diff line change
@@ -60,6 +60,21 @@ import { test } from 'vitest'
60 60 `)
61 61 })
62 62
63 +test('recognizes the vite-plus/test redistribution as the hoisted module', () => {
64 +expect(hoistSimpleCode(`
65 +import { vi } from 'vite-plus/test'
66 +vi.mock('path', () => {})
67 +vi.unmock('path')
68 +vi.hoisted(() => {})
69 + `)).toMatchInlineSnapshot(`
70 + "vi.mock('path', () => {})
71 + vi.unmock('path')
72 + vi.hoisted(() => {})
73 +
74 + import { vi } from 'vite-plus/test'"
75 + `)
76 +})
77 +
63 78 test('always hoists all imports but they are under mocks', () => {
64 79 expect(hoistSimpleCode(`
65 80 import { vi } from 'vitest'