Skip to content

Commit

Permalink
fix(coverage): istanbul provider to preserve implicit else (#2275)
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Nov 5, 2022
1 parent b8d3a95 commit d1b5b36
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 2 deletions.
43 changes: 43 additions & 0 deletions packages/coverage-istanbul/src/provider.ts
Expand Up @@ -108,6 +108,8 @@ export class IstanbulCoverageProvider implements CoverageProvider {
if (this.options.all)
await this.includeUntestedFiles(mergedCoverage)

includeImplicitElseBranches(mergedCoverage)

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

Expand Down Expand Up @@ -238,3 +240,44 @@ function resolveIstanbulOptions(options: CoverageIstanbulOptions, root: string)
function removeQueryParameters(filename: string) {
return filename.split('?')[0]
}

/**
* Work-around for #1887 and #2239 while waiting for https://github.com/istanbuljs/istanbuljs/pull/706
*
* Goes through all files in the coverage map and checks if branchMap's have
* if-statements with implicit else. When finds one, copies source location of
* the if-statement into the else statement.
*/
function includeImplicitElseBranches(coverageMap: CoverageMap) {
for (const file of coverageMap.files()) {
const fileCoverage = coverageMap.fileCoverageFor(file)

for (const branchMap of Object.values(fileCoverage.branchMap)) {
if (branchMap.type === 'if') {
const lastIndex = branchMap.locations.length - 1

if (lastIndex > 0) {
const elseLocation = branchMap.locations[lastIndex]

if (elseLocation && isEmptyCoverageRange(elseLocation)) {
const ifLocation = branchMap.locations[0]

elseLocation.start = { ...ifLocation.start }
elseLocation.end = { ...ifLocation.end }
}
}
}
}
}
}

function isEmptyCoverageRange(range: libCoverage.Range) {
return (
range.start === undefined
|| range.start.line === undefined
|| range.start.column === undefined
|| range.end === undefined
|| range.end.line === undefined
|| range.end.column === undefined
)
}
13 changes: 12 additions & 1 deletion test/coverage-test/coverage-test/coverage.istanbul.test.ts
@@ -1,5 +1,5 @@
import fs from 'fs'
import { resolve } from 'pathe'
import { normalize, resolve } from 'pathe'
import { expect, test } from 'vitest'

test('istanbul html report', async () => {
Expand Down Expand Up @@ -39,3 +39,14 @@ test('files should not contain query parameters', () => {
expect(files).toContain('Counter.component.ts.html')
expect(files).not.toContain('Counter.component.ts?vue&type=script&src=true&lang.ts.html')
})

test('implicit else is included in branch count', async () => {
// @ts-expect-error -- generated file
const { default: coverageMap } = await import('./coverage/coverage-final.json')

const filename = normalize(resolve('./src/implicitElse.ts'))
const fileCoverage = coverageMap[filename]

expect(fileCoverage.b).toHaveProperty('0')
expect(fileCoverage.b['0']).toHaveLength(2)
})
8 changes: 8 additions & 0 deletions test/coverage-test/src/implicitElse.ts
@@ -0,0 +1,8 @@
export function implicitElse(condition: boolean) {
let a = 1

if (condition)
a = 2

return a
}
5 changes: 5 additions & 0 deletions test/coverage-test/test/coverage.test.ts
@@ -1,6 +1,11 @@
import { expect, test } from 'vitest'
import { pythagoras } from '../src'
import { implicitElse } from '../src/implicitElse'

test('Math.sqrt()', async () => {
expect(pythagoras(3, 4)).toBe(5)
})

test('implicit else', () => {
expect(implicitElse(true)).toBe(2)
})
2 changes: 1 addition & 1 deletion test/coverage-test/vitest.config.ts
Expand Up @@ -20,7 +20,7 @@ export default defineConfig({
enabled: true,
clean: true,
all: true,
reporter: ['html', 'text', 'lcov'],
reporter: ['html', 'text', 'lcov', 'json'],
},
},
})

0 comments on commit d1b5b36

Please sign in to comment.