Skip to content

Commit cfc9c62

Browse files
committed
chore(plugin-coverage): include project path for issues reference
1 parent 6657a4d commit cfc9c62

10 files changed

Lines changed: 108 additions & 42 deletions

File tree

code-pushup.config.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,30 @@ const config: CoreConfig = {
4848
coveragePlugin({
4949
coverageType: ['branch', 'function', 'line'],
5050
reports: [
51-
'coverage/cli/unit-tests/lcov.info',
52-
'coverage/core/unit-tests/lcov.info',
53-
'coverage/models/unit-tests/lcov.info',
54-
'coverage/utils/unit-tests/lcov.info',
55-
'coverage/plugin-eslint/unit-tests/lcov.info',
56-
'coverage/plugin-coverage/unit-tests/lcov.info',
51+
{
52+
resultsPath: 'coverage/cli/unit-tests/lcov.info',
53+
pathToProject: 'packages/cli',
54+
},
55+
{
56+
resultsPath: 'coverage/core/unit-tests/lcov.info',
57+
pathToProject: 'packages/core',
58+
},
59+
{
60+
resultsPath: 'coverage/models/unit-tests/lcov.info',
61+
pathToProject: 'packages/models',
62+
},
63+
{
64+
resultsPath: 'coverage/utils/unit-tests/lcov.info',
65+
pathToProject: 'packages/utils',
66+
},
67+
{
68+
resultsPath: 'coverage/plugin-eslint/unit-tests/lcov.info',
69+
pathToProject: 'packages/plugin-eslint',
70+
},
71+
{
72+
resultsPath: 'coverage/plugin-coverage/unit-tests/lcov.info',
73+
pathToProject: 'packages/plugin-coverage',
74+
},
5775
],
5876
}),
5977
fileSizePlugin({

e2e/cli-e2e/mocks/fixtures/code-pushup.config.coverage.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ export default {
3838
plugins: [
3939
coveragePlugin({
4040
coverageType: ['branch', 'function', 'line'],
41-
reports: [join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info')],
41+
reports: [
42+
{
43+
resultsPath: join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info'),
44+
pathToProject: join('packages', 'cli'),
45+
},
46+
],
4247
}),
4348
],
4449
} satisfies CoreConfig;

e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
4040
"message": "Branch 1 is not taken in any test case.",
4141
"severity": "error",
4242
"source": {
43-
"file": "src/lib/partly-covered/utils.ts",
43+
"file": "packages/cli/src/lib/partly-covered/utils.ts",
4444
"position": {
4545
"startLine": 6,
4646
},
@@ -50,7 +50,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
5050
"message": "Branch 1 is not taken in any test case.",
5151
"severity": "error",
5252
"source": {
53-
"file": "src/lib/partly-covered/utils.ts",
53+
"file": "packages/cli/src/lib/partly-covered/utils.ts",
5454
"position": {
5555
"startLine": 10,
5656
},
@@ -60,7 +60,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
6060
"message": "Branch 0 is not taken in any test case.",
6161
"severity": "error",
6262
"source": {
63-
"file": "src/lib/not-covered/sorting.ts",
63+
"file": "packages/cli/src/lib/not-covered/sorting.ts",
6464
"position": {
6565
"startLine": 7,
6666
},
@@ -70,7 +70,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
7070
"message": "Branch 1 is not taken in any test case.",
7171
"severity": "error",
7272
"source": {
73-
"file": "src/lib/not-covered/sorting.ts",
73+
"file": "packages/cli/src/lib/not-covered/sorting.ts",
7474
"position": {
7575
"startLine": 7,
7676
},
@@ -92,7 +92,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
9292
"message": "Function formatReportScore is not called in any test case.",
9393
"severity": "error",
9494
"source": {
95-
"file": "src/lib/partly-covered/utils.ts",
95+
"file": "packages/cli/src/lib/partly-covered/utils.ts",
9696
"position": {
9797
"startLine": 2,
9898
},
@@ -102,7 +102,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
102102
"message": "Function sortReport is not called in any test case.",
103103
"severity": "error",
104104
"source": {
105-
"file": "src/lib/not-covered/sorting.ts",
105+
"file": "packages/cli/src/lib/not-covered/sorting.ts",
106106
"position": {
107107
"startLine": 1,
108108
},
@@ -124,7 +124,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
124124
"message": "Lines 7-9 are not covered in any test case.",
125125
"severity": "warning",
126126
"source": {
127-
"file": "src/lib/partly-covered/utils.ts",
127+
"file": "packages/cli/src/lib/partly-covered/utils.ts",
128128
"position": {
129129
"endLine": 9,
130130
"startLine": 7,
@@ -135,7 +135,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
135135
"message": "Lines 1-5 are not covered in any test case.",
136136
"severity": "warning",
137137
"source": {
138-
"file": "src/lib/not-covered/sorting.ts",
138+
"file": "packages/cli/src/lib/not-covered/sorting.ts",
139139
"position": {
140140
"endLine": 5,
141141
"startLine": 1,

packages/plugin-coverage/README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @code-pushup/coverage-plugin
22

3-
**Code PushUp plugin for tracking code coverage.**
3+
🧪 **Code PushUp plugin for tracking code coverage.** ☂️
44

55
This plugin allows you to measure and track code coverage on your project.
66

@@ -20,8 +20,7 @@ Measured coverage types are mapped to Code PushUp audits in the following way
2020

2121
Pass coverage types you wish to track (line, branch or function), paths to the code coverage results in LCOV format and optionally define your code coverage tool to be run first.
2222

23-
> [!IMPORTANT]
24-
> Please note that when you define the tool command, you still need to define the paths to the coverage results.
23+
📌 Please note that when you define the tool command, you still need to define the paths to all relevant coverage results.
2524

2625
The configuration will look similarly to the following:
2726

@@ -34,7 +33,7 @@ Measured coverage types are mapped to Code PushUp audits in the following way
3433
// ...
3534
await coveragePlugin({
3635
coverageType: ['branch', 'function', 'line'],
37-
reports: ['coverage/cli/lcov.info'],
36+
reports: [{ resultsPath: 'coverage/cli/lcov.info', pathToProject: 'packages/cli' }],
3837
coverageToolCommand: {
3938
command: 'npx',
4039
args: ['jest', '--coverage', '--coverageReporters=lcov'],
@@ -46,8 +45,7 @@ Measured coverage types are mapped to Code PushUp audits in the following way
4645

4746
4. (Optional) Reference audits which you wish to include in custom categories (use `npx code-pushup print-config` to list audits and groups).
4847

49-
> [!TIP]
50-
> Assign weights based on what influence each coverage type should have on the overall category score (assign weight 0 to only include as extra info, without influencing category score).
48+
💡 Assign weights based on what influence each coverage type should have on the overall category score (assign weight 0 to only include as extra info, without influencing category score).
5149

5250
```js
5351
export default {
@@ -124,7 +122,7 @@ It recognises the following entities:
124122
The plugin accepts the following parameters:
125123

126124
- `coverageType`: An array of types of coverage that you wish to track. Supported values: `function`, `branch`, `line`.
127-
- `reports`: Array of paths to files with code coverage results. LCOV format is supported for now.
125+
- `reports`: Array of information about files with code coverage results - paths to results, path to project root the results belong to. LCOV format is supported for now.
128126
- (optional) `coverageToolCommand`: If you wish to run your coverage tool to generate the results first, you may define it here.
129127
- (optional) `perfectScoreThreshold`: If your coverage goal is not 100%, you may define it here in range 0-1. Any score above the defined threshold will be given the perfect score. The value will stay unaffected.
130128

packages/plugin-coverage/src/lib/config.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ import { z } from 'zod';
33
export const coverageTypeSchema = z.enum(['function', 'branch', 'line']);
44
export type CoverageType = z.infer<typeof coverageTypeSchema>;
55

6+
export const coverageReportSchema = z.object({
7+
resultsPath: z.string().includes('lcov'),
8+
pathToProject: z
9+
.string({
10+
description:
11+
'Path from workspace root to project root. Necessary for LCOV reports.',
12+
})
13+
.optional(),
14+
});
15+
export type CoverageReport = z.infer<typeof coverageReportSchema>;
16+
617
export const coveragePluginConfigSchema = z.object({
718
coverageToolCommand: z
819
.object({
@@ -18,7 +29,7 @@ export const coveragePluginConfigSchema = z.object({
1829
.optional(),
1930
coverageType: z.array(coverageTypeSchema).min(1),
2031
reports: z
21-
.array(z.string().includes('lcov'), {
32+
.array(coverageReportSchema, {
2233
description:
2334
'Path to all code coverage report files. Only LCOV format is supported for now.',
2435
})

packages/plugin-coverage/src/lib/config.unit.test.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ describe('coveragePluginConfigSchema', () => {
66
expect(() =>
77
coveragePluginConfigSchema.parse({
88
coverageType: ['branch', 'function'],
9-
reports: ['coverage/cli/lcov.info'],
9+
reports: [
10+
{
11+
resultsPath: 'coverage/cli/lcov.info',
12+
pathToProject: 'packages/cli',
13+
},
14+
],
1015
coverageToolCommand: {
1116
command: 'npx nx run-many',
1217
args: ['-t', 'test', '--coverage'],
@@ -20,7 +25,7 @@ describe('coveragePluginConfigSchema', () => {
2025
expect(() =>
2126
coveragePluginConfigSchema.parse({
2227
coverageType: ['line'],
23-
reports: ['coverage/cli/lcov.info'],
28+
reports: [{ resultsPath: 'coverage/cli/lcov.info' }],
2429
} satisfies CoveragePluginConfig),
2530
).not.toThrow();
2631
});
@@ -29,7 +34,7 @@ describe('coveragePluginConfigSchema', () => {
2934
expect(() =>
3035
coveragePluginConfigSchema.parse({
3136
coverageType: [],
32-
reports: ['coverage/cli/lcov.info'],
37+
reports: [{ resultsPath: 'coverage/cli/lcov.info' }],
3338
} satisfies CoveragePluginConfig),
3439
).toThrow('too_small');
3540
});
@@ -47,8 +52,8 @@ describe('coveragePluginConfigSchema', () => {
4752
expect(() =>
4853
coveragePluginConfigSchema.parse({
4954
coverageType: ['line'],
50-
reports: ['coverage/cli/coverage-final.json'],
51-
}),
55+
reports: [{ resultsPath: 'coverage/cli/coverage-final.json' }],
56+
} satisfies CoveragePluginConfig),
5257
).toThrow(/Invalid input: must include.+lcov/);
5358
});
5459

@@ -68,7 +73,7 @@ describe('coveragePluginConfigSchema', () => {
6873
expect(() =>
6974
coveragePluginConfigSchema.parse({
7075
coverageType: ['line'],
71-
reports: ['coverage/cli/lcov.info'],
76+
reports: [{ resultsPath: 'coverage/cli/lcov.info' }],
7277
perfectScoreThreshold: 110,
7378
} satisfies CoveragePluginConfig),
7479
).toThrow('too_big');

packages/plugin-coverage/src/lib/coverage-plugin.integration.test.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ import { CoveragePluginConfig } from './config';
44
import { coveragePlugin } from './coverage-plugin';
55

66
describe('coveragePluginConfigSchema', () => {
7+
const LCOV_PATH = join(
8+
'packages',
9+
'plugin-coverage',
10+
'mocks',
11+
'single-record-lcov.info',
12+
);
13+
714
it('should initialise a Code coverage plugin', () => {
815
expect(
916
coveragePlugin({
1017
coverageType: ['function'],
11-
reports: [join('packages', 'plugin-coverage', 'mocks', 'lcov.info')],
18+
reports: [{ resultsPath: LCOV_PATH }],
1219
}),
1320
).toStrictEqual(
1421
expect.objectContaining({
@@ -23,7 +30,7 @@ describe('coveragePluginConfigSchema', () => {
2330
expect(
2431
coveragePlugin({
2532
coverageType: ['function', 'branch'],
26-
reports: [join('packages', 'plugin-coverage', 'mocks', 'lcov.info')],
33+
reports: [{ resultsPath: LCOV_PATH }],
2734
}),
2835
).toStrictEqual(
2936
expect.objectContaining({
@@ -43,7 +50,7 @@ describe('coveragePluginConfigSchema', () => {
4350
expect(
4451
coveragePlugin({
4552
coverageType: ['line'],
46-
reports: [join('packages', 'plugin-coverage', 'mocks', 'lcov.info')],
53+
reports: [{ resultsPath: LCOV_PATH }],
4754
coverageToolCommand: {
4855
command: 'npm run-many',
4956
args: ['-t', 'test', '--coverage'],
@@ -66,7 +73,7 @@ describe('coveragePluginConfigSchema', () => {
6673
expect(
6774
coveragePlugin({
6875
coverageType: ['line'],
69-
reports: [join('packages', 'plugin-coverage', 'mocks', 'lcov.info')],
76+
reports: [{ resultsPath: LCOV_PATH }],
7077
} satisfies CoveragePluginConfig),
7178
).toStrictEqual(
7279
expect.objectContaining({

packages/plugin-coverage/src/lib/runner/lcov/__snapshots__/runner.integration.test.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ exports[`lcovResultsToAuditOutputs > should correctly convert lcov results to Au
99
"message": "Branch 0 is not taken in any test case.",
1010
"severity": "error",
1111
"source": {
12-
"file": "src/lib/utils.ts",
12+
"file": "packages/cli/src/lib/utils.ts",
1313
"position": {
1414
"startLine": 6,
1515
},
@@ -19,7 +19,7 @@ exports[`lcovResultsToAuditOutputs > should correctly convert lcov results to Au
1919
"message": "Branch 0 is not taken in any test case.",
2020
"severity": "error",
2121
"source": {
22-
"file": "src/lib/utils.ts",
22+
"file": "packages/cli/src/lib/utils.ts",
2323
"position": {
2424
"startLine": 10,
2525
},
@@ -46,7 +46,7 @@ exports[`lcovResultsToAuditOutputs > should correctly convert lcov results to Au
4646
"message": "Lines 7-9 are not covered in any test case.",
4747
"severity": "warning",
4848
"source": {
49-
"file": "src/lib/utils.ts",
49+
"file": "packages/cli/src/lib/utils.ts",
5050
"position": {
5151
"endLine": 9,
5252
"startLine": 7,

packages/plugin-coverage/src/lib/runner/lcov/runner.integration.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@ describe('lcovResultsToAuditOutputs', () => {
1111
* Lines: 10 found, 7 covered (70% coverage) - merged into one issue with line range
1212
*/
1313
const results = await lcovResultsToAuditOutputs(
14-
[join('packages', 'plugin-coverage', 'mocks', 'single-record-lcov.info')],
14+
[
15+
{
16+
resultsPath: join(
17+
'packages',
18+
'plugin-coverage',
19+
'mocks',
20+
'single-record-lcov.info',
21+
),
22+
pathToProject: join('packages', 'cli'),
23+
},
24+
],
1525
['branch', 'function', 'line'],
1626
);
1727
expect(results).toMatchSnapshot();

packages/plugin-coverage/src/lib/runner/lcov/runner.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import { join } from 'node:path';
12
import type { LCOVRecord } from 'parse-lcov';
23
import { AuditOutputs } from '@code-pushup/models';
3-
import { exists, readTextFile } from '@code-pushup/utils';
4-
import { CoverageType } from '../../config';
4+
import { readTextFile, toUnixPath } from '@code-pushup/utils';
5+
//TODO fix, why doesnt it know the exists import??
6+
import { exists } from '../../../../../models/src/lib/implementation/utils';
7+
import { CoverageReport, CoverageType } from '../../config';
58
import { parseLcov } from './parse-lcov';
69
import {
710
lcovCoverageToAuditOutput,
@@ -19,15 +22,24 @@ import { LCOVStat, LCOVStats } from './types';
1922
* @returns Audit outputs with complete coverage data.
2023
*/
2124
export async function lcovResultsToAuditOutputs(
22-
reports: string[],
25+
reports: CoverageReport[],
2326
coverageTypes: CoverageType[],
2427
): Promise<AuditOutputs> {
2528
const parsedReports = await Promise.all(
2629
reports.map(report =>
27-
readTextFile(report).then(reportContent => parseLcov(reportContent)),
30+
readTextFile(toUnixPath(report.resultsPath))
31+
.then(reportContent => parseLcov(reportContent))
32+
.then(records =>
33+
records.map<LCOVRecord>(record => ({
34+
...record,
35+
file:
36+
report.pathToProject == null
37+
? record.file
38+
: join(report.pathToProject, record.file),
39+
})),
40+
),
2841
),
2942
);
30-
3143
if (parsedReports.length !== reports.length) {
3244
throw new Error('Some provided LCOV reports were not valid.');
3345
}

0 commit comments

Comments
 (0)