Skip to content

Commit 238ed3b

Browse files
committed
chore(plugin-coverage): make coverageTypes optional, improve branch issues, score precision
1 parent cd5159f commit 238ed3b

11 files changed

Lines changed: 120 additions & 98 deletions

File tree

code-pushup.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ const config: CoreConfig = {
4646
plugins: [
4747
await eslintPlugin(await eslintConfigFromNxProjects()),
4848
coveragePlugin({
49-
coverageType: ['branch', 'function', 'line'],
5049
reports: [
5150
{
5251
resultsPath: 'coverage/cli/unit-tests/lcov.info',

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default {
3737
],
3838
plugins: [
3939
coveragePlugin({
40-
coverageType: ['branch', 'function', 'line'],
40+
coverageTypes: ['branch', 'function', 'line'],
4141
reports: [
4242
{
4343
resultsPath: join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info'),

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
3333
{
3434
"audits": [
3535
{
36-
"description": "branch coverage percentage on the project",
36+
"description": "Branch coverage percentage on the project.",
3737
"details": {
3838
"issues": [
3939
{
40-
"message": "Branch 1 is not taken in any test case.",
40+
"message": "2nd branch is not taken in any test case.",
4141
"severity": "error",
4242
"source": {
4343
"file": "packages/cli/src/lib/partly-covered/utils.ts",
@@ -47,7 +47,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
4747
},
4848
},
4949
{
50-
"message": "Branch 1 is not taken in any test case.",
50+
"message": "2nd branch is not taken in any test case.",
5151
"severity": "error",
5252
"source": {
5353
"file": "packages/cli/src/lib/partly-covered/utils.ts",
@@ -57,7 +57,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
5757
},
5858
},
5959
{
60-
"message": "Branch 0 is not taken in any test case.",
60+
"message": "1st branch is not taken in any test case.",
6161
"severity": "error",
6262
"source": {
6363
"file": "packages/cli/src/lib/not-covered/sorting.ts",
@@ -67,7 +67,7 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
6767
},
6868
},
6969
{
70-
"message": "Branch 1 is not taken in any test case.",
70+
"message": "2nd branch is not taken in any test case.",
7171
"severity": "error",
7272
"source": {
7373
"file": "packages/cli/src/lib/not-covered/sorting.ts",
@@ -79,13 +79,13 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
7979
],
8080
},
8181
"displayValue": "76 %",
82-
"score": 0.76,
82+
"score": 0.7647,
8383
"slug": "branch-coverage",
84-
"title": "branch coverage",
84+
"title": "Branch coverage",
8585
"value": 76,
8686
},
8787
{
88-
"description": "function coverage percentage on the project",
88+
"description": "Function coverage percentage on the project.",
8989
"details": {
9090
"issues": [
9191
{
@@ -113,11 +113,11 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
113113
"displayValue": "60 %",
114114
"score": 0.6,
115115
"slug": "function-coverage",
116-
"title": "function coverage",
116+
"title": "Function coverage",
117117
"value": 60,
118118
},
119119
{
120-
"description": "line coverage percentage on the project",
120+
"description": "Line coverage percentage on the project.",
121121
"details": {
122122
"issues": [
123123
{
@@ -147,12 +147,12 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
147147
"displayValue": "68 %",
148148
"score": 0.68,
149149
"slug": "line-coverage",
150-
"title": "line coverage",
150+
"title": "Line coverage",
151151
"value": 68,
152152
},
153153
],
154-
"description": "Official Code PushUp code coverage plugin",
155-
"docsUrl": "https://www.softwaretestinghelp.com/code-coverage-tutorial/",
154+
"description": "Official Code PushUp code coverage plugin.",
155+
"docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/",
156156
"icon": "folder-coverage-open",
157157
"packageName": "@code-pushup/coverage-plugin",
158158
"slug": "coverage",

packages/plugin-coverage/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ Measured coverage types are mapped to Code PushUp audits in the following way
1818

1919
3. Add this plugin to the `plugins` array in your Code PushUp CLI config file (e.g. `code-pushup.config.js`).
2020

21-
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.
21+
Pass paths to the code coverage results in LCOV format and optionally define your code coverage tool to be run first.
22+
All coverage types are measured by default. If you wish to focus on a subset of offered types of coverage, define them in `coverageTypes`.
2223

2324
📌 Please note that when you define the tool command, you still need to define the paths to all relevant coverage results.
2425

@@ -32,7 +33,6 @@ Measured coverage types are mapped to Code PushUp audits in the following way
3233
plugins: [
3334
// ...
3435
await coveragePlugin({
35-
coverageType: ['branch', 'function', 'line'],
3636
reports: [{ resultsPath: 'coverage/cli/lcov.info', pathToProject: 'packages/cli' }],
3737
coverageToolCommand: {
3838
command: 'npx',
@@ -121,7 +121,7 @@ It recognises the following entities:
121121

122122
The plugin accepts the following parameters:
123123

124-
- `coverageType`: An array of types of coverage that you wish to track. Supported values: `function`, `branch`, `line`.
124+
- `coverageTypes`: An array of types of coverage that you wish to track. Supported values: `function`, `branch`, `line`. Defaults to all available types.
125125
- `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.
126126
- (optional) `coverageToolCommand`: If you wish to run your coverage tool to generate the results first, you may define it here.
127127
- (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.

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,25 @@ export const coveragePluginConfigSchema = z.object({
2727
.optional(),
2828
})
2929
.optional(),
30-
coverageType: z.array(coverageTypeSchema).min(1),
30+
coverageTypes: z
31+
.array(coverageTypeSchema, {
32+
description: 'Coverage types measured. Defaults to all available types.',
33+
})
34+
.min(1)
35+
.default(['function', 'branch', 'line']),
3136
reports: z
3237
.array(coverageReportSchema, {
3338
description:
3439
'Path to all code coverage report files. Only LCOV format is supported for now.',
3540
})
3641
.min(1),
3742
perfectScoreThreshold: z
38-
.number({ description: 'Score will be 100 for this coverage and above.' })
39-
.min(1)
40-
.max(100)
43+
.number({
44+
description:
45+
'Score will be 1 (perfect) for this coverage and above. Score range is 0 - 1.',
46+
})
47+
.gt(0)
48+
.max(1)
4149
.optional(),
4250
});
43-
44-
export type CoveragePluginConfig = z.infer<typeof coveragePluginConfigSchema>;
51+
export type CoveragePluginConfig = z.input<typeof coveragePluginConfigSchema>;

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

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { describe, expect, it } from 'vitest';
2-
import { CoveragePluginConfig, coveragePluginConfigSchema } from './config';
2+
import {
3+
CoveragePluginConfig,
4+
CoverageType,
5+
coveragePluginConfigSchema,
6+
} from './config';
37

48
describe('coveragePluginConfigSchema', () => {
59
it('accepts a code coverage configuration with all entities', () => {
610
expect(() =>
711
coveragePluginConfigSchema.parse({
8-
coverageType: ['branch', 'function'],
12+
coverageTypes: ['branch', 'function'],
913
reports: [
1014
{
1115
resultsPath: 'coverage/cli/lcov.info',
@@ -16,24 +20,37 @@ describe('coveragePluginConfigSchema', () => {
1620
command: 'npx nx run-many',
1721
args: ['-t', 'test', '--coverage'],
1822
},
19-
perfectScoreThreshold: 85,
23+
perfectScoreThreshold: 0.85,
2024
} satisfies CoveragePluginConfig),
2125
).not.toThrow();
2226
});
2327

2428
it('accepts a minimal code coverage configuration', () => {
2529
expect(() =>
2630
coveragePluginConfigSchema.parse({
27-
coverageType: ['line'],
2831
reports: [{ resultsPath: 'coverage/cli/lcov.info' }],
2932
} satisfies CoveragePluginConfig),
3033
).not.toThrow();
3134
});
3235

33-
it('throws for no coverage type', () => {
36+
it('replaces undefined coverage with all available types', () => {
37+
const config = {
38+
reports: [{ resultsPath: 'coverage/cli/lcov.info' }],
39+
} satisfies CoveragePluginConfig;
40+
expect(() => coveragePluginConfigSchema.parse(config)).not.toThrow();
41+
42+
const { coverageTypes } = coveragePluginConfigSchema.parse(config);
43+
expect(coverageTypes).toEqual([
44+
'function',
45+
'branch',
46+
'line',
47+
] satisfies CoverageType[]);
48+
});
49+
50+
it('throws for empty coverage type array', () => {
3451
expect(() =>
3552
coveragePluginConfigSchema.parse({
36-
coverageType: [],
53+
coverageTypes: [],
3754
reports: [{ resultsPath: 'coverage/cli/lcov.info' }],
3855
} satisfies CoveragePluginConfig),
3956
).toThrow('too_small');
@@ -42,7 +59,7 @@ describe('coveragePluginConfigSchema', () => {
4259
it('throws for no report', () => {
4360
expect(() =>
4461
coveragePluginConfigSchema.parse({
45-
coverageType: ['branch'],
62+
coverageTypes: ['branch'],
4663
reports: [],
4764
} satisfies CoveragePluginConfig),
4865
).toThrow('too_small');
@@ -51,7 +68,7 @@ describe('coveragePluginConfigSchema', () => {
5168
it('throws for unsupported report format', () => {
5269
expect(() =>
5370
coveragePluginConfigSchema.parse({
54-
coverageType: ['line'],
71+
coverageTypes: ['line'],
5572
reports: [{ resultsPath: 'coverage/cli/coverage-final.json' }],
5673
} satisfies CoveragePluginConfig),
5774
).toThrow(/Invalid input: must include.+lcov/);
@@ -60,7 +77,7 @@ describe('coveragePluginConfigSchema', () => {
6077
it('throws for missing command', () => {
6178
expect(() =>
6279
coveragePluginConfigSchema.parse({
63-
coverageType: ['line'],
80+
coverageTypes: ['line'],
6481
reports: ['coverage/cli/lcov.info'],
6582
coverageToolCommand: {
6683
args: ['npx', 'nx', 'run-many', '-t', 'test', '--coverage'],
@@ -72,9 +89,9 @@ describe('coveragePluginConfigSchema', () => {
7289
it('throws for invalid score threshold', () => {
7390
expect(() =>
7491
coveragePluginConfigSchema.parse({
75-
coverageType: ['line'],
92+
coverageTypes: ['line'],
7693
reports: [{ resultsPath: 'coverage/cli/lcov.info' }],
77-
perfectScoreThreshold: 110,
94+
perfectScoreThreshold: 1.1,
7895
} satisfies CoveragePluginConfig),
7996
).toThrow('too_big');
8097
});

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest';
33
import { CoveragePluginConfig } from './config';
44
import { coveragePlugin } from './coverage-plugin';
55

6-
describe('coveragePluginConfigSchema', () => {
6+
describe('coveragePlugin', () => {
77
const LCOV_PATH = join(
88
'packages',
99
'plugin-coverage',
@@ -14,7 +14,7 @@ describe('coveragePluginConfigSchema', () => {
1414
it('should initialise a Code coverage plugin', () => {
1515
expect(
1616
coveragePlugin({
17-
coverageType: ['function'],
17+
coverageTypes: ['function'],
1818
reports: [{ resultsPath: LCOV_PATH }],
1919
}),
2020
).toStrictEqual(
@@ -29,16 +29,16 @@ describe('coveragePluginConfigSchema', () => {
2929
it('should generate audits from coverage types', () => {
3030
expect(
3131
coveragePlugin({
32-
coverageType: ['function', 'branch'],
32+
coverageTypes: ['function', 'branch'],
3333
reports: [{ resultsPath: LCOV_PATH }],
3434
}),
3535
).toStrictEqual(
3636
expect.objectContaining({
3737
audits: [
3838
{
3939
slug: 'function-coverage',
40-
title: 'function coverage',
41-
description: 'function coverage percentage on the project',
40+
title: 'Function coverage',
41+
description: expect.stringContaining('Function coverage'),
4242
},
4343
expect.objectContaining({ slug: 'branch-coverage' }),
4444
],
@@ -49,7 +49,7 @@ describe('coveragePluginConfigSchema', () => {
4949
it('should assign RunnerConfig when a command is passed', () => {
5050
expect(
5151
coveragePlugin({
52-
coverageType: ['line'],
52+
coverageTypes: ['line'],
5353
reports: [{ resultsPath: LCOV_PATH }],
5454
coverageToolCommand: {
5555
command: 'npm run-many',
@@ -72,7 +72,7 @@ describe('coveragePluginConfigSchema', () => {
7272
it('should assign a RunnerFunction when only reports are passed', () => {
7373
expect(
7474
coveragePlugin({
75-
coverageType: ['line'],
75+
coverageTypes: ['line'],
7676
reports: [{ resultsPath: LCOV_PATH }],
7777
} satisfies CoveragePluginConfig),
7878
).toStrictEqual(

0 commit comments

Comments
 (0)