Skip to content

Commit d259c14

Browse files
committed
feat(plugin-coverage): add coverage tool run option, convert to runnerConfig
1 parent e05a56e commit d259c14

18 files changed

+285
-191
lines changed

.github/workflows/ci.yml

-2
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,6 @@ jobs:
173173
cache: npm
174174
- name: Install dependencies
175175
run: npm ci
176-
- name: Collect unit test coverage (temporary due to coverage plugin)
177-
run: npx nx run-many -t unit-test --coverage
178176
- name: Collect Code PushUp report
179177
run: npx nx run-collect
180178
- name: Upload Code PushUp report to portal

.github/workflows/release.yml

-2
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ jobs:
9090
run: |
9191
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> .npmrc
9292
npx nx run-many -t=deploy --exclude=plugin-lighthouse,nx-plugin
93-
- name: Collect unit test coverage (temporary due to coverage plugin)
94-
run: npx nx run-many -t unit-test --coverage
9593
- name: Collect and upload Code PushUp report
9694
run: npx nx run-autorun
9795
env:

code-pushup.config.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ const config: CoreConfig = {
4949

5050
plugins: [
5151
await eslintPlugin(await eslintConfigFromNxProjects()),
52-
coveragePlugin({
52+
await coveragePlugin({
53+
coverageToolCommand: {
54+
command: 'npx',
55+
args: ['nx', 'run-many', '-t', 'unit-test', '--coverage'],
56+
},
5357
reports: [
5458
{
5559
resultsPath: 'coverage/cli/unit-tests/lcov.info',

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

+3-16
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,16 @@ export default {
1515
title: 'Code coverage',
1616
refs: [
1717
{
18-
type: 'audit',
18+
type: 'group',
1919
plugin: 'coverage',
20-
slug: 'function-coverage',
21-
weight: 1,
22-
},
23-
{
24-
type: 'audit',
25-
plugin: 'coverage',
26-
slug: 'branch-coverage',
27-
weight: 1,
28-
},
29-
{
30-
type: 'audit',
31-
plugin: 'coverage',
32-
slug: 'line-coverage',
20+
slug: 'coverage',
3321
weight: 1,
3422
},
3523
],
3624
},
3725
],
3826
plugins: [
39-
coveragePlugin({
40-
coverageTypes: ['branch', 'function', 'line'],
27+
await coveragePlugin({
4128
reports: [
4229
{
4330
resultsPath: join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info'),

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

+36-48
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,8 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
77
"refs": [
88
{
99
"plugin": "coverage",
10-
"slug": "function-coverage",
11-
"type": "audit",
12-
"weight": 1,
13-
},
14-
{
15-
"plugin": "coverage",
16-
"slug": "branch-coverage",
17-
"type": "audit",
18-
"weight": 1,
19-
},
20-
{
21-
"plugin": "coverage",
22-
"slug": "line-coverage",
23-
"type": "audit",
10+
"slug": "coverage",
11+
"type": "group",
2412
"weight": 1,
2513
},
2614
],
@@ -32,6 +20,38 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
3220
"plugins": [
3321
{
3422
"audits": [
23+
{
24+
"description": "Measures how many functions were called in at least one test.",
25+
"details": {
26+
"issues": [
27+
{
28+
"message": "Function formatReportScore is not called in any test case.",
29+
"severity": "error",
30+
"source": {
31+
"file": "packages/cli/src/lib/partly-covered/utils.ts",
32+
"position": {
33+
"startLine": 2,
34+
},
35+
},
36+
},
37+
{
38+
"message": "Function sortReport is not called in any test case.",
39+
"severity": "error",
40+
"source": {
41+
"file": "packages/cli/src/lib/not-covered/sorting.ts",
42+
"position": {
43+
"startLine": 1,
44+
},
45+
},
46+
},
47+
],
48+
},
49+
"displayValue": "60 %",
50+
"score": 0.6,
51+
"slug": "function-coverage",
52+
"title": "Function coverage",
53+
"value": 60,
54+
},
3555
{
3656
"description": "Measures how many branches were executed after conditional statements in at least one test.",
3757
"details": {
@@ -84,38 +104,6 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
84104
"title": "Branch coverage",
85105
"value": 76,
86106
},
87-
{
88-
"description": "Measures how many functions were called in at least one test.",
89-
"details": {
90-
"issues": [
91-
{
92-
"message": "Function formatReportScore is not called in any test case.",
93-
"severity": "error",
94-
"source": {
95-
"file": "packages/cli/src/lib/partly-covered/utils.ts",
96-
"position": {
97-
"startLine": 2,
98-
},
99-
},
100-
},
101-
{
102-
"message": "Function sortReport is not called in any test case.",
103-
"severity": "error",
104-
"source": {
105-
"file": "packages/cli/src/lib/not-covered/sorting.ts",
106-
"position": {
107-
"startLine": 1,
108-
},
109-
},
110-
},
111-
],
112-
},
113-
"displayValue": "60 %",
114-
"score": 0.6,
115-
"slug": "function-coverage",
116-
"title": "Function coverage",
117-
"value": 60,
118-
},
119107
{
120108
"description": "Measures how many lines of code were executed in at least one test.",
121109
"details": {
@@ -158,11 +146,11 @@ exports[`CLI collect > should run Code coverage plugin and create report.json 1`
158146
"description": "Group containing all defined coverage types as audits.",
159147
"refs": [
160148
{
161-
"slug": "branch-coverage",
149+
"slug": "function-coverage",
162150
"weight": 1,
163151
},
164152
{
165-
"slug": "function-coverage",
153+
"slug": "branch-coverage",
166154
"weight": 1,
167155
},
168156
{

packages/plugin-coverage/project.json

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"outputPath": "dist/packages/plugin-coverage",
1212
"main": "packages/plugin-coverage/src/index.ts",
1313
"tsConfig": "packages/plugin-coverage/tsconfig.lib.json",
14+
"additionalEntryPoints": ["packages/plugin-coverage/src/bin.ts"],
1415
"assets": ["packages/plugin-coverage/*.md"],
1516
"esbuildConfig": "esbuild.config.js"
1617
}

packages/plugin-coverage/src/bin.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { executeRunner } from './lib/runner';
2+
3+
await executeRunner().catch(console.error);

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ 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({
6+
export const coverageResultSchema = z.object({
77
resultsPath: z.string().includes('lcov'),
88
pathToProject: z
99
.string({
@@ -12,7 +12,7 @@ export const coverageReportSchema = z.object({
1212
})
1313
.optional(),
1414
});
15-
export type CoverageReport = z.infer<typeof coverageReportSchema>;
15+
export type CoverageResult = z.infer<typeof coverageResultSchema>;
1616

1717
export const coveragePluginConfigSchema = z.object({
1818
coverageToolCommand: z
@@ -34,7 +34,7 @@ export const coveragePluginConfigSchema = z.object({
3434
.min(1)
3535
.default(['function', 'branch', 'line']),
3636
reports: z
37-
.array(coverageReportSchema, {
37+
.array(coverageResultSchema, {
3838
description:
3939
'Path to all code coverage report files. Only LCOV format is supported for now.',
4040
})
@@ -49,3 +49,6 @@ export const coveragePluginConfigSchema = z.object({
4949
.optional(),
5050
});
5151
export type CoveragePluginConfig = z.input<typeof coveragePluginConfigSchema>;
52+
export type FinalCoveragePluginConfig = z.infer<
53+
typeof coveragePluginConfigSchema
54+
>;
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
1-
import { join } from 'node:path';
2-
import type {
3-
Audit,
4-
Group,
5-
PluginConfig,
6-
RunnerConfig,
7-
RunnerFunction,
8-
} from '@code-pushup/models';
9-
import { capitalize, pluginWorkDir } from '@code-pushup/utils';
1+
import { dirname, join } from 'node:path';
2+
import { fileURLToPath } from 'node:url';
3+
import type { Audit, Group, PluginConfig } from '@code-pushup/models';
4+
import { capitalize } from '@code-pushup/utils';
105
import { name, version } from '../../package.json';
116
import { CoveragePluginConfig, coveragePluginConfigSchema } from './config';
12-
import { lcovResultsToAuditOutputs } from './runner/lcov/runner';
13-
import { applyMaxScoreAboveThreshold, coverageDescription } from './utils';
14-
15-
export const RUNNER_OUTPUT_PATH = join(
16-
pluginWorkDir('coverage'),
17-
'runner-output.json',
18-
);
7+
import { createRunnerConfig } from './runner';
8+
import { coverageDescription } from './utils';
199

2010
/**
2111
* Instantiates Code PushUp code coverage plugin for core config.
@@ -35,11 +25,12 @@ export const RUNNER_OUTPUT_PATH = join(
3525
*
3626
* @returns Plugin configuration.
3727
*/
38-
export function coveragePlugin(config: CoveragePluginConfig): PluginConfig {
39-
const { reports, perfectScoreThreshold, coverageTypes, coverageToolCommand } =
40-
coveragePluginConfigSchema.parse(config);
28+
export async function coveragePlugin(
29+
config: CoveragePluginConfig,
30+
): Promise<PluginConfig> {
31+
const coverageConfig = coveragePluginConfigSchema.parse(config);
4132

42-
const audits = coverageTypes.map(
33+
const audits = coverageConfig.coverageTypes.map(
4334
(type): Audit => ({
4435
slug: `${type}-coverage`,
4536
title: `${capitalize(type)} coverage`,
@@ -54,25 +45,10 @@ export function coveragePlugin(config: CoveragePluginConfig): PluginConfig {
5445
refs: audits.map(audit => ({ ...audit, weight: 1 })),
5546
};
5647

57-
const getAuditOutputs = async () =>
58-
perfectScoreThreshold
59-
? applyMaxScoreAboveThreshold(
60-
await lcovResultsToAuditOutputs(reports, coverageTypes),
61-
perfectScoreThreshold,
62-
)
63-
: await lcovResultsToAuditOutputs(reports, coverageTypes);
64-
65-
// if coverage results are provided, only convert them to AuditOutputs
66-
// if not, run coverage command and then run result conversion
67-
const runner: RunnerConfig | RunnerFunction =
68-
coverageToolCommand == null
69-
? getAuditOutputs
70-
: {
71-
command: coverageToolCommand.command,
72-
args: coverageToolCommand.args,
73-
outputFile: RUNNER_OUTPUT_PATH,
74-
outputTransform: getAuditOutputs,
75-
};
48+
const runnerScriptPath = join(
49+
fileURLToPath(dirname(import.meta.url)),
50+
'bin.js',
51+
);
7652

7753
return {
7854
slug: 'coverage',
@@ -84,6 +60,6 @@ export function coveragePlugin(config: CoveragePluginConfig): PluginConfig {
8460
version,
8561
audits,
8662
groups: [group],
87-
runner,
63+
runner: await createRunnerConfig(runnerScriptPath, coverageConfig),
8864
};
8965
}

0 commit comments

Comments
 (0)