From f4afce17ddc33e54a612e93763bea905a5e8e155 Mon Sep 17 00:00:00 2001 From: Misery Lee Date: Thu, 17 Aug 2023 07:59:11 +0000 Subject: [PATCH 1/4] fix: should remove mockPath from callstack whether success or failed --- packages/vitest/src/runtime/mocker.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/vitest/src/runtime/mocker.ts b/packages/vitest/src/runtime/mocker.ts index adfd9485e981..43df959cb4a2 100644 --- a/packages/vitest/src/runtime/mocker.ts +++ b/packages/vitest/src/runtime/mocker.ts @@ -423,11 +423,13 @@ export class VitestMocker { return exports } if (typeof mock === 'function' && !callstack.includes(mockPath) && !callstack.includes(url)) { - callstack.push(mockPath) - const result = await this.callFunctionMock(mockPath, mock) - const indexMock = callstack.indexOf(mockPath) - callstack.splice(indexMock, 1) - return result + try { + callstack.push(mockPath) + return await this.callFunctionMock(mockPath, mock) + } finally { + const indexMock = callstack.indexOf(mockPath) + callstack.splice(indexMock, 1) + } } if (typeof mock === 'string' && !callstack.includes(mock)) return mock From b7bfe12aadc8b0110e5720693fd927dd7d843f4e Mon Sep 17 00:00:00 2001 From: lijifei Date: Thu, 17 Aug 2023 20:55:43 +0800 Subject: [PATCH 2/4] test: add test unit for mock issue --- examples/mocks/src/dynamic-module.ts | 1 + examples/mocks/src/retry-dynamic-import.ts | 17 +++++++++++++++++ .../mocks/test/retry-dynamic-import.test.ts | 17 +++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 examples/mocks/src/dynamic-module.ts create mode 100644 examples/mocks/src/retry-dynamic-import.ts create mode 100644 examples/mocks/test/retry-dynamic-import.test.ts diff --git a/examples/mocks/src/dynamic-module.ts b/examples/mocks/src/dynamic-module.ts new file mode 100644 index 000000000000..336ce12bb910 --- /dev/null +++ b/examples/mocks/src/dynamic-module.ts @@ -0,0 +1 @@ +export {} diff --git a/examples/mocks/src/retry-dynamic-import.ts b/examples/mocks/src/retry-dynamic-import.ts new file mode 100644 index 000000000000..727699adbf5c --- /dev/null +++ b/examples/mocks/src/retry-dynamic-import.ts @@ -0,0 +1,17 @@ +export async function retryDynamicImport() { + let retryTimes = 0 + const load = async () => { + try { // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + return await import('./dynamic-module') + } + catch (e) { + if (retryTimes === 3) + throw new Error('import dynamic module failed.') + retryTimes += 1 + return await load() + } + } + + return await load() +} diff --git a/examples/mocks/test/retry-dynamic-import.test.ts b/examples/mocks/test/retry-dynamic-import.test.ts new file mode 100644 index 000000000000..8aa7ee1922e4 --- /dev/null +++ b/examples/mocks/test/retry-dynamic-import.test.ts @@ -0,0 +1,17 @@ +import { retryDynamicImport } from '../src/retry-dynamic-import' + +vi.mock('../src/dynamic-module', () => { + return { foo: 'bar' } +}) + +describe('retry-dynamic-import', () => { + it('should dynamic import module success', async () => { + expect(await retryDynamicImport()).toEqual({ foo: 'bar' }) + }) + it('should throw when retry over 3 times', async () => { + vi.doMock('../src/dynamic-module', () => { + throw new Error('foobar') + }) + await expect(retryDynamicImport()).rejects.toThrowError(new Error('import dynamic module failed.')) + }) +}) From 6588390c458017ab6f785fbcd20d0b148b3d5d22 Mon Sep 17 00:00:00 2001 From: lijifei Date: Fri, 18 Aug 2023 10:57:26 +0800 Subject: [PATCH 3/4] chore: fix lint issue --- packages/vitest/src/runtime/mocker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/vitest/src/runtime/mocker.ts b/packages/vitest/src/runtime/mocker.ts index 43df959cb4a2..908581ed2fa5 100644 --- a/packages/vitest/src/runtime/mocker.ts +++ b/packages/vitest/src/runtime/mocker.ts @@ -426,7 +426,8 @@ export class VitestMocker { try { callstack.push(mockPath) return await this.callFunctionMock(mockPath, mock) - } finally { + } + finally { const indexMock = callstack.indexOf(mockPath) callstack.splice(indexMock, 1) } From 95a1aa8dff68c332f24da635b53887458f25e79d Mon Sep 17 00:00:00 2001 From: lijifei Date: Fri, 18 Aug 2023 11:15:43 +0800 Subject: [PATCH 4/4] chore: import module with extension, avoid ts check issue --- examples/mocks/src/{dynamic-module.ts => dynamic-module.js} | 0 examples/mocks/src/retry-dynamic-import.ts | 5 ++--- 2 files changed, 2 insertions(+), 3 deletions(-) rename examples/mocks/src/{dynamic-module.ts => dynamic-module.js} (100%) diff --git a/examples/mocks/src/dynamic-module.ts b/examples/mocks/src/dynamic-module.js similarity index 100% rename from examples/mocks/src/dynamic-module.ts rename to examples/mocks/src/dynamic-module.js diff --git a/examples/mocks/src/retry-dynamic-import.ts b/examples/mocks/src/retry-dynamic-import.ts index 727699adbf5c..4c4c34685397 100644 --- a/examples/mocks/src/retry-dynamic-import.ts +++ b/examples/mocks/src/retry-dynamic-import.ts @@ -1,9 +1,8 @@ export async function retryDynamicImport() { let retryTimes = 0 const load = async () => { - try { // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - return await import('./dynamic-module') + try { + return await import('./dynamic-module.js') } catch (e) { if (retryTimes === 3)