diff --git a/eslint.config.js b/eslint.config.js index 0cbb5e635..ab0243ed4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -15,6 +15,7 @@ export default antfu( '**/*.d.ts', '**/*.timestamp-*', 'test/core/src/self', + 'test/core/test/mocking/already-hoisted.test.ts', 'test/cache/cache/.vitest-base/results.json', 'test/core/src/wasm/wasm-bindgen-no-cyclic', 'test/workspaces/results.json', diff --git a/packages/mocker/src/node/hoistMocksPlugin.ts b/packages/mocker/src/node/hoistMocksPlugin.ts index 49edea0b3..7d4d0ae3c 100644 --- a/packages/mocker/src/node/hoistMocksPlugin.ts +++ b/packages/mocker/src/node/hoistMocksPlugin.ts @@ -498,11 +498,11 @@ export function hoistMocks( // hoist vi.mock/vi.hoisted for (const node of hoistedNodes) { const end = getNodeTail(code, node) - if (hoistIndex === end) { + // don't hoist into itself if it's already at the top + if (hoistIndex === end || hoistIndex === node.start) { hoistIndex = end } - // don't hoist into itself if it's already at the top - else if (hoistIndex !== node.start) { + else { s.move(node.start, end, hoistIndex) } } diff --git a/test/core/test/injector-mock.test.ts b/test/core/test/injector-mock.test.ts index 22b43a8fc..a21dabe81 100644 --- a/test/core/test/injector-mock.test.ts +++ b/test/core/test/injector-mock.test.ts @@ -1273,6 +1273,29 @@ test('test', async () => { `) }) + test('vi.mock already hoisted at the top', () => { + expect( + hoistSimpleCode(`\ +vi.mock('node:path', () => ({ mocked: true })); + +import { test, vi } from 'vitest'; + +import * as path from 'node:path'; + +console.log(path.mocked); +`), + ).toMatchInlineSnapshot(` + "vi.mock('node:path', () => ({ mocked: true })); + const __vi_import_0__ = await import("node:path"); + + import { test, vi } from 'vitest'; + + + + console.log(__vi_import_0__.mocked);" + `) + }) + test('correctly hoists when import.meta is used', () => { expect(hoistSimpleCode(` import { calc } from './calc' diff --git a/test/core/test/mocking/already-hoisted.test.ts b/test/core/test/mocking/already-hoisted.test.ts new file mode 100644 index 000000000..d7c522e62 --- /dev/null +++ b/test/core/test/mocking/already-hoisted.test.ts @@ -0,0 +1,9 @@ +vi.mock('node:path', () => ({ mocked: true })) + +import { expect, test, vi } from 'vitest' + +import * as path from 'node:path' + +test('already hoisted', () => { + expect(path).toHaveProperty('mocked', true) +})