Files
upstream-atomic-crm/.claude/hooks/test/provision-worktree.test.mjs
upstream-mirror 93ecc1a6f8
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
snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:48:50 +05:00

91 lines
3.0 KiB
JavaScript

// Tests for the config-driven worktree provisioning dispatcher
// (context.mjs provisionWorktree, config.worktree.provision): `npm-link`
// (builtin), `none` (no-op), or a script path. Run in a child node process with
// APP_DIR pointing at a temp repo, so paths.mjs REPO resolves to that repo's
// harness.config.json.
import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { spawnSync } from "node:child_process";
import { afterEach, describe, test, expect } from "vitest";
const HERE = dirname(fileURLToPath(import.meta.url));
const CTX_URL = pathToFileURL(join(HERE, "..", "lib", "context.mjs")).href;
const tmpDirs = [];
afterEach(() => {
while (tmpDirs.length)
rmSync(tmpDirs.pop(), { recursive: true, force: true });
});
// Run provisionWorktree(wt) in a child process whose REPO is `repo`.
const runProvision = (repo, wt) => {
const script = `
const { createHookContext } = await import(${JSON.stringify(CTX_URL)});
const ctx = createHookContext({ session_id: "prov-test" }, "prov");
ctx.provisionWorktree(process.env.WT);
console.log("PROVISION_OK");
`;
const env = { ...process.env, APP_DIR: repo, WT: wt };
delete env.CLAUDE_PROJECT_DIR;
return spawnSync("node", ["--input-type=module", "-e", script], {
env,
encoding: "utf8",
});
};
const makeRepo = (provision) => {
const repo = mkdtempSync(join(tmpdir(), "provision-repo-"));
tmpDirs.push(repo);
writeFileSync(
join(repo, "harness.config.json"),
JSON.stringify({
validation: { steps: [] },
roles: {},
worktree: { provision },
}),
);
return repo;
};
const makeWorktree = () => {
const wt = mkdtempSync(join(tmpdir(), "provision-wt-"));
tmpDirs.push(wt);
return wt;
};
describe("worktree provisioning dispatcher", () => {
test("`none` provisions nothing and does not error", () => {
const repo = makeRepo("none");
const wt = makeWorktree();
const r = runProvision(repo, wt);
expect(r.status).toBe(0);
expect(r.stdout).toContain("PROVISION_OK");
expect(existsSync(join(wt, "node_modules"))).toBe(false);
});
test("a script path is run with the worktree as its argument", () => {
const repo = makeRepo("provision.sh");
const sentinel = join(repo, ".provisioned");
// $1 is the worktree path; the script records that it ran.
writeFileSync(
join(repo, "provision.sh"),
`#!/bin/sh\necho "$1" > "${sentinel}"\n`,
);
const wt = makeWorktree();
const r = runProvision(repo, wt);
expect(r.status).toBe(0);
expect(existsSync(sentinel)).toBe(true);
});
test("default `npm-link` with no source node_modules is a safe no-op", () => {
const repo = makeRepo("npm-link"); // repo has no node_modules to mirror
const wt = makeWorktree();
const r = runProvision(repo, wt);
expect(r.status).toBe(0);
expect(existsSync(join(wt, "node_modules"))).toBe(false);
});
});