Skip to content

Commit

Permalink
test: more testeable code, multiple comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Andres Adjimann committed Sep 18, 2023
1 parent 0a2dcdf commit bccce9e
Show file tree
Hide file tree
Showing 12 changed files with 860 additions and 238 deletions.
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ inputs:
app-name:
description: App name to display on comment
required: false
multiple-comment:
description: Add multiple comments
required: false
max_lines:
description: Maximum numbers of line print
required: false
Expand Down
4 changes: 2 additions & 2 deletions dist/main.js

Large diffs are not rendered by default.

40 changes: 25 additions & 15 deletions src/badge.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import path from "path";
import fs from "fs";
import { badgen } from "badgen";
import path from "path";
import { percentage } from "./lcov";

const badge = (option, pct) => {
const { label = "coverage", style = "classic" } = option || {};
export const badge = (option, pct) => {
const { label = "coverage", style = "classic" } = option;
const colorData = {
"49c31a": [100],
"97c40f": [99.99, 90],
Expand All @@ -22,26 +21,37 @@ const badge = (option, pct) => {
const badgenArgs = {
style,
label,
status: `${pct < 0 ? "Unknown" : `${pct}%`}`,
color: color || "e5e5e5",
status: `${pct}%`,
color: color,
};
return badgen(badgenArgs);
};

export const createBadges = (badgePath, toCheck, options) => {
const dirName = path.resolve(badgePath);
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName);
} else if (!fs.statSync(dirName).isDirectory()) {
throw new Error("badge path is not a directory");
export const badges = ({ rootLcov, lcovArray, options, mkDir, writeBadge }) => {
const badgeOptions = {
label: options.badgeLabel,
style: options.badgeStyle,
};
const toBadge = [];
if (lcovArray) lcovArray.forEach((x) => toBadge.push(x));
if (rootLcov) {
toBadge.push({
packageName: "root_package",
lcov: rootLcov,
});
}
if (toBadge.length === 0) {
return;
}
for (const lcovObj of toCheck) {
const dirName = path.resolve(options.badgePath);
mkDir(dirName);
for (const lcovObj of toBadge) {
const coverage = percentage(lcovObj.lcov);
const svgStr = badge(options, coverage.toFixed(2));
const svgStr = badge(badgeOptions, coverage.toFixed(2));
const fileName = path.join(dirName, `${lcovObj.packageName}.svg`);
console.log("writing badge", fileName);
try {
fs.writeFileSync(fileName, svgStr);
writeBadge(fileName, svgStr);
} catch (err) {
console.error("Error writing badge", fileName, err.toString());
}
Expand Down
192 changes: 192 additions & 0 deletions src/badge.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { badges } from "./badge";
import path from "path";

const someLcov = [
{
file: "/files/project/src/foo.js",
lines: {
found: 23,
hit: 21,
details: [
{
line: 20,
hit: 3,
},
{
line: 21,
hit: 3,
},
{
line: 22,
hit: 3,
},
],
},
functions: {
hit: 2,
found: 3,
details: [
{
name: "foo",
line: 19,
},
{
name: "bar",
line: 33,
},
{
name: "baz",
line: 54,
},
],
},
branches: {
hit: 3,
found: 3,
details: [
{
line: 21,
block: 0,
branch: 0,
taken: 1,
},
{
line: 21,
block: 0,
branch: 1,
taken: 2,
},
{
line: 37,
block: 1,
branch: 0,
taken: 0,
},
],
},
},
{
file: "/files/project/src/bar/baz.js",
lines: {
found: 10,
hit: 5,
details: [
{
line: 20,
hit: 0,
},
{
line: 21,
hit: 0,
},
{
line: 22,
hit: 3,
},
],
},
functions: {
hit: 2,
found: 3,
details: [
{
name: "foo",
line: 19,
},
{
name: "bar",
line: 33,
},
{
name: "baz",
line: 54,
},
],
},
},
];
const lcovArray = [
{
packageName: "SOME_PACKAGE",
lcov: someLcov,
},
{
packageName: "SOME_PACKAGE2",
lcov: someLcov,
},
{
packageName: "SOME_PACKAGE3",
lcov: someLcov,
},
];
const SOME_PATH = "SOME_PATH/";
describe("badges", function () {
test("should render badges rootLcov", () => {
const mkDir = jest.fn();
const writeBadge = jest.fn();
badges({
rootLcov: someLcov,
lcovArray: undefined,
options: { badgePath: SOME_PATH },
mkDir,
writeBadge,
});
expect(mkDir).toBeCalledWith(path.resolve(SOME_PATH));
expect(writeBadge).toBeCalledWith(
expect.stringContaining("root_package.svg"),
expect.stringContaining("<svg"),
);
});
test("should render badges lcovArray", () => {
const mkDir = jest.fn();
const writeBadge = jest.fn();
badges({
rootLcov: undefined,
lcovArray,
options: { badgePath: SOME_PATH },
mkDir,
writeBadge,
});
expect(mkDir).toBeCalledWith(path.resolve(SOME_PATH));
for (let i = 0; i < lcovArray.length; i++) {
expect(writeBadge).toHaveBeenNthCalledWith(
i + 1,
expect.stringContaining(`${lcovArray[i].packageName}.svg`),
expect.stringContaining("<svg"),
);
}
});
test("should do nothing with no data", () => {
const mkDir = jest.fn();
const writeBadge = jest.fn();
badges({
rootLcov: undefined,
lcovArray: undefined,
options: { badgePath: SOME_PATH },
mkDir,
writeBadge,
});
expect(mkDir).not.toBeCalled();
expect(writeBadge).not.toBeCalled();
});
test("should catch errors when writting", () => {
const mkDir = jest.fn();
const writeBadge = () => {
throw new Error();
};
expect(() =>
badges({
rootLcov: undefined,
lcovArray,
options: {
badgePath: SOME_PATH,
label: "other",
style: "flat",
},
mkDir,
writeBadge,
}),
).not.toThrowError();
expect(mkDir).toBeCalledWith(path.resolve(SOME_PATH));
});
});
45 changes: 41 additions & 4 deletions src/check.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,56 @@
import { percentage } from "./lcov";

export const checkCoverage = (minCoverage, toCheck) => {
const checkCoverage = (toCheck) => {
let accum = 0;
for (const lcovObj of toCheck) {
const coverage = percentage(lcovObj.lcov);
const isValidBuild = coverage >= minCoverage;
const isValidBuild = coverage >= lcovObj.minCoverage;
if (!isValidBuild) {
return { isValidBuild, coverage, name: lcovObj.packageName };
}
accum += coverage;
}

return {
isValidBuild: true,
coverage: toCheck.length === 0 ? 0 : accum / toCheck.length,
coverage: accum / toCheck.length,
name: "average",
};
};

export const checks = ({ rootLcov, lcovArray, options, setFailed, info }) => {
const minCoverage = options.minCoverage || 100;
const excludedFiles = (options.excluded || "")
.split(" ")
.map((x) => x.trim())
.filter((x) => x.length > 0);
const toCheck = [];
if (lcovArray) {
lcovArray
.filter((x) => !excludedFiles.some((y) => x.packageName === y))
.forEach((x) => toCheck.push({ minCoverage, ...x }));
}
if (rootLcov && !options.excludeRoot) {
toCheck.unshift({
packageName: "root_package",
lcov: rootLcov,
minCoverage,
});
}
if (toCheck.length === 0) {
return;
}
const { isValidBuild, coverage, name } = checkCoverage(toCheck);
if (!isValidBuild) {
setFailed(
`${coverage.toFixed(
2,
)}% for ${name} is less than min_coverage ${minCoverage}.`,
);
} else {
info(
`Coverage: ${coverage.toFixed(
2,
)}% is greater than or equal to min_coverage ${minCoverage}.`,
);
}
};
Loading

0 comments on commit bccce9e

Please sign in to comment.