|
1 | 1 | import { importModule } from 'local-pkg'
|
2 | 2 | import type { CoverageOptions, CoverageProvider, CoverageProviderModule } from '../types'
|
3 | 3 |
|
4 |
| -export const CoverageProviderMap = { |
| 4 | +interface Loader { |
| 5 | + executeId: (id: string) => Promise<{ default: CoverageProviderModule }> |
| 6 | +} |
| 7 | + |
| 8 | +export const CoverageProviderMap: Record<string, string> = { |
5 | 9 | c8: '@vitest/coverage-c8',
|
6 | 10 | istanbul: '@vitest/coverage-istanbul',
|
7 | 11 | }
|
8 | 12 |
|
9 |
| -export async function resolveCoverageProvider(provider: NonNullable<CoverageOptions['provider']>) { |
10 |
| - if (typeof provider === 'string') { |
11 |
| - const pkg = CoverageProviderMap[provider] |
12 |
| - if (!pkg) |
13 |
| - throw new Error(`Unknown coverage provider: ${provider}`) |
14 |
| - return await importModule<CoverageProviderModule>(pkg) |
| 13 | +async function resolveCoverageProviderModule(options: CoverageOptions & Required<Pick<CoverageOptions, 'provider'>>, loader: Loader) { |
| 14 | + const provider = options.provider |
| 15 | + |
| 16 | + if (provider === 'c8' || provider === 'istanbul') |
| 17 | + return await importModule<CoverageProviderModule>(CoverageProviderMap[provider]) |
| 18 | + |
| 19 | + let customProviderModule |
| 20 | + |
| 21 | + try { |
| 22 | + customProviderModule = await loader.executeId(options.customProviderModule) |
15 | 23 | }
|
16 |
| - else { |
17 |
| - return provider |
| 24 | + catch (error) { |
| 25 | + throw new Error(`Failed to load custom CoverageProviderModule from ${options.customProviderModule}`, { cause: error }) |
18 | 26 | }
|
| 27 | + |
| 28 | + if (customProviderModule.default == null) |
| 29 | + throw new Error(`Custom CoverageProviderModule loaded from ${options.customProviderModule} was not the default export`) |
| 30 | + |
| 31 | + return customProviderModule.default |
19 | 32 | }
|
20 | 33 |
|
21 |
| -export async function getCoverageProvider(options?: CoverageOptions): Promise<CoverageProvider | null> { |
22 |
| - if (options?.enabled && options?.provider) { |
23 |
| - const { getProvider } = await resolveCoverageProvider(options.provider) |
| 34 | +export async function getCoverageProvider(options: CoverageOptions, loader: Loader): Promise<CoverageProvider | null> { |
| 35 | + if (options.enabled && options.provider) { |
| 36 | + const { getProvider } = await resolveCoverageProviderModule(options, loader) |
24 | 37 | return await getProvider()
|
25 | 38 | }
|
26 | 39 | return null
|
27 | 40 | }
|
28 | 41 |
|
29 |
| -export async function takeCoverageInsideWorker(options: CoverageOptions) { |
| 42 | +export async function takeCoverageInsideWorker(options: CoverageOptions, loader: Loader) { |
30 | 43 | if (options.enabled && options.provider) {
|
31 |
| - const { takeCoverage } = await resolveCoverageProvider(options.provider) |
| 44 | + const { takeCoverage } = await resolveCoverageProviderModule(options, loader) |
32 | 45 | return await takeCoverage?.()
|
33 | 46 | }
|
34 | 47 | }
|
0 commit comments