Skip to content

Commit ddf24af

Browse files
committed
feat(coverage): support --changed option
1 parent dfe16e1 commit ddf24af

File tree

10 files changed

+345
-25
lines changed

10 files changed

+345
-25
lines changed

packages/coverage-istanbul/src/provider.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,17 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
253253
}
254254

255255
async getCoverageMapForUncoveredFiles(coveredFiles: string[]) {
256-
// Load, instrument and collect empty coverages from all files which
257-
// are not already in the coverage map
258-
const includedFiles = await this.testExclude.glob(this.ctx.config.root)
256+
let includedFiles: string[]
257+
258+
if (this.ctx.config.changed) {
259+
includedFiles = this.ctx.config.related || []
260+
}
261+
else {
262+
const allFiles = await this.testExclude.glob(this.ctx.config.root)
263+
includedFiles = allFiles.map(file => resolve(this.ctx.config.root, file))
264+
}
265+
259266
const uncoveredFiles = includedFiles
260-
.map(file => resolve(this.ctx.config.root, file))
261267
.filter(file => !coveredFiles.includes(file))
262268

263269
const cacheKey = new Date().getTime()

packages/coverage-v8/src/provider.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,18 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
244244

245245
private async getUntestedFiles(testedFiles: string[]): Promise<RawCoverage> {
246246
const transformResults = normalizeTransformResults(this.ctx.vitenode.fetchCache)
247+
let includedFiles: string[]
248+
249+
if (this.ctx.config.changed) {
250+
includedFiles = this.ctx.config.related || []
251+
}
252+
else {
253+
const allFiles = await this.testExclude.glob(this.ctx.config.root)
254+
includedFiles = allFiles.map(file => resolve(this.ctx.config.root, file))
255+
}
247256

248-
const includedFiles = await this.testExclude.glob(this.ctx.config.root)
249257
const uncoveredFiles = includedFiles
250-
.map(file => pathToFileURL(resolve(this.ctx.config.root, file)))
258+
.map(file => pathToFileURL(file))
251259
.filter(file => !testedFiles.includes(file.pathname))
252260

253261
let merged: RawCoverage = { result: [] }

packages/vitest/src/node/core.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,6 @@ export class Vitest {
382382
}
383383
}
384384

385-
// all subsequent runs will treat this as a fresh run
386-
this.config.changed = false
387-
this.config.related = undefined
388-
389385
if (files.length) {
390386
// populate once, update cache on watch
391387
await this.cache.stats.populateStats(this.config.root, files)
@@ -532,6 +528,10 @@ export class Vitest {
532528

533529
this.runningPromise = undefined
534530
this.isFirstRun = false
531+
532+
// all subsequent runs will treat this as a fresh run
533+
this.config.changed = false
534+
this.config.related = undefined
535535
})
536536

537537
return await this.runningPromise

test/coverage-test/coverage-report-tests/__snapshots__/istanbul.report.test.ts.snap

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,89 @@ exports[`istanbul json report 1`] = `
11341134
},
11351135
},
11361136
},
1137+
"<process-cwd>/src/file-to-change.ts": {
1138+
"b": {},
1139+
"branchMap": {},
1140+
"f": {
1141+
"0": 0,
1142+
"1": 0,
1143+
},
1144+
"fnMap": {
1145+
"0": {
1146+
"decl": {
1147+
"end": {
1148+
"column": 22,
1149+
"line": 1,
1150+
},
1151+
"start": {
1152+
"column": 16,
1153+
"line": 1,
1154+
},
1155+
},
1156+
"loc": {
1157+
"end": {
1158+
"column": null,
1159+
"line": 3,
1160+
},
1161+
"start": {
1162+
"column": 22,
1163+
"line": 1,
1164+
},
1165+
},
1166+
"name": "run",
1167+
},
1168+
"1": {
1169+
"decl": {
1170+
"end": {
1171+
"column": 36,
1172+
"line": 5,
1173+
},
1174+
"start": {
1175+
"column": 16,
1176+
"line": 5,
1177+
},
1178+
},
1179+
"loc": {
1180+
"end": {
1181+
"column": null,
1182+
"line": 7,
1183+
},
1184+
"start": {
1185+
"column": 36,
1186+
"line": 5,
1187+
},
1188+
},
1189+
"name": "uncoveredFunction",
1190+
},
1191+
},
1192+
"path": "<process-cwd>/src/file-to-change.ts",
1193+
"s": {
1194+
"0": 0,
1195+
"1": 0,
1196+
},
1197+
"statementMap": {
1198+
"0": {
1199+
"end": {
1200+
"column": null,
1201+
"line": 2,
1202+
},
1203+
"start": {
1204+
"column": 2,
1205+
"line": 2,
1206+
},
1207+
},
1208+
"1": {
1209+
"end": {
1210+
"column": null,
1211+
"line": 6,
1212+
},
1213+
"start": {
1214+
"column": 2,
1215+
"line": 6,
1216+
},
1217+
},
1218+
},
1219+
},
11371220
"<process-cwd>/src/function-count.ts": {
11381221
"b": {},
11391222
"branchMap": {},

test/coverage-test/coverage-report-tests/__snapshots__/v8.report.test.ts.snap

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2777,6 +2777,153 @@ exports[`v8 json report 1`] = `
27772777
},
27782778
},
27792779
},
2780+
"<process-cwd>/src/file-to-change.ts": {
2781+
"all": true,
2782+
"b": {
2783+
"0": [
2784+
0,
2785+
],
2786+
},
2787+
"branchMap": {
2788+
"0": {
2789+
"line": 1,
2790+
"loc": {
2791+
"end": {
2792+
"column": 1,
2793+
"line": 7,
2794+
},
2795+
"start": {
2796+
"column": 0,
2797+
"line": 1,
2798+
},
2799+
},
2800+
"locations": [
2801+
{
2802+
"end": {
2803+
"column": 1,
2804+
"line": 7,
2805+
},
2806+
"start": {
2807+
"column": 0,
2808+
"line": 1,
2809+
},
2810+
},
2811+
],
2812+
"type": "branch",
2813+
},
2814+
},
2815+
"f": {
2816+
"0": 0,
2817+
},
2818+
"fnMap": {
2819+
"0": {
2820+
"decl": {
2821+
"end": {
2822+
"column": 1,
2823+
"line": 7,
2824+
},
2825+
"start": {
2826+
"column": 0,
2827+
"line": 1,
2828+
},
2829+
},
2830+
"line": 1,
2831+
"loc": {
2832+
"end": {
2833+
"column": 1,
2834+
"line": 7,
2835+
},
2836+
"start": {
2837+
"column": 0,
2838+
"line": 1,
2839+
},
2840+
},
2841+
"name": "(empty-report)",
2842+
},
2843+
},
2844+
"path": "<process-cwd>/src/file-to-change.ts",
2845+
"s": {
2846+
"0": 0,
2847+
"1": 0,
2848+
"2": 0,
2849+
"3": 0,
2850+
"4": 0,
2851+
"5": 0,
2852+
"6": 0,
2853+
},
2854+
"statementMap": {
2855+
"0": {
2856+
"end": {
2857+
"column": 23,
2858+
"line": 1,
2859+
},
2860+
"start": {
2861+
"column": 0,
2862+
"line": 1,
2863+
},
2864+
},
2865+
"1": {
2866+
"end": {
2867+
"column": 51,
2868+
"line": 2,
2869+
},
2870+
"start": {
2871+
"column": 0,
2872+
"line": 2,
2873+
},
2874+
},
2875+
"2": {
2876+
"end": {
2877+
"column": 1,
2878+
"line": 3,
2879+
},
2880+
"start": {
2881+
"column": 0,
2882+
"line": 3,
2883+
},
2884+
},
2885+
"3": {
2886+
"end": {
2887+
"column": 0,
2888+
"line": 4,
2889+
},
2890+
"start": {
2891+
"column": 0,
2892+
"line": 4,
2893+
},
2894+
},
2895+
"4": {
2896+
"end": {
2897+
"column": 37,
2898+
"line": 5,
2899+
},
2900+
"start": {
2901+
"column": 0,
2902+
"line": 5,
2903+
},
2904+
},
2905+
"5": {
2906+
"end": {
2907+
"column": 14,
2908+
"line": 6,
2909+
},
2910+
"start": {
2911+
"column": 0,
2912+
"line": 6,
2913+
},
2914+
},
2915+
"6": {
2916+
"end": {
2917+
"column": 1,
2918+
"line": 7,
2919+
},
2920+
"start": {
2921+
"column": 0,
2922+
"line": 7,
2923+
},
2924+
},
2925+
},
2926+
},
27802927
"<process-cwd>/src/function-count.ts": {
27812928
"all": false,
27822929
"b": {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { expect, test } from 'vitest'
2+
import libCoverage from 'istanbul-lib-coverage'
3+
4+
import { readCoverageJson } from './utils'
5+
6+
test('report contains only the changed files', async () => {
7+
const coverageJson = await readCoverageJson('./coverage/coverage-final.json')
8+
const coverageMap = libCoverage.createCoverageMap(coverageJson as any)
9+
10+
expect(coverageMap.files()).toMatchInlineSnapshot(`
11+
[
12+
"<process-cwd>/src/file-to-change.ts",
13+
"<process-cwd>/src/new-uncovered-file.ts",
14+
]
15+
`)
16+
17+
const uncoveredFile = coverageMap.fileCoverageFor('<process-cwd>/src/new-uncovered-file.ts').toSummary()
18+
expect(uncoveredFile.lines.pct).toBe(0)
19+
20+
const changedFile = coverageMap.fileCoverageFor('<process-cwd>/src/file-to-change.ts').toSummary()
21+
expect(changedFile.lines.pct).toBeGreaterThanOrEqual(50)
22+
})

test/coverage-test/coverage-report-tests/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ interface CoverageFinalJson {
1717
* Read JSON coverage report from file system.
1818
* Normalizes paths to keep contents consistent between OS's
1919
*/
20-
export async function readCoverageJson() {
21-
const jsonReport = JSON.parse(readFileSync('./coverage/custom-json-report-name.json', 'utf8')) as CoverageFinalJson
20+
export async function readCoverageJson(name = './coverage/custom-json-report-name.json') {
21+
const jsonReport = JSON.parse(readFileSync(name, 'utf8')) as CoverageFinalJson
2222

2323
const normalizedReport: CoverageFinalJson['default'] = {}
2424

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { test } from 'vitest'
2+
import { run } from '../src/file-to-change'
3+
4+
test('test case for changed file', () => {
5+
run()
6+
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function run() {
2+
return 'This file will be modified by test cases'
3+
}
4+
5+
export function uncoveredFunction() {
6+
return 1 + 2
7+
}

0 commit comments

Comments
 (0)