Skip to content

Commit 9d3a7b4

Browse files
author
Andres Adjimann
committed
test: more testeable code, multiple comments
1 parent 0a2dcdf commit 9d3a7b4

File tree

7 files changed

+278
-233
lines changed

7 files changed

+278
-233
lines changed

action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ inputs:
2020
app-name:
2121
description: App name to display on comment
2222
required: false
23+
multiple-comment:
24+
description: Add multiple comments
25+
required: false
2326
max_lines:
2427
description: Maximum numbers of line print
2528
required: false

dist/main.js

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

src/badge.js

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import path from "path";
2-
import fs from "fs";
31
import { badgen } from "badgen";
4-
import { percentage } from "./lcov";
52

6-
const badge = (option, pct) => {
3+
export const badge = (option, pct) => {
74
const { label = "coverage", style = "classic" } = option || {};
85
const colorData = {
96
"49c31a": [100],
@@ -27,23 +24,3 @@ const badge = (option, pct) => {
2724
};
2825
return badgen(badgenArgs);
2926
};
30-
31-
export const createBadges = (badgePath, toCheck, options) => {
32-
const dirName = path.resolve(badgePath);
33-
if (!fs.existsSync(dirName)) {
34-
fs.mkdirSync(dirName);
35-
} else if (!fs.statSync(dirName).isDirectory()) {
36-
throw new Error("badge path is not a directory");
37-
}
38-
for (const lcovObj of toCheck) {
39-
const coverage = percentage(lcovObj.lcov);
40-
const svgStr = badge(options, coverage.toFixed(2));
41-
const fileName = path.join(dirName, `${lcovObj.packageName}.svg`);
42-
console.log("writing badge", fileName);
43-
try {
44-
fs.writeFileSync(fileName, svgStr);
45-
} catch (err) {
46-
console.error("Error writing badge", fileName, err.toString());
47-
}
48-
}
49-
};

src/cli.js

Lines changed: 33 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,44 @@
11
import process from "process";
22
import fs from "fs";
33
import path from "path";
4-
import { diff, diffForMonorepo } from "./comment";
5-
import { getLcovArray, readLcov } from "./monorepo";
6-
import { checkCoverage } from "./check";
7-
import { createBadges } from "./badge";
4+
import { codeCoverageAssistant } from "./codeCoverageAssistant";
85

9-
const addPackageName = (x) => ({
10-
...x,
11-
...{ packageName: x.dir.split("/").slice(-2)[0] },
12-
});
136
const main = async () => {
147
const file = process.argv[2];
15-
const beforeFile = process.argv[3];
16-
178
const prefix = `${path.dirname(path.dirname(path.resolve(file)))}/`;
18-
const options = {
19-
repository: "example/foo",
20-
commit: "f9d42291812ed03bb197e48050ac38ac6befe4e5",
21-
prefix,
22-
head: "feat/test",
23-
base: "master",
24-
maxLines: "10",
9+
const baseClient = {
10+
upsert: (title, body) => {
11+
console.log("--> COMMENT", "title:", title, "body:", body);
12+
},
13+
mkDir: (dirName) => console.log("Creating directory", dirName),
14+
writeBadge: (fileName) => console.log("written", fileName),
15+
getPackageName: (x) => x.split("/").slice(-2)[0],
16+
setFailed: (...x) => console.error("ERROR", ...x),
17+
info: (...x) => console.log("INFO:", ...x),
18+
options: {
19+
repository: "example/foo",
20+
commit: "f9d42291812ed03bb197e48050ac38ac6befe4e5",
21+
prefix,
22+
head: "feat/test",
23+
base: "master",
24+
maxLines: 100,
25+
badgePath: "./badges",
26+
appName: "someAppName",
27+
minCoverage: 80,
28+
multipleComment: true,
29+
},
2530
};
26-
27-
if (fs.statSync(file).isDirectory()) {
28-
const lcovArrayForMonorepo = (
29-
await getLcovArray(file, "lcov.info")
30-
).map(addPackageName);
31-
console.log(
32-
diffForMonorepo(
33-
lcovArrayForMonorepo,
34-
await getLcovArray(file, "lcov-base"),
35-
options,
36-
),
37-
);
38-
createBadges("./badges", lcovArrayForMonorepo, {});
39-
console.log(checkCoverage(90, lcovArrayForMonorepo));
40-
} else {
41-
const lcov = await readLcov(file);
42-
console.log(
43-
diff(lcov, beforeFile && (await readLcov(beforeFile)), options),
44-
);
45-
createBadges(
46-
"./build",
47-
{
48-
packageName: "root",
49-
lcov,
50-
},
51-
{},
52-
);
53-
console.log(
54-
checkCoverage(90, [
55-
{
56-
packageName: "root",
57-
lcov,
58-
},
59-
]),
60-
);
61-
}
31+
await codeCoverageAssistant({
32+
...(fs.statSync(file).isDirectory()
33+
? {
34+
monorepoBasePath: file,
35+
}
36+
: {
37+
lcovFile: file,
38+
baseFile: "lcov-base",
39+
}),
40+
...baseClient,
41+
});
6242
};
6343

6444
main().catch((err) => {

src/codeCoverageAssistant.js

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import { renderCommentArray, renderCommentLine } from "./comment";
2+
import { getLcovArray, readLcov } from "./monorepo";
3+
import { checkCoverage } from "./check";
4+
import { badge } from "./badge";
5+
import path from "path";
6+
import { percentage } from "./lcov";
7+
8+
async function comments(
9+
rootLcov,
10+
baseFile,
11+
monorepoBasePath,
12+
lcovArrayForMonorepo,
13+
options,
14+
addPackageName,
15+
upsert,
16+
) {
17+
// Comments
18+
if (lcovArrayForMonorepo.length > 0) {
19+
const lcovBaseArrayForMonorepo = (
20+
await getLcovArray(monorepoBasePath, "lcov-base")
21+
).map(addPackageName);
22+
if (options.multipleComment) {
23+
for (const lcovObj of lcovArrayForMonorepo) {
24+
const baseLcov = lcovBaseArrayForMonorepo.find(
25+
(el) => el.packageName === lcovObj.packageName,
26+
);
27+
const body = renderCommentLine(
28+
lcovObj.lcov,
29+
baseLcov && baseLcov.lcov,
30+
lcovObj.packageName,
31+
options,
32+
);
33+
await upsert(`m-${lcovObj.packageName}`, body);
34+
}
35+
} else {
36+
const body = renderCommentArray(
37+
lcovArrayForMonorepo,
38+
lcovBaseArrayForMonorepo,
39+
options,
40+
);
41+
await upsert("single-comment", body);
42+
}
43+
}
44+
if (rootLcov) {
45+
const body = renderCommentLine(
46+
rootLcov,
47+
baseFile && (await readLcov(baseFile)),
48+
"root",
49+
options,
50+
);
51+
await upsert(`root-comment`, body);
52+
}
53+
}
54+
55+
async function badges(
56+
rootLcov,
57+
lcovArrayForMonorepo,
58+
options,
59+
mkDir,
60+
writeBadge,
61+
) {
62+
const badgeOptions = {
63+
label: options.badgeLabel,
64+
style: options.badgeStyle,
65+
};
66+
const toBadge = lcovArrayForMonorepo;
67+
if (rootLcov) {
68+
toBadge.push({
69+
packageName: "root_package",
70+
lcov: rootLcov,
71+
});
72+
}
73+
const dirName = path.resolve(options.badgePath);
74+
mkDir(dirName);
75+
for (const lcovObj of toBadge) {
76+
const coverage = percentage(lcovObj.lcov);
77+
const svgStr = badge(badgeOptions, coverage.toFixed(2));
78+
const fileName = path.join(dirName, `${lcovObj.packageName}.svg`);
79+
console.log("writing badge", fileName);
80+
try {
81+
writeBadge(fileName, svgStr);
82+
} catch (err) {
83+
console.error("Error writing badge", fileName, err.toString());
84+
}
85+
}
86+
}
87+
88+
async function checks(
89+
rootLcov,
90+
lcovArrayForMonorepo,
91+
options,
92+
setFailed,
93+
info,
94+
) {
95+
const excludedFiles = (options.excluded || "")
96+
.split(" ")
97+
.map((x) => x.trim())
98+
.filter((x) => x.length > 0);
99+
const toCheck = lcovArrayForMonorepo.filter(
100+
(x) => !excludedFiles.some((y) => x.packageName === y),
101+
);
102+
if (rootLcov && !options.excludeRoot) {
103+
toCheck.unshift({
104+
packageName: "root_package",
105+
lcov: rootLcov,
106+
});
107+
}
108+
const { isValidBuild, coverage, name } = checkCoverage(
109+
options.minCoverage,
110+
toCheck,
111+
);
112+
if (!isValidBuild) {
113+
setFailed(
114+
`${coverage.toFixed(2)}% for ${name} is less than min_coverage ${
115+
options.minCoverage
116+
}.`,
117+
);
118+
} else {
119+
info(
120+
`Coverage: ${coverage.toFixed(
121+
2,
122+
)}% is greater than or equal to min_coverage ${
123+
options.minCoverage
124+
}.`,
125+
);
126+
}
127+
}
128+
129+
export const codeCoverageAssistant = async ({
130+
monorepoBasePath,
131+
lcovFile,
132+
baseFile,
133+
options,
134+
upsert,
135+
mkDir,
136+
writeBadge,
137+
getPackageName,
138+
setFailed,
139+
info,
140+
}) => {
141+
const addPackageName = (x) => ({
142+
...x,
143+
...{ packageName: getPackageName(x.dir) },
144+
});
145+
const lcovArrayForMonorepo = (
146+
monorepoBasePath
147+
? await getLcovArray(monorepoBasePath, "lcov.info")
148+
: []
149+
).map(addPackageName);
150+
// Always process root file if exists.
151+
const rootLcov = lcovFile && (await readLcov(lcovFile));
152+
if (options.maxLines > 0) {
153+
await comments(
154+
rootLcov,
155+
baseFile,
156+
monorepoBasePath,
157+
lcovArrayForMonorepo,
158+
options,
159+
addPackageName,
160+
upsert,
161+
);
162+
}
163+
if (options.badgePath) {
164+
await badges(
165+
rootLcov,
166+
lcovArrayForMonorepo,
167+
options,
168+
mkDir,
169+
writeBadge,
170+
);
171+
}
172+
if (options.minCoverage) {
173+
await checks(rootLcov, lcovArrayForMonorepo, options, setFailed, info);
174+
}
175+
};

src/comment.js

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const comparer = (otherArray) => (current) =>
3535
).length === 0;
3636

3737
const renderLcov = (lcov, base, appTitle, options) => {
38-
const maxLines = options.maxLines || 15;
3938
const pbefore = base ? percentage(base) : 0;
4039
const pafter = base ? percentage(lcov) : 0;
4140
const pdiff = pafter - pbefore;
@@ -71,7 +70,7 @@ const renderLcov = (lcov, base, appTitle, options) => {
7170
}
7271
return [
7372
table(tbody(tr(...row))),
74-
report.length > maxLines
73+
report.length > options.maxLines
7574
? p("Coverage Report too long to display")
7675
: details(summary("Coverage Report"), tabulate(report, options)),
7776
"<br/>",
@@ -81,10 +80,10 @@ const renderLcov = (lcov, base, appTitle, options) => {
8180
/**
8281
* Github comment for monorepo
8382
* @param {Array<{packageName, lcovPath}>} lcovArrayForMonorepo
84-
* @param {{Array<{packageName, lcovBasePath}>}} lcovBaseArrayForMonorepo
83+
* @param {Array<{packageName, lcovPath}>} lcovBaseArrayForMonorepo
8584
* @param {*} options
8685
*/
87-
const commentForMonorepo = (
86+
export const renderCommentArray = (
8887
lcovArrayForMonorepo,
8988
lcovBaseArrayForMonorepo,
9089
options,
@@ -110,32 +109,14 @@ const commentForMonorepo = (
110109

111110
/**
112111
* Github comment for single repo
113-
* @param {raw lcov} lcov
112+
* @param {raw} lcov
113+
* @param {raw} baseLcov
114+
* @param {string} appTitle
114115
* @param {*} options
115116
*/
116-
const comment = (lcov, before, options) => {
117-
const { appName, base } = options;
117+
export const renderCommentLine = (lcov, baseLcov, appTitle, options) => {
118+
const inner = renderLcov(lcov, baseLcov, appTitle, options);
119+
const { base } = options;
118120
const title = `Coverage after merging into ${b(base)} <p></p>`;
119-
return fragment(title, renderLcov(lcov, before, appName, options));
121+
return fragment(title, inner);
120122
};
121-
122-
/**
123-
* Diff in coverage percentage for single repo
124-
* @param {raw lcov} lcov
125-
* @param {raw base lcov} before
126-
* @param {*} options
127-
*/
128-
export const diff = (lcov, before, options) => comment(lcov, before, options);
129-
130-
/**
131-
* Diff in coverage percentage for monorepo
132-
* @param {Array<{packageName, lcovPath}>} lcovArrayForMonorepo
133-
* @param {{Array<{packageName, lcovBasePath}>}} lcovBaseArrayForMonorepo
134-
* @param {*} options
135-
*/
136-
export const diffForMonorepo = (
137-
lcovArrayForMonorepo,
138-
lcovBaseArrayForMonorepo,
139-
options,
140-
) =>
141-
commentForMonorepo(lcovArrayForMonorepo, lcovBaseArrayForMonorepo, options);

0 commit comments

Comments
 (0)