Track HiveGrid Cloud planning reference
This commit is contained in:
1 parent
b3d5ea6764
commit
e341c5938a
5784 files changed
+1104929
-3
No files matched your search
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env node
|
||||
// Anti-regression gate: asserts a minimum test-file-per-source-file density
|
||||
// per workspace. Catches "route added without test" without requiring full
|
||||
// coverage tooling. Floors are deliberate snapshots of the current ratio;
|
||||
// they must only go down via deliberate commits (= more tests added).
|
||||
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const repoRoot = path.resolve(fileURLToPath(import.meta.url), "..", "..");
|
||||
|
||||
const TARGETS = [
|
||||
{ name: "apps/api", root: "apps/api/src", minRatio: 0.18 },
|
||||
{ name: "apps/worker", root: "apps/worker/src", minRatio: 0.18 },
|
||||
{ name: "apps/web app routes", root: "apps/web/app/routes", minRatio: 0.05 },
|
||||
{ name: "apps/web app modules", root: "apps/web/app/modules", minRatio: 0.04 },
|
||||
{ name: "apps/web app utils", root: "apps/web/app/utils", minRatio: 0.10 },
|
||||
{ name: "packages/foundation", root: "packages/foundation/src", minRatio: 0.10 },
|
||||
{ name: "packages/db", root: "packages/db/src", minRatio: 0.05 },
|
||||
{ name: "packages/mail", root: "packages/mail/src", minRatio: 0.30 },
|
||||
{ name: "packages/queue", root: "packages/queue/src", minRatio: 0.10 },
|
||||
{ name: "packages/i18n", root: "packages/i18n/src", minRatio: 0.30 },
|
||||
{ name: "packages/brand", root: "packages/brand/src", minRatio: 0.50 },
|
||||
{ name: "packages/config", root: "packages/config/src", minRatio: 0.50 },
|
||||
];
|
||||
|
||||
const ignoredDirs = new Set(["node_modules", "dist", "build", "coverage", ".react-router", "generated", "__generated__"]);
|
||||
const sourcePattern = /\.(?:ts|tsx)$/;
|
||||
const testPattern = /\.(?:test|spec)\.(?:ts|tsx)$/;
|
||||
const declarationPattern = /\.d\.ts$/;
|
||||
|
||||
export function walk(dir, acc = { source: 0, test: 0 }) {
|
||||
if (!fs.existsSync(dir)) return acc;
|
||||
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
if (ignoredDirs.has(entry.name) || entry.name.startsWith(".")) continue;
|
||||
const full = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
walk(full, acc);
|
||||
continue;
|
||||
}
|
||||
if (!entry.isFile()) continue;
|
||||
if (declarationPattern.test(entry.name)) continue;
|
||||
if (testPattern.test(entry.name)) {
|
||||
acc.test += 1;
|
||||
} else if (sourcePattern.test(entry.name)) {
|
||||
acc.source += 1;
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
export function evaluateTargets(targets, rootDir = repoRoot) {
|
||||
const failures = [];
|
||||
const passes = [];
|
||||
|
||||
for (const target of targets) {
|
||||
const counts = walk(path.join(rootDir, target.root));
|
||||
if (counts.source === 0) {
|
||||
passes.push(`SKIP ${target.name} no source files`);
|
||||
continue;
|
||||
}
|
||||
const ratio = counts.test / counts.source;
|
||||
const line = `${target.name} source=${counts.source} tests=${counts.test} ratio=${ratio.toFixed(3)} min=${target.minRatio.toFixed(3)}`;
|
||||
if (ratio >= target.minRatio) {
|
||||
passes.push(`PASS ${line}`);
|
||||
} else {
|
||||
failures.push(`FAIL ${line} (drift=${(ratio - target.minRatio).toFixed(3)})`);
|
||||
}
|
||||
}
|
||||
|
||||
return { failures, passes };
|
||||
}
|
||||
|
||||
export function formatSummary(result) {
|
||||
return `Summary: ${result.passes.length} passed, 0 observed, ${result.failures.length} failed`;
|
||||
}
|
||||
|
||||
function main() {
|
||||
const result = evaluateTargets(TARGETS);
|
||||
|
||||
for (const line of result.passes) console.log(line);
|
||||
for (const line of result.failures) console.error(line);
|
||||
console.log(formatSummary(result));
|
||||
|
||||
if (result.failures.length > 0) process.exit(1);
|
||||
}
|
||||
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
main();
|
||||
}
|
||||
Reference in new issue
Block a user