Skip to content

Commit 181b6dd

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

12 files changed

+860
-238
lines changed

Diff for: action.yml

+3
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

Diff for: dist/main.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: src/badge.js

+25-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import path from "path";
2-
import fs from "fs";
31
import { badgen } from "badgen";
2+
import path from "path";
43
import { percentage } from "./lcov";
54

6-
const badge = (option, pct) => {
7-
const { label = "coverage", style = "classic" } = option || {};
5+
export const badge = (option, pct) => {
6+
const { label = "coverage", style = "classic" } = option;
87
const colorData = {
98
"49c31a": [100],
109
"97c40f": [99.99, 90],
@@ -22,26 +21,37 @@ const badge = (option, pct) => {
2221
const badgenArgs = {
2322
style,
2423
label,
25-
status: `${pct < 0 ? "Unknown" : `${pct}%`}`,
26-
color: color || "e5e5e5",
24+
status: `${pct}%`,
25+
color: color,
2726
};
2827
return badgen(badgenArgs);
2928
};
3029

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");
30+
export const badges = ({ rootLcov, lcovArray, options, mkDir, writeBadge }) => {
31+
const badgeOptions = {
32+
label: options.badgeLabel,
33+
style: options.badgeStyle,
34+
};
35+
const toBadge = [];
36+
if (lcovArray) lcovArray.forEach((x) => toBadge.push(x));
37+
if (rootLcov) {
38+
toBadge.push({
39+
packageName: "root_package",
40+
lcov: rootLcov,
41+
});
42+
}
43+
if (toBadge.length === 0) {
44+
return;
3745
}
38-
for (const lcovObj of toCheck) {
46+
const dirName = path.resolve(options.badgePath);
47+
mkDir(dirName);
48+
for (const lcovObj of toBadge) {
3949
const coverage = percentage(lcovObj.lcov);
40-
const svgStr = badge(options, coverage.toFixed(2));
50+
const svgStr = badge(badgeOptions, coverage.toFixed(2));
4151
const fileName = path.join(dirName, `${lcovObj.packageName}.svg`);
4252
console.log("writing badge", fileName);
4353
try {
44-
fs.writeFileSync(fileName, svgStr);
54+
writeBadge(fileName, svgStr);
4555
} catch (err) {
4656
console.error("Error writing badge", fileName, err.toString());
4757
}

Diff for: src/badge.test.js

+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import { badges } from "./badge";
2+
import path from "path";
3+
4+
const someLcov = [
5+
{
6+
file: "/files/project/src/foo.js",
7+
lines: {
8+
found: 23,
9+
hit: 21,
10+
details: [
11+
{
12+
line: 20,
13+
hit: 3,
14+
},
15+
{
16+
line: 21,
17+
hit: 3,
18+
},
19+
{
20+
line: 22,
21+
hit: 3,
22+
},
23+
],
24+
},
25+
functions: {
26+
hit: 2,
27+
found: 3,
28+
details: [
29+
{
30+
name: "foo",
31+
line: 19,
32+
},
33+
{
34+
name: "bar",
35+
line: 33,
36+
},
37+
{
38+
name: "baz",
39+
line: 54,
40+
},
41+
],
42+
},
43+
branches: {
44+
hit: 3,
45+
found: 3,
46+
details: [
47+
{
48+
line: 21,
49+
block: 0,
50+
branch: 0,
51+
taken: 1,
52+
},
53+
{
54+
line: 21,
55+
block: 0,
56+
branch: 1,
57+
taken: 2,
58+
},
59+
{
60+
line: 37,
61+
block: 1,
62+
branch: 0,
63+
taken: 0,
64+
},
65+
],
66+
},
67+
},
68+
{
69+
file: "/files/project/src/bar/baz.js",
70+
lines: {
71+
found: 10,
72+
hit: 5,
73+
details: [
74+
{
75+
line: 20,
76+
hit: 0,
77+
},
78+
{
79+
line: 21,
80+
hit: 0,
81+
},
82+
{
83+
line: 22,
84+
hit: 3,
85+
},
86+
],
87+
},
88+
functions: {
89+
hit: 2,
90+
found: 3,
91+
details: [
92+
{
93+
name: "foo",
94+
line: 19,
95+
},
96+
{
97+
name: "bar",
98+
line: 33,
99+
},
100+
{
101+
name: "baz",
102+
line: 54,
103+
},
104+
],
105+
},
106+
},
107+
];
108+
const lcovArray = [
109+
{
110+
packageName: "SOME_PACKAGE",
111+
lcov: someLcov,
112+
},
113+
{
114+
packageName: "SOME_PACKAGE2",
115+
lcov: someLcov,
116+
},
117+
{
118+
packageName: "SOME_PACKAGE3",
119+
lcov: someLcov,
120+
},
121+
];
122+
const SOME_PATH = "SOME_PATH/";
123+
describe("badges", function () {
124+
test("should render badges rootLcov", () => {
125+
const mkDir = jest.fn();
126+
const writeBadge = jest.fn();
127+
badges({
128+
rootLcov: someLcov,
129+
lcovArray: undefined,
130+
options: { badgePath: SOME_PATH },
131+
mkDir,
132+
writeBadge,
133+
});
134+
expect(mkDir).toBeCalledWith(path.resolve(SOME_PATH));
135+
expect(writeBadge).toBeCalledWith(
136+
expect.stringContaining("root_package.svg"),
137+
expect.stringContaining("<svg"),
138+
);
139+
});
140+
test("should render badges lcovArray", () => {
141+
const mkDir = jest.fn();
142+
const writeBadge = jest.fn();
143+
badges({
144+
rootLcov: undefined,
145+
lcovArray,
146+
options: { badgePath: SOME_PATH },
147+
mkDir,
148+
writeBadge,
149+
});
150+
expect(mkDir).toBeCalledWith(path.resolve(SOME_PATH));
151+
for (let i = 0; i < lcovArray.length; i++) {
152+
expect(writeBadge).toHaveBeenNthCalledWith(
153+
i + 1,
154+
expect.stringContaining(`${lcovArray[i].packageName}.svg`),
155+
expect.stringContaining("<svg"),
156+
);
157+
}
158+
});
159+
test("should do nothing with no data", () => {
160+
const mkDir = jest.fn();
161+
const writeBadge = jest.fn();
162+
badges({
163+
rootLcov: undefined,
164+
lcovArray: undefined,
165+
options: { badgePath: SOME_PATH },
166+
mkDir,
167+
writeBadge,
168+
});
169+
expect(mkDir).not.toBeCalled();
170+
expect(writeBadge).not.toBeCalled();
171+
});
172+
test("should catch errors when writting", () => {
173+
const mkDir = jest.fn();
174+
const writeBadge = () => {
175+
throw new Error();
176+
};
177+
expect(() =>
178+
badges({
179+
rootLcov: undefined,
180+
lcovArray,
181+
options: {
182+
badgePath: SOME_PATH,
183+
label: "other",
184+
style: "flat",
185+
},
186+
mkDir,
187+
writeBadge,
188+
}),
189+
).not.toThrowError();
190+
expect(mkDir).toBeCalledWith(path.resolve(SOME_PATH));
191+
});
192+
});

Diff for: src/check.js

+41-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,56 @@
11
import { percentage } from "./lcov";
22

3-
export const checkCoverage = (minCoverage, toCheck) => {
3+
const checkCoverage = (toCheck) => {
44
let accum = 0;
55
for (const lcovObj of toCheck) {
66
const coverage = percentage(lcovObj.lcov);
7-
const isValidBuild = coverage >= minCoverage;
7+
const isValidBuild = coverage >= lcovObj.minCoverage;
88
if (!isValidBuild) {
99
return { isValidBuild, coverage, name: lcovObj.packageName };
1010
}
1111
accum += coverage;
1212
}
13-
1413
return {
1514
isValidBuild: true,
16-
coverage: toCheck.length === 0 ? 0 : accum / toCheck.length,
15+
coverage: accum / toCheck.length,
1716
name: "average",
1817
};
1918
};
19+
20+
export const checks = ({ rootLcov, lcovArray, options, setFailed, info }) => {
21+
const minCoverage = options.minCoverage || 100;
22+
const excludedFiles = (options.excluded || "")
23+
.split(" ")
24+
.map((x) => x.trim())
25+
.filter((x) => x.length > 0);
26+
const toCheck = [];
27+
if (lcovArray) {
28+
lcovArray
29+
.filter((x) => !excludedFiles.some((y) => x.packageName === y))
30+
.forEach((x) => toCheck.push({ minCoverage, ...x }));
31+
}
32+
if (rootLcov && !options.excludeRoot) {
33+
toCheck.unshift({
34+
packageName: "root_package",
35+
lcov: rootLcov,
36+
minCoverage,
37+
});
38+
}
39+
if (toCheck.length === 0) {
40+
return;
41+
}
42+
const { isValidBuild, coverage, name } = checkCoverage(toCheck);
43+
if (!isValidBuild) {
44+
setFailed(
45+
`${coverage.toFixed(
46+
2,
47+
)}% for ${name} is less than min_coverage ${minCoverage}.`,
48+
);
49+
} else {
50+
info(
51+
`Coverage: ${coverage.toFixed(
52+
2,
53+
)}% is greater than or equal to min_coverage ${minCoverage}.`,
54+
);
55+
}
56+
};

0 commit comments

Comments
 (0)