Files
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

170 lines
5.5 KiB
JavaScript

/**
* Coverage audit — cross-references the Hono router (apps/api/src/_router.generated.ts)
* against e2e tests living at cloud/packages/tests/e2e/.
*
* Run from repo root or anywhere — paths are resolved relative to this file.
* Output: writes COVERAGE.md next to itself.
*
* node apps/api/test/_audit-coverage.mjs
*/
import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const API_ROOT = resolve(__dirname, "..");
const CLOUD_ROOT = resolve(API_ROOT, "..", "..");
const ROUTER = join(API_ROOT, "src", "_router.generated.ts");
const E2E_ROOTS = [
join(CLOUD_ROOT, "packages", "tests", "e2e"),
join(API_ROOT, "test", "e2e"),
];
const OUTPUT = join(__dirname, "COVERAGE.md");
const routerSrc = readFileSync(ROUTER, "utf8");
const routes = [];
for (const m of routerSrc.matchAll(/app\.route\(\s*"([^"]+)"/g))
routes.push(m[1]);
function walk(dir) {
const out = [];
for (const e of readdirSync(dir)) {
const p = join(dir, e);
const s = statSync(p);
if (s.isDirectory()) out.push(...walk(p));
else if (e.endsWith(".test.ts")) out.push(p);
}
return out;
}
const testFiles = E2E_ROOTS.filter((root) => {
try {
return statSync(root).isDirectory();
} catch {
return false;
}
}).flatMap(walk);
const tests = testFiles.map((p) => ({
path: p,
text: readFileSync(p, "utf8"),
}));
function honoToRegex(route) {
const source = route
.split("/")
.map((segment, index) => {
if (index === 0) return "";
if (segment.startsWith(":") && segment.includes("{.+}")) return ".+";
if (segment.startsWith(":")) return "[^/?#]+";
return segment.replace(/[.+^${}()|[\]\\]/g, "\\$&");
})
.join("/");
return new RegExp(`^${source}(/[^"]*)?(\\?[^"]*)?$`);
}
/**
* Static prefix of a route — everything up to (but not including) the first
* `:param` segment. Used as a loose match so template literals like
* `\`/api/mcps/${provider}/mcp\`` count toward coverage.
*
* /api/mcps/airtable/:transport → /api/mcps/airtable/
* /api/v1/agents/:agentId/logs → /api/v1/agents/
* /api/health → /api/health
*/
function staticPrefix(route) {
const colonIdx = route.indexOf("/:");
if (colonIdx === -1) return route;
return route.slice(0, colonIdx + 1);
}
function localPath(p) {
return (
p.split("/apps/api/test/e2e/")[1] ?? p.split("/packages/tests/e2e/")[1] ?? p
);
}
const covered = [];
const uncovered = [];
for (const route of routes) {
const re = honoToRegex(route);
const prefix = staticPrefix(route);
const isPrefixUseful = prefix.length > "/api/".length + 1;
const hits = new Set();
for (const t of tests) {
let matched = false;
for (const m of t.text.matchAll(/"(\/api\/[^"]+)"/g)) {
if (re.test(m[1])) {
hits.add(localPath(t.path));
matched = true;
break;
}
}
// Fallback: route's static prefix appears anywhere (template literals,
// dynamic URL builders). Skip too-generic prefixes like `/api/`.
if (!matched && isPrefixUseful && t.text.includes(prefix)) {
hits.add(localPath(t.path));
matched = true;
}
// Loop-coverage fallback: tests that iterate over a provider/segment list
// — e.g. `for (const provider of [...]) ` /api/mcps/${provider}/${tr}` `.
// Recognize coverage when the parent prefix appears AND the route's first
// `:`-bearing segment value (the literal between the last static segment
// and `:`) is referenced as a quoted token.
if (!matched) {
const firstColonAt = route.indexOf("/:");
if (firstColonAt !== -1) {
const before = route.slice(0, firstColonAt);
const lastSlash = before.lastIndexOf("/");
const parent = before.slice(0, lastSlash + 1);
const segment = before.slice(lastSlash + 1);
if (
parent.length > "/api/".length + 1 &&
segment.length > 0 &&
t.text.includes(parent) &&
new RegExp(`["'\`]${segment}["'\`]`).test(t.text)
) {
hits.add(localPath(t.path));
}
}
}
}
if (hits.size > 0) covered.push({ route, files: [...hits] });
else uncovered.push(route);
}
const lines = [];
lines.push("# Hono Worker Route Coverage Audit");
lines.push("");
lines.push(
"Auto-generated. Re-run with `node apps/api/test/_audit-coverage.mjs`.",
);
lines.push("");
lines.push(`- Mounted routes: **${routes.length}**`);
lines.push(
`- Covered (path appears in at least one Next-targeted e2e test): **${covered.length}**`,
);
lines.push(`- Uncovered: **${uncovered.length}**`);
lines.push("");
lines.push(
'> Note: "covered" here means the path appears in a test file under ' +
"`cloud/packages/tests/e2e/`. Those tests target the legacy Next.js app, not " +
"the Hono Worker built from `apps/api/`. Even covered routes need a Worker-" +
"targeted run to confirm the migrated implementation works end-to-end.",
);
lines.push("");
lines.push(`## Uncovered (${uncovered.length})`);
lines.push("");
for (const r of uncovered) lines.push(`- \`${r}\``);
lines.push("");
lines.push(`## Covered (${covered.length})`);
lines.push("");
for (const c of covered) lines.push(`- \`${c.route}\` — ${c.files.join(", ")}`);
lines.push("");
writeFileSync(OUTPUT, lines.join("\n"));
console.log(
`Mounted: ${routes.length}, Covered: ${covered.length}, Uncovered: ${uncovered.length}`,
);
console.log(`Wrote ${OUTPUT}`);