Skip to content

Commit

Permalink
fix(coverage): thresholds.autoUpdate to work with arrow function co…
Browse files Browse the repository at this point in the history
…nfiguration files (#4959)
  • Loading branch information
AriPerkkio authored Jan 15, 2024
1 parent 3e6668e commit 4b41131
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 46 deletions.
2 changes: 1 addition & 1 deletion packages/coverage-istanbul/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"istanbul-lib-report": "^3.0.1",
"istanbul-lib-source-maps": "^4.0.1",
"istanbul-reports": "^3.1.6",
"magicast": "^0.3.2",
"magicast": "^0.3.3",
"picocolors": "^1.0.0",
"test-exclude": "^6.0.0"
},
Expand Down
31 changes: 28 additions & 3 deletions packages/coverage-istanbul/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { AfterSuiteRunMeta, CoverageIstanbulOptions, CoverageProvider, Repo
import { coverageConfigDefaults, defaultExclude, defaultInclude } from 'vitest/config'
import { BaseCoverageProvider } from 'vitest/coverage'
import c from 'picocolors'
import type { ProxifiedModule } from 'magicast'
import { parseModule } from 'magicast'
import createDebug from 'debug'
import libReport from 'istanbul-lib-report'
Expand Down Expand Up @@ -238,9 +239,7 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
perFile: this.options.thresholds.perFile,
configurationFile: {
write: () => writeFileSync(configFilePath, configModule.generate().code, 'utf-8'),
read: () => configModule.exports.default.$type === 'function-call'
? configModule.exports.default.$args[0]
: configModule.exports.default,
read: () => resolveConfig(configModule),
},
})
}
Expand Down Expand Up @@ -360,3 +359,29 @@ function toSlices<T>(array: T[], size: number): T[][] {
return chunks
}, [])
}

function resolveConfig(configModule: ProxifiedModule<any>) {
const mod = configModule.exports.default

try {
// Check for "export default { test: {...} }"
if (mod.$type === 'object')
return mod

if (mod.$type === 'function-call') {
// "export default defineConfig({ test: {...} })"
if (mod.$args[0].$type === 'object')
return mod.$args[0]

// "export default defineConfig(() => ({ test: {...} }))"
if (mod.$args[0].$type === 'arrow-function-expression' && mod.$args[0].$body.$type === 'object')
return mod.$args[0].$body
}
}
catch (error) {
// Reduce magicast's verbose errors to readable ones
throw new Error(error instanceof Error ? error.message : String(error))
}

throw new Error('Failed to update coverage thresholds. Configuration file is too complex.')
}
2 changes: 1 addition & 1 deletion packages/coverage-v8/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"istanbul-lib-source-maps": "^4.0.1",
"istanbul-reports": "^3.1.6",
"magic-string": "^0.30.5",
"magicast": "^0.3.2",
"magicast": "^0.3.3",
"picocolors": "^1.0.0",
"std-env": "^3.5.0",
"test-exclude": "^6.0.0",
Expand Down
31 changes: 28 additions & 3 deletions packages/coverage-v8/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { CoverageMap } from 'istanbul-lib-coverage'
import libCoverage from 'istanbul-lib-coverage'
import libSourceMaps from 'istanbul-lib-source-maps'
import MagicString from 'magic-string'
import type { ProxifiedModule } from 'magicast'
import { parseModule } from 'magicast'
import remapping from '@ampproject/remapping'
import { normalize, resolve } from 'pathe'
Expand Down Expand Up @@ -230,9 +231,7 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
perFile: this.options.thresholds.perFile,
configurationFile: {
write: () => writeFileSync(configFilePath, configModule.generate().code, 'utf-8'),
read: () => configModule.exports.default.$type === 'function-call'
? configModule.exports.default.$args[0]
: configModule.exports.default,
read: () => resolveConfig(configModule),
},
})
}
Expand Down Expand Up @@ -432,3 +431,29 @@ function toSlices<T>(array: T[], size: number): T[][] {
return chunks
}, [])
}

function resolveConfig(configModule: ProxifiedModule<any>) {
const mod = configModule.exports.default

try {
// Check for "export default { test: {...} }"
if (mod.$type === 'object')
return mod

if (mod.$type === 'function-call') {
// "export default defineConfig({ test: {...} })"
if (mod.$args[0].$type === 'object')
return mod.$args[0]

// "export default defineConfig(() => ({ test: {...} }))"
if (mod.$args[0].$type === 'arrow-function-expression' && mod.$args[0].$body.$type === 'object')
return mod.$args[0].$body
}
}
catch (error) {
// Reduce magicast's verbose errors to readable ones
throw new Error(error instanceof Error ? error.message : String(error))
}

throw new Error('Failed to update coverage thresholds. Configuration file is too complex.')
}
Loading

0 comments on commit 4b41131

Please sign in to comment.