Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
68 lines
2.3 KiB
JavaScript
68 lines
2.3 KiB
JavaScript
// Tests for reinject-invariants.mjs, a PostCompact hook that re-injects the
|
|
// load-bearing harness invariants via hookSpecificOutput.additionalContext.
|
|
// It must always exit 0 (fail-open), emit parseable JSON, and stay compact.
|
|
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { spawnSync } from "node:child_process";
|
|
import { describe, test, expect } from "vitest";
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
const HOOK = join(HERE, "..", "reinject-invariants.mjs");
|
|
|
|
const runHook = (payload) =>
|
|
spawnSync("node", [HOOK], {
|
|
input: typeof payload === "string" ? payload : JSON.stringify(payload),
|
|
encoding: "utf8",
|
|
});
|
|
|
|
const parse = (r) => JSON.parse(r.stdout);
|
|
|
|
describe("reinject-invariants hook", () => {
|
|
test("emits additionalContext on a PostCompact payload", () => {
|
|
const r = runHook({
|
|
hook_event_name: "PostCompact",
|
|
trigger: "auto",
|
|
compact_summary: "previous work summary",
|
|
});
|
|
expect(r.status).toBe(0);
|
|
const out = parse(r);
|
|
expect(out.hookSpecificOutput.hookEventName).toBe("PostCompact");
|
|
expect(out.hookSpecificOutput.additionalContext).toMatch(
|
|
/harness-invariants/,
|
|
);
|
|
});
|
|
|
|
test("injected block covers the load-bearing invariants", () => {
|
|
const out = parse(
|
|
runHook({ hook_event_name: "PostCompact", trigger: "manual" }),
|
|
);
|
|
const ctx = out.hookSpecificOutput.additionalContext;
|
|
expect(ctx).toMatch(/Worktree scope/);
|
|
expect(ctx).toMatch(/Launched is NOT done/);
|
|
expect(ctx).toMatch(/orchestrator runs/i);
|
|
expect(ctx).toMatch(/Git rights/);
|
|
});
|
|
|
|
test("injected block stays under 25 lines", () => {
|
|
const out = parse(
|
|
runHook({ hook_event_name: "PostCompact", trigger: "auto" }),
|
|
);
|
|
const lines = out.hookSpecificOutput.additionalContext.split("\n").length;
|
|
expect(lines).toBeLessThanOrEqual(25);
|
|
});
|
|
|
|
test("fails open on an unparseable payload (still exit 0, still emits)", () => {
|
|
const r = runHook("not json at all");
|
|
expect(r.status).toBe(0);
|
|
expect(parse(r).hookSpecificOutput.additionalContext).toMatch(
|
|
/harness-invariants/,
|
|
);
|
|
});
|
|
|
|
test("fails open on empty stdin", () => {
|
|
const r = spawnSync("node", [HOOK], { input: "", encoding: "utf8" });
|
|
expect(r.status).toBe(0);
|
|
});
|
|
});
|