|
1 | 1 | import { generateCode, parseModule } from 'magicast'; |
2 | | -import { deepMergeObject } from 'magicast/helpers'; |
| 2 | +import { deepMergeObject, getDefaultExportOptions } from 'magicast/helpers'; |
3 | 3 |
|
4 | | -type ProxyObject = Record<string, unknown> & { |
5 | | - toJSON?: () => unknown; |
6 | | -}; |
7 | | - |
8 | | -const REPORTER_CONFIGS: Record<string, { path: string[]; key: string }> = { |
9 | | - vitest: { path: ['test', 'coverage'], key: 'reporter' }, |
10 | | - jest: { path: [], key: 'coverageReporters' }, |
11 | | -}; |
| 4 | +const VITEST_DEFAULTS = ['text', 'html', 'clover', 'json']; |
12 | 5 |
|
13 | 6 | export function hasLcovReporter(content: string, framework: string): boolean { |
14 | | - const reporterConfig = REPORTER_CONFIGS[framework]; |
15 | | - if (!reporterConfig) { |
16 | | - return false; |
| 7 | + switch (framework) { |
| 8 | + case 'vitest': |
| 9 | + return /['"]lcov['"]/.test(content) && content.includes('reporter'); |
| 10 | + case 'jest': |
| 11 | + return ( |
| 12 | + !content.includes('coverageReporters') || /['"]lcov['"]/.test(content) |
| 13 | + ); |
| 14 | + default: |
| 15 | + return false; |
17 | 16 | } |
18 | | - return /['"]lcov['"]/.test(content) && content.includes(reporterConfig.key); |
19 | 17 | } |
20 | 18 |
|
21 | 19 | export function addLcovReporter(content: string, framework: string): string { |
22 | | - const reporterConfig = REPORTER_CONFIGS[framework]; |
23 | | - if (!reporterConfig) { |
24 | | - return content; |
| 20 | + switch (framework) { |
| 21 | + case 'vitest': |
| 22 | + return addLcovToVitest(content); |
| 23 | + case 'jest': |
| 24 | + return addLcovToJest(content); |
| 25 | + default: |
| 26 | + return content; |
25 | 27 | } |
| 28 | +} |
| 29 | + |
| 30 | +function addLcovToVitest(content: string): string { |
26 | 31 | try { |
27 | 32 | const mod = parseModule(content); |
28 | | - const exported = mod.exports['default']; |
29 | | - const configObject = |
30 | | - exported.$type === 'function-call' ? exported.$args[0] : exported; |
31 | | - const currentReporters = readReporters(configObject, reporterConfig); |
32 | | - const updatedReporters = [...currentReporters, 'lcov']; |
33 | | - |
| 33 | + const config = getDefaultExportOptions(mod); |
| 34 | + const reporter = config['test']?.['coverage']?.['reporter']; |
| 35 | + const base = reporter?.['length'] ? [...reporter] : VITEST_DEFAULTS; |
34 | 36 | deepMergeObject( |
35 | | - configObject, |
36 | | - buildNestedObject( |
37 | | - [...reporterConfig.path, reporterConfig.key], |
38 | | - updatedReporters, |
39 | | - ), |
| 37 | + config, |
| 38 | + buildNestedObject(['test', 'coverage', 'reporter'], [...base, 'lcov']), |
40 | 39 | ); |
41 | | - |
42 | 40 | return generateCode(mod).code; |
43 | 41 | } catch { |
44 | 42 | return content; |
45 | 43 | } |
46 | 44 | } |
47 | 45 |
|
48 | | -function isProxyObject(value: unknown): value is ProxyObject { |
49 | | - return typeof value === 'object' && value != null; |
50 | | -} |
51 | | - |
52 | | -function readReporters( |
53 | | - configObject: ProxyObject, |
54 | | - { path, key }: { path: string[]; key: string }, |
55 | | -): string[] { |
56 | | - const container = path.reduce<ProxyObject>((parent, segment) => { |
57 | | - const nested = parent[segment]; |
58 | | - return isProxyObject(nested) ? nested : {}; |
59 | | - }, configObject); |
60 | | - const reporterProxy = container[key]; |
61 | | - const resolved = |
62 | | - isProxyObject(reporterProxy) && typeof reporterProxy.toJSON === 'function' |
63 | | - ? reporterProxy.toJSON() |
64 | | - : reporterProxy; |
65 | | - return Array.isArray(resolved) ? resolved : []; |
| 46 | +function addLcovToJest(content: string): string { |
| 47 | + try { |
| 48 | + const mod = parseModule(content); |
| 49 | + const config = getDefaultExportOptions(mod); |
| 50 | + const reporters = config['coverageReporters']; |
| 51 | + if (!reporters?.['length']) { |
| 52 | + return content; |
| 53 | + } |
| 54 | + deepMergeObject( |
| 55 | + config, |
| 56 | + buildNestedObject(['coverageReporters'], [...reporters, 'lcov']), |
| 57 | + ); |
| 58 | + return generateCode(mod).code; |
| 59 | + } catch { |
| 60 | + return content; |
| 61 | + } |
66 | 62 | } |
67 | 63 |
|
68 | 64 | export function buildNestedObject( |
|
0 commit comments