Skip to content

Commit 8e15d69

Browse files
Copilotchagong
andcommitted
feat: Support excluding source paths from coverage reporting
Implements PR #1809 with fixes: - Add minimatch as direct dependency (was only transitive before) - Fix typo in description ('The can' -> 'They can') - Use correct @SInCE version (0.44.0 matching current package version) - Remove unnecessary eslint-disable comment and debug question - Cleaner filtering logic using Array.filter Co-authored-by: chagong <831821+chagong@users.noreply.github.com>
1 parent c0e765d commit 8e15d69

6 files changed

Lines changed: 44 additions & 10 deletions

File tree

package-lock.json

Lines changed: 4 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 17 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
}
@@ -559,6 +575,7 @@
559575
"iconv-lite": "^0.6.3",
560576
"lodash": "^4.17.23",
561577
"lru-cache": "^7.17.0",
578+
"minimatch": "^3.1.2",
562579
"vscode-extension-telemetry-wrapper": "^0.14.0",
563580
"vscode-languageclient": "6.0.0-next.9",
564581
"vscode-tas-client": "^0.1.75"

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. They 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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ export const runTests: (request: TestRunRequest, option: IRunOption) => any = in
265265
}
266266
}
267267
if (request.profile?.kind === TestRunProfileKind.Coverage) {
268-
await coverageProvider!.provideFileCoverage(run, projectName);
268+
await coverageProvider!.provideFileCoverage(testContext);
269269
}
270270
}
271271
}

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+
* They can use any valid [minimatch](https://www.npmjs.com/package/minimatch)
360+
* pattern.
361+
* @since 0.44.0
362+
*/
363+
excludes?: string[];
356364
}
357365

358366
/**

src/provider/JavaTestCoverageProvider.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import { BranchCoverage, DeclarationCoverage, FileCoverage, FileCoverageDetail, Position, StatementCoverage, TestRun, Uri } from 'vscode';
4+
import * as minimatch from 'minimatch';
5+
import { BranchCoverage, DeclarationCoverage, FileCoverage, FileCoverageDetail, Position, StatementCoverage, Uri } from 'vscode';
56
import { getJacocoReportBasePath } from '../utils/coverageUtils';
67
import { executeJavaLanguageServerCommand } from '../utils/commandUtils';
78
import { JavaTestRunnerDelegateCommands } from '../constants';
9+
import { IRunTestContext } from '../java-test-runner.api';
810

911
export class JavaTestCoverageProvider {
1012

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

13-
public async provideFileCoverage(run: TestRun, projectName: string): Promise<void> {
15+
public async provideFileCoverage({testRun: run, projectName, testConfig}: IRunTestContext): Promise<void> {
1416
const sourceFileCoverages: ISourceFileCoverage[] = await executeJavaLanguageServerCommand<void>(JavaTestRunnerDelegateCommands.GET_COVERAGE_DETAIL,
1517
projectName, getJacocoReportBasePath(projectName)) || [];
16-
for (const sourceFileCoverage of sourceFileCoverages) {
18+
const excludePatterns: minimatch.Minimatch[] = (testConfig?.coverage?.excludes ?? []).map((pattern: string) =>
19+
new minimatch.Minimatch(pattern, {flipNegate: true, nonegate: true}));
20+
const filteredCoverages: ISourceFileCoverage[] = excludePatterns.length > 0
21+
? sourceFileCoverages.filter((sourceFileCoverage: ISourceFileCoverage) => {
22+
const uri: Uri = Uri.parse(sourceFileCoverage.uriString);
23+
return !excludePatterns.some((exclusion: minimatch.Minimatch) => exclusion.match(uri.fsPath));
24+
})
25+
: sourceFileCoverages;
26+
for (const sourceFileCoverage of filteredCoverages) {
1727
const uri: Uri = Uri.parse(sourceFileCoverage.uriString);
1828
const detailedCoverage: FileCoverageDetail[] = [];
1929
for (const lineCoverage of sourceFileCoverage.lineCoverages) {

0 commit comments

Comments
 (0)