Skip to content

Commit ac2cc98

Browse files
glektarsszachagong
andauthored
feat: Support excluding source paths from coverage reporting (#1809)
* Disable a small linting thing. * Pass the whole test run context down. * Define our new setting. * Remove an unused import. * Implement new feature. * Ensure coverage surfaces when no exclusions are set. * Rewrote solution. Sometimes simplicity is best. * Do not permit negating. --------- Co-authored-by: Changyong Gong <chagon@microsoft.com>
1 parent ad7cde1 commit ac2cc98

File tree

5 files changed

+47
-5
lines changed

5 files changed

+47
-5
lines changed

package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,14 @@
350350
"type": "boolean",
351351
"description": "%configuration.java.test.config.coverage.appendResult.description%",
352352
"default": true
353+
},
354+
"excludes": {
355+
"type": "array",
356+
"items": {
357+
"type": "string"
358+
},
359+
"description": "%configuration.java.test.config.coverage.excludes.description%",
360+
"default": []
353361
}
354362
}
355363
}
@@ -510,6 +518,14 @@
510518
"type": "boolean",
511519
"description": "%configuration.java.test.config.coverage.appendResult.description%",
512520
"default": true
521+
},
522+
"excludes": {
523+
"type": "array",
524+
"items": {
525+
"type": "string"
526+
},
527+
"description": "%configuration.java.test.config.coverage.excludes.description%",
528+
"default": []
513529
}
514530
}
515531
}

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"configuration.java.test.config.javaExec.description": "The path to java executable to use. For example: `C:\\Program Files\\jdk\\bin\\java.exe`. If unset project JDK's java executable is used.",
3737
"configuration.java.test.config.coverage.description": "The configurations for test coverage.",
3838
"configuration.java.test.config.coverage.appendResult.description": "Whether the coverage result is appended.",
39+
"configuration.java.test.config.coverage.excludes.description": "A list of source files that should be excluded from coverage analysis. The can use any valid [minimatch](https://www.npmjs.com/package/minimatch) pattern.",
3940
"contributes.viewsWelcome.inLightWeightMode": "No test cases are listed because the Java Language Server is currently running in [LightWeight Mode](https://aka.ms/vscode-java-lightweight). To show test cases, click on the button to switch to Standard Mode.\n[Switch to Standard Mode](command:java.server.mode.switch?%5B%22Standard%22,true%5D)",
4041
"contributes.viewsWelcome.enableTests": "Click below button to configure a test framework for your project.\n[Enable Java Tests](command:_java.test.enableTests)"
4142
}

src/controller/testController.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ export const runTests: (request: TestRunRequest, option: IRunOption) => any = in
177177
let coverageProvider: JavaTestCoverageProvider | undefined;
178178
if (request.profile?.kind === TestRunProfileKind.Coverage) {
179179
coverageProvider = new JavaTestCoverageProvider();
180+
// QUESTION: Fix this?
181+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
180182
request.profile.loadDetailedCoverage = (_testRun: TestRun, fileCoverage: FileCoverage, _token: CancellationToken): Promise<FileCoverageDetail[]> => {
181183
return Promise.resolve(coverageProvider!.getCoverageDetails(fileCoverage.uri));
182184
};
@@ -265,7 +267,7 @@ export const runTests: (request: TestRunRequest, option: IRunOption) => any = in
265267
}
266268
}
267269
if (request.profile?.kind === TestRunProfileKind.Coverage) {
268-
await coverageProvider!.provideFileCoverage(run, projectName);
270+
await coverageProvider!.provideFileCoverage(testContext);
269271
}
270272
}
271273
}

src/java-test-runner.api.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ export interface IExecutionConfig {
353353
* @since 0.41.0
354354
*/
355355
appendResult?: boolean;
356+
357+
/**
358+
* A list of source files that should be excluded from coverage analysis.
359+
* The can use any valid [minimatch](https://www.npmjs.com/package/minimatch)
360+
* pattern.
361+
* @since 0.43.2
362+
*/
363+
excludes?: string[];
356364
}
357365

358366
/**

src/provider/JavaTestCoverageProvider.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,34 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
3-
4-
import { BranchCoverage, DeclarationCoverage, FileCoverage, FileCoverageDetail, Position, StatementCoverage, TestRun, Uri } from 'vscode';
3+
import * as minimatch from 'minimatch';
4+
import { BranchCoverage, DeclarationCoverage, FileCoverage, FileCoverageDetail, Position, StatementCoverage, Uri } from 'vscode';
55
import { getJacocoReportBasePath } from '../utils/coverageUtils';
66
import { executeJavaLanguageServerCommand } from '../utils/commandUtils';
77
import { JavaTestRunnerDelegateCommands } from '../constants';
8+
import { IRunTestContext } from '../java-test-runner.api';
89

910
export class JavaTestCoverageProvider {
1011

1112
private coverageDetails: Map<Uri, FileCoverageDetail[]> = new Map<Uri, FileCoverageDetail[]>();
1213

13-
public async provideFileCoverage(run: TestRun, projectName: string): Promise<void> {
14+
public async provideFileCoverage({testRun: run, projectName, testConfig}: IRunTestContext): Promise<void> {
1415
const sourceFileCoverages: ISourceFileCoverage[] = await executeJavaLanguageServerCommand<void>(JavaTestRunnerDelegateCommands.GET_COVERAGE_DETAIL,
1516
projectName, getJacocoReportBasePath(projectName)) || [];
16-
for (const sourceFileCoverage of sourceFileCoverages) {
17+
const sourceFileCoverageExclusions: minimatch.Minimatch[] = (testConfig?.coverage?.excludes ?? []).map((exclusion: string) =>
18+
new minimatch.Minimatch(exclusion, {flipNegate: true, nonegate: true}));
19+
const sourceFileCoveragesToReport: ISourceFileCoverage[] = [];
20+
if (sourceFileCoverageExclusions.length <= 0) {
21+
sourceFileCoveragesToReport.push(...sourceFileCoverages);
22+
} else {
23+
sourceFileCoverages.forEach((sourceFileCoverage: ISourceFileCoverage) => {
24+
const uri: Uri = Uri.parse(sourceFileCoverage.uriString);
25+
if (!sourceFileCoverageExclusions.some((exclusion: minimatch.Minimatch) =>
26+
exclusion.match(uri.fsPath))) {
27+
sourceFileCoveragesToReport.push(sourceFileCoverage);
28+
}
29+
});
30+
}
31+
for (const sourceFileCoverage of sourceFileCoveragesToReport) {
1732
const uri: Uri = Uri.parse(sourceFileCoverage.uriString);
1833
const detailedCoverage: FileCoverageDetail[] = [];
1934
for (const lineCoverage of sourceFileCoverage.lineCoverages) {

0 commit comments

Comments
 (0)