Files
2026-05-27 23:29:53 +01:00

66 lines
2.3 KiB
TypeScript

import { readdirSync, readFileSync, statSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "@suaveplan/testing/runner";
import { registerRateLimitServiceSlot } from "../src/services/registry-augmentation.js";
const here = dirname(fileURLToPath(import.meta.url));
const pkgRoot = join(here, "..");
const pkg = JSON.parse(readFileSync(join(pkgRoot, "package.json"), "utf8"));
describe("dep-graph", () => {
it("ships ten subpath exports including the root", {
timeout: 5000,
}, () => {
const exportKeys = Object.keys(pkg.exports).filter(
(k: string) => k !== "./package.json"
);
expect(exportKeys.length).toBeGreaterThanOrEqual(10);
});
it("declares the canonical runtime deps", { timeout: 5000 }, () => {
const deps = pkg.dependencies as Record<string, string>;
expect(deps["@suaveplan/api-plugin"]).toBe("workspace:^");
expect(deps["@suaveplan/rate-limiter"]).toBe("workspace:^");
expect(deps["@suaveplan/error"]).toBe("workspace:^");
expect(deps["@suaveplan/types"]).toBe("workspace:^");
expect(deps.hono).toBe("catalog:");
expect(deps.zod).toBe("catalog:forms");
});
function walk(dir: string, out: string[] = []): string[] {
for (const entry of readdirSync(dir)) {
const p = join(dir, entry);
if (statSync(p).isDirectory()) walk(p, out);
else if (
entry.endsWith(".ts") &&
!entry.endsWith(".test.ts") &&
!entry.endsWith(".types.ts") &&
entry !== "index.ts"
)
out.push(p);
}
return out;
}
it("registerRateLimitServiceSlot is callable without throwing", {
timeout: 5000,
}, () => {
expect(() => registerRateLimitServiceSlot()).not.toThrow();
});
it("every implementation .ts has a sibling .md", { timeout: 5000 }, () => {
const sources = walk(join(pkgRoot, "src"));
const missing: string[] = [];
for (const ts of sources) {
const md = ts.replace(/\.ts$/, ".md");
try {
statSync(md);
} catch {
missing.push(md);
}
}
expect(missing).toEqual([]);
});
});