Files
OmniRoute/scripts/check/test-report-summary.mjs
diegosouzapw f3b944a55a refactor(scripts): organize into build/dev/check/docs/i18n/ad-hoc subfolders
Reorganizes the 29 active scripts under scripts/ into purpose-driven
subfolders:

- scripts/build/    (11) — Build, install, publish, runtime env
- scripts/dev/      (13) — Dev servers, test runners, healthchecks
- scripts/check/    (10) — Lint/validation/coverage checks
- scripts/docs/      (2) — Docs index and provider reference generation
- scripts/i18n/     (+3) — Adds Python translation utilities (check/validate/autotranslate)
- scripts/ad-hoc/    (4) — One-shot maintenance utilities

Updates all references in package.json, electron/package.json,
.husky/pre-commit, .github/workflows/ci.yml, Dockerfile, src/,
tests/, scripts/ internal cross-imports, playwright.config.ts,
and English docs (CODEBASE_DOCUMENTATION, ENVIRONMENT, FEATURES,
RELEASE_CHECKLIST, COVERAGE_PLAN, ELECTRON_GUIDE, I18N, GEMINI).

Also patches scripts/build/pack-artifact-policy.ts so the npm pack
allowlist mirrors the new layout.

Validates with:
- npm run lint            (exit 0 — pre-existing minified-bundle errors only)
- npm run typecheck:core  (exit 0)
- npm run check:docs-all  (exit 0)
- unit tests for moved scripts (57 tests pass)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:14:25 -03:00

93 lines
2.9 KiB
JavaScript

import { existsSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
function getArg(name, fallbackValue = "") {
const index = process.argv.indexOf(name);
if (index === -1 || index === process.argv.length - 1) {
return fallbackValue;
}
return process.argv[index + 1];
}
function formatPercent(value) {
return `${Number(value ?? 0).toFixed(2)}%`;
}
const inputPath = getArg("--input", "coverage/coverage-summary.json");
const outputPath = getArg("--output", "");
const threshold = Number(getArg("--threshold", "60"));
if (!existsSync(inputPath)) {
console.error(`Coverage summary file not found: ${inputPath}`);
process.exit(1);
}
const summary = JSON.parse(readFileSync(inputPath, "utf8"));
const cwd = process.cwd();
const metrics = [
["lines", "Lines"],
["statements", "Statements"],
["functions", "Functions"],
["branches", "Branches"],
];
const total = summary.total ?? {};
const gatePassed = metrics.every(([metric]) => (total[metric]?.pct ?? 0) >= threshold);
const files = Object.entries(summary)
.filter(([name]) => name !== "total" && /\.(?:[cm]?[jt]sx?)$/.test(name))
.map(([name, stats]) => {
const relativeName = path.relative(cwd, name);
const totalLines = stats.lines?.total ?? 0;
const coveredLines = stats.lines?.covered ?? 0;
return {
name: relativeName,
lines: stats.lines?.pct ?? 0,
branches: stats.branches?.pct ?? 0,
functions: stats.functions?.pct ?? 0,
missingLines: Math.max(totalLines - coveredLines, 0),
};
})
.sort((left, right) => {
if (left.lines !== right.lines) return left.lines - right.lines;
if (left.branches !== right.branches) return left.branches - right.branches;
return right.missingLines - left.missingLines;
})
.slice(0, 15);
const report = [
"# Coverage Report",
"",
`Gate: ${gatePassed ? "PASS" : "FAIL"} at ${threshold}% minimum for lines, statements, functions, and branches.`,
"",
"## Totals",
"",
"| Metric | Covered | Total | Percent | Threshold | Status |",
"| --- | ---: | ---: | ---: | ---: | --- |",
...metrics.map(([metric, label]) => {
const covered = total[metric]?.covered ?? 0;
const totalCount = total[metric]?.total ?? 0;
const pct = total[metric]?.pct ?? 0;
const status = pct >= threshold ? "PASS" : "FAIL";
return `| ${label} | ${covered} | ${totalCount} | ${formatPercent(pct)} | ${threshold}% | ${status} |`;
}),
"",
"## Lowest Coverage Files",
"",
"| File | Lines | Branches | Functions | Missing Lines |",
"| --- | ---: | ---: | ---: | ---: |",
...files.map(
(entry) =>
`| \`${entry.name}\` | ${formatPercent(entry.lines)} | ${formatPercent(entry.branches)} | ${formatPercent(entry.functions)} | ${entry.missingLines} |`
),
];
const reportContent = `${report.join("\n")}\n`;
if (outputPath) {
writeFileSync(outputPath, reportContent);
} else {
process.stdout.write(reportContent);
}