Skip to content

Commit

Permalink
feat(coverage-istanbul): add "all" option
Browse files Browse the repository at this point in the history
- Similar as nyc and c8 has
  • Loading branch information
AriPerkkio committed Aug 18, 2022
1 parent 637e2b3 commit 471b29f
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 4 deletions.
7 changes: 7 additions & 0 deletions docs/config/index.md
Expand Up @@ -518,6 +518,13 @@ Set to array of class method names to ignore for coverage.

Watermarks for statements, lines, branches and functions.

##### all

- **Type:** `boolean`
- **Default:** false

Whether to include all files, including the untested ones into report.

### testNamePattern

- **Type** `string | RegExp`
Expand Down
40 changes: 38 additions & 2 deletions packages/coverage-istanbul/src/provider.ts
Expand Up @@ -12,6 +12,7 @@ import libSourceMaps from 'istanbul-lib-source-maps'
import { type Instrumenter, createInstrumenter } from 'istanbul-lib-instrument'
// @ts-expect-error missing types
import _TestExclude from 'test-exclude'
import type { TransformResult } from 'vite'
import { COVERAGE_STORE_KEY } from './constants'

type Threshold = 'lines' | 'functions' | 'statements' | 'branches'
Expand All @@ -23,7 +24,10 @@ interface TestExclude {
exclude?: string | string[]
extension?: string | string[]
excludeNodeModules?: boolean
}): { shouldInstrument(filePath: string): boolean }
}): {
shouldInstrument(filePath: string): boolean
glob(cwd: string): Promise<string[]>
}
}

export class IstanbulCoverageProvider implements CoverageProvider {
Expand Down Expand Up @@ -93,12 +97,15 @@ export class IstanbulCoverageProvider implements CoverageProvider {
}

async reportCoverage() {
const mergedCoverage = this.coverages.reduce((coverage, previousCoverageMap) => {
const mergedCoverage: CoverageMap = this.coverages.reduce((coverage, previousCoverageMap) => {
const map = libCoverage.createCoverageMap(coverage)
map.merge(previousCoverageMap)
return map
}, {})

if (this.options.all)
await this.includeUntestedFiles(mergedCoverage)

const sourceMapStore = libSourceMaps.createSourceMapStore()
const coverageMap: CoverageMap = await sourceMapStore.transformCoverage(mergedCoverage)

Expand Down Expand Up @@ -173,6 +180,35 @@ export class IstanbulCoverageProvider implements CoverageProvider {
}
}
}

async includeUntestedFiles(coverageMap: CoverageMap) {
const files = await this.testExclude.glob(this.ctx.config.root)

for (const file of files) {
const filename = resolve(this.ctx.config.root, file)

if (!coverageMap.data[filename]) {
const transformResult = await this.ctx.vitenode.transformRequest(filename) as TransformResult
const sourceMap = transformResult?.map as NonNullable<TransformResult['map']>

this.instrumenter.instrumentSync(
transformResult.code,
filename,
{
...sourceMap,
version: sourceMap.version.toString(),
},
)

const lastCoverage = this.instrumenter.lastFileCoverage()
if (lastCoverage) {
coverageMap.data[lastCoverage.path] = {
...lastCoverage,
}
}
}
}
}
}

function resolveIstanbulOptions(options: CoverageIstanbulOptions, root: string) {
Expand Down
6 changes: 5 additions & 1 deletion packages/vitest/src/types/coverage.ts
Expand Up @@ -132,6 +132,11 @@ export interface BaseCoverageOptions {
* Extensions for files to be included in coverage
*/
extension?: string | string[]

/**
* Whether to include all files, including the untested ones into report
*/
all?: boolean
}

export interface CoverageIstanbulOptions extends BaseCoverageOptions {
Expand Down Expand Up @@ -162,7 +167,6 @@ export interface CoverageC8Options extends BaseCoverageOptions {
excludeNodeModules?: boolean
include?: string[]

all?: boolean
src?: string[]

100?: boolean
Expand Down
9 changes: 8 additions & 1 deletion test/coverage-test/coverage-test/coverage.istanbul.test.ts
Expand Up @@ -3,7 +3,7 @@ import { resolve } from 'pathe'
import { expect, test } from 'vitest'

test('istanbul html report', async () => {
const coveragePath = resolve('./coverage')
const coveragePath = resolve('./coverage/coverage-test/src')
const files = fs.readdirSync(coveragePath)

expect(files).toContain('index.html')
Expand All @@ -22,3 +22,10 @@ test('istanbul lcov report', async () => {

expect(lcovReportFiles).toContain('index.html')
})

test('all includes untested files', () => {
const coveragePath = resolve('./coverage/coverage-test/src')
const files = fs.readdirSync(coveragePath)

expect(files).toContain('untested-file.ts.html')
})
3 changes: 3 additions & 0 deletions test/coverage-test/src/untested-file.ts
@@ -0,0 +1,3 @@
export default function untestedFile() {
return 'This file should end up in report when {"all": true} is given'
}
1 change: 1 addition & 0 deletions test/coverage-test/vitest.config.ts
Expand Up @@ -19,6 +19,7 @@ export default defineConfig({
coverage: {
enabled: true,
clean: true,
all: true,
reporter: ['html', 'text', 'lcov'],
},
},
Expand Down

0 comments on commit 471b29f

Please sign in to comment.