59 lines
1.7 KiB
JavaScript
59 lines
1.7 KiB
JavaScript
/**
|
||
* Coverage gate for CI.
|
||
*
|
||
* Reads coverage-summary.json (Vitest --coverage output) and fails
|
||
* if overall line coverage drops below the configured threshold.
|
||
*
|
||
* Usage:
|
||
* pnpm test:coverage
|
||
* node scripts/ci/check-coverage-delta.mjs
|
||
*
|
||
* Environment variable overrides:
|
||
* COVERAGE_THRESHOLD – minimum line coverage % (default: 65)
|
||
* COVERAGE_FILE – path to coverage-summary.json
|
||
*/
|
||
|
||
import { readFileSync } from "node:fs";
|
||
|
||
const THRESHOLD = Number(process.env.COVERAGE_THRESHOLD ?? 65);
|
||
const COVERAGE_FILE =
|
||
process.env.COVERAGE_FILE ?? "coverage/coverage-summary.json";
|
||
|
||
let summary;
|
||
try {
|
||
summary = JSON.parse(readFileSync(COVERAGE_FILE, "utf8"));
|
||
} catch (err) {
|
||
console.error(`Could not read ${COVERAGE_FILE}: ${err.message}`);
|
||
console.error("Run `pnpm test:coverage` first.");
|
||
process.exit(1);
|
||
}
|
||
|
||
const total = summary.total;
|
||
if (!total) {
|
||
console.error(`No "total" key in ${COVERAGE_FILE}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
const linePct = total.lines?.pct ?? 0;
|
||
const branchPct = total.branches?.pct ?? 0;
|
||
const fnPct = total.functions?.pct ?? 0;
|
||
const stmtPct = total.statements?.pct ?? 0;
|
||
|
||
console.log("\n--- Coverage Report ---\n");
|
||
console.log(` Lines: ${linePct.toFixed(2)}%`);
|
||
console.log(` Branches: ${branchPct.toFixed(2)}%`);
|
||
console.log(` Functions: ${fnPct.toFixed(2)}%`);
|
||
console.log(` Statements: ${stmtPct.toFixed(2)}%`);
|
||
console.log(`\n Threshold: ${THRESHOLD}% (lines)\n`);
|
||
|
||
if (linePct < THRESHOLD) {
|
||
console.error(
|
||
`FAILED: Line coverage ${linePct.toFixed(2)}% is below the ${THRESHOLD}% threshold`
|
||
);
|
||
process.exit(1);
|
||
} else {
|
||
console.log(
|
||
`PASSED: Line coverage ${linePct.toFixed(2)}% meets the ${THRESHOLD}% threshold`
|
||
);
|
||
}
|