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 11, 2023
1 parent 0a2dcdf commit 9d3a7b4
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 233 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.

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

const badge = (option, pct) => {
export const badge = (option, pct) => {
const { label = "coverage", style = "classic" } = option || {};
const colorData = {
"49c31a": [100],
Expand All @@ -27,23 +24,3 @@ const badge = (option, pct) => {
};
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");
}
for (const lcovObj of toCheck) {
const coverage = percentage(lcovObj.lcov);
const svgStr = badge(options, coverage.toFixed(2));
const fileName = path.join(dirName, `${lcovObj.packageName}.svg`);
console.log("writing badge", fileName);
try {
fs.writeFileSync(fileName, svgStr);
} catch (err) {
console.error("Error writing badge", fileName, err.toString());
}
}
};
86 changes: 33 additions & 53 deletions src/cli.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,44 @@
import process from "process";
import fs from "fs";
import path from "path";
import { diff, diffForMonorepo } from "./comment";
import { getLcovArray, readLcov } from "./monorepo";
import { checkCoverage } from "./check";
import { createBadges } from "./badge";
import { codeCoverageAssistant } from "./codeCoverageAssistant";

const addPackageName = (x) => ({
...x,
...{ packageName: x.dir.split("/").slice(-2)[0] },
});
const main = async () => {
const file = process.argv[2];
const beforeFile = process.argv[3];

const prefix = `${path.dirname(path.dirname(path.resolve(file)))}/`;
const options = {
repository: "example/foo",
commit: "f9d42291812ed03bb197e48050ac38ac6befe4e5",
prefix,
head: "feat/test",
base: "master",
maxLines: "10",
const baseClient = {
upsert: (title, body) => {
console.log("--> COMMENT", "title:", title, "body:", body);
},
mkDir: (dirName) => console.log("Creating directory", dirName),
writeBadge: (fileName) => console.log("written", fileName),
getPackageName: (x) => x.split("/").slice(-2)[0],
setFailed: (...x) => console.error("ERROR", ...x),
info: (...x) => console.log("INFO:", ...x),
options: {
repository: "example/foo",
commit: "f9d42291812ed03bb197e48050ac38ac6befe4e5",
prefix,
head: "feat/test",
base: "master",
maxLines: 100,
badgePath: "./badges",
appName: "someAppName",
minCoverage: 80,
multipleComment: true,
},
};

if (fs.statSync(file).isDirectory()) {
const lcovArrayForMonorepo = (
await getLcovArray(file, "lcov.info")
).map(addPackageName);
console.log(
diffForMonorepo(
lcovArrayForMonorepo,
await getLcovArray(file, "lcov-base"),
options,
),
);
createBadges("./badges", lcovArrayForMonorepo, {});
console.log(checkCoverage(90, lcovArrayForMonorepo));
} else {
const lcov = await readLcov(file);
console.log(
diff(lcov, beforeFile && (await readLcov(beforeFile)), options),
);
createBadges(
"./build",
{
packageName: "root",
lcov,
},
{},
);
console.log(
checkCoverage(90, [
{
packageName: "root",
lcov,
},
]),
);
}
await codeCoverageAssistant({
...(fs.statSync(file).isDirectory()
? {
monorepoBasePath: file,
}
: {
lcovFile: file,
baseFile: "lcov-base",
}),
...baseClient,
});
};

main().catch((err) => {
Expand Down
175 changes: 175 additions & 0 deletions src/codeCoverageAssistant.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { renderCommentArray, renderCommentLine } from "./comment";
import { getLcovArray, readLcov } from "./monorepo";
import { checkCoverage } from "./check";
import { badge } from "./badge";
import path from "path";
import { percentage } from "./lcov";

async function comments(
rootLcov,
baseFile,
monorepoBasePath,
lcovArrayForMonorepo,
options,
addPackageName,
upsert,
) {
// Comments
if (lcovArrayForMonorepo.length > 0) {
const lcovBaseArrayForMonorepo = (
await getLcovArray(monorepoBasePath, "lcov-base")
).map(addPackageName);
if (options.multipleComment) {
for (const lcovObj of lcovArrayForMonorepo) {
const baseLcov = lcovBaseArrayForMonorepo.find(
(el) => el.packageName === lcovObj.packageName,
);
const body = renderCommentLine(
lcovObj.lcov,
baseLcov && baseLcov.lcov,
lcovObj.packageName,
options,
);
await upsert(`m-${lcovObj.packageName}`, body);
}
} else {
const body = renderCommentArray(
lcovArrayForMonorepo,
lcovBaseArrayForMonorepo,
options,
);
await upsert("single-comment", body);
}
}
if (rootLcov) {
const body = renderCommentLine(
rootLcov,
baseFile && (await readLcov(baseFile)),
"root",
options,
);
await upsert(`root-comment`, body);
}
}

async function badges(
rootLcov,
lcovArrayForMonorepo,
options,
mkDir,
writeBadge,
) {
const badgeOptions = {
label: options.badgeLabel,
style: options.badgeStyle,
};
const toBadge = lcovArrayForMonorepo;
if (rootLcov) {
toBadge.push({
packageName: "root_package",
lcov: rootLcov,
});
}
const dirName = path.resolve(options.badgePath);
mkDir(dirName);
for (const lcovObj of toBadge) {
const coverage = percentage(lcovObj.lcov);
const svgStr = badge(badgeOptions, coverage.toFixed(2));
const fileName = path.join(dirName, `${lcovObj.packageName}.svg`);
console.log("writing badge", fileName);
try {
writeBadge(fileName, svgStr);
} catch (err) {
console.error("Error writing badge", fileName, err.toString());
}
}
}

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

export const codeCoverageAssistant = async ({
monorepoBasePath,
lcovFile,
baseFile,
options,
upsert,
mkDir,
writeBadge,
getPackageName,
setFailed,
info,
}) => {
const addPackageName = (x) => ({
...x,
...{ packageName: getPackageName(x.dir) },
});
const lcovArrayForMonorepo = (
monorepoBasePath
? await getLcovArray(monorepoBasePath, "lcov.info")
: []
).map(addPackageName);
// Always process root file if exists.
const rootLcov = lcovFile && (await readLcov(lcovFile));
if (options.maxLines > 0) {
await comments(
rootLcov,
baseFile,
monorepoBasePath,
lcovArrayForMonorepo,
options,
addPackageName,
upsert,
);
}
if (options.badgePath) {
await badges(
rootLcov,
lcovArrayForMonorepo,
options,
mkDir,
writeBadge,
);
}
if (options.minCoverage) {
await checks(rootLcov, lcovArrayForMonorepo, options, setFailed, info);
}
};
39 changes: 10 additions & 29 deletions src/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const comparer = (otherArray) => (current) =>
).length === 0;

const renderLcov = (lcov, base, appTitle, options) => {
const maxLines = options.maxLines || 15;
const pbefore = base ? percentage(base) : 0;
const pafter = base ? percentage(lcov) : 0;
const pdiff = pafter - pbefore;
Expand Down Expand Up @@ -71,7 +70,7 @@ const renderLcov = (lcov, base, appTitle, options) => {
}
return [
table(tbody(tr(...row))),
report.length > maxLines
report.length > options.maxLines
? p("Coverage Report too long to display")
: details(summary("Coverage Report"), tabulate(report, options)),
"<br/>",
Expand All @@ -81,10 +80,10 @@ const renderLcov = (lcov, base, appTitle, options) => {
/**
* Github comment for monorepo
* @param {Array<{packageName, lcovPath}>} lcovArrayForMonorepo
* @param {{Array<{packageName, lcovBasePath}>}} lcovBaseArrayForMonorepo
* @param {Array<{packageName, lcovPath}>} lcovBaseArrayForMonorepo
* @param {*} options
*/
const commentForMonorepo = (
export const renderCommentArray = (
lcovArrayForMonorepo,
lcovBaseArrayForMonorepo,
options,
Expand All @@ -110,32 +109,14 @@ const commentForMonorepo = (

/**
* Github comment for single repo
* @param {raw lcov} lcov
* @param {raw} lcov
* @param {raw} baseLcov
* @param {string} appTitle
* @param {*} options
*/
const comment = (lcov, before, options) => {
const { appName, base } = options;
export const renderCommentLine = (lcov, baseLcov, appTitle, options) => {
const inner = renderLcov(lcov, baseLcov, appTitle, options);
const { base } = options;
const title = `Coverage after merging into ${b(base)} <p></p>`;
return fragment(title, renderLcov(lcov, before, appName, options));
return fragment(title, inner);
};

/**
* Diff in coverage percentage for single repo
* @param {raw lcov} lcov
* @param {raw base lcov} before
* @param {*} options
*/
export const diff = (lcov, before, options) => comment(lcov, before, options);

/**
* Diff in coverage percentage for monorepo
* @param {Array<{packageName, lcovPath}>} lcovArrayForMonorepo
* @param {{Array<{packageName, lcovBasePath}>}} lcovBaseArrayForMonorepo
* @param {*} options
*/
export const diffForMonorepo = (
lcovArrayForMonorepo,
lcovBaseArrayForMonorepo,
options,
) =>
commentForMonorepo(lcovArrayForMonorepo, lcovBaseArrayForMonorepo, options);
Loading

0 comments on commit 9d3a7b4

Please sign in to comment.