syntaxai/tdd.md · main · src / b32_sama_cli_install.test.ts
import { describe, test, expect } from "bun:test";
import { buildSamaCliInstallScript } from "./b32_sama_cli_install.ts";
describe("buildSamaCliInstallScript", () => {
test("shebang + set -eu in the header", () => {
const out = buildSamaCliInstallScript([]);
expect(out.startsWith("#!/usr/bin/env bash\n")).toBe(true);
expect(out).toContain("set -eu");
});
test("embeds each file inside a single-quoted heredoc", () => {
const out = buildSamaCliInstallScript([
{ path: "sama", content: "echo hi\n", executable: true },
]);
expect(out).toContain("cat > \"$INSTALL_DIR/sama\" <<'__SAMACLI_INSTALL_EOF__'");
expect(out).toContain("echo hi");
expect(out).toContain("__SAMACLI_INSTALL_EOF__\n");
expect(out).toContain('chmod +x "$INSTALL_DIR/sama"');
});
test("non-executable file omits chmod +x", () => {
const out = buildSamaCliInstallScript([
{ path: "README.md", content: "# hi\n" },
]);
expect(out).toContain('cat > "$INSTALL_DIR/README.md"');
expect(out).not.toContain('chmod +x "$INSTALL_DIR/README.md"');
});
test("emits mkdir -p for nested paths", () => {
const out = buildSamaCliInstallScript([
{ path: "src/a31_constants.sh", content: "X=1\n" },
]);
expect(out).toContain('mkdir -p "$INSTALL_DIR/$(dirname "src/a31_constants.sh")"');
});
test("symlinks sama into $BIN_LINK", () => {
const out = buildSamaCliInstallScript([]);
expect(out).toContain('ln -sf "$INSTALL_DIR/sama" "$BIN_LINK"');
});
test("refuses to embed a file containing the heredoc marker", () => {
expect(() =>
buildSamaCliInstallScript([
{ path: "evil.sh", content: "innocent\n__SAMACLI_INSTALL_EOF__\noops\n" },
]),
).toThrow(/heredoc marker/);
});
test("refuses path escapes", () => {
expect(() =>
buildSamaCliInstallScript([{ path: "../evil.sh", content: "x\n" }]),
).toThrow(/path escape/);
expect(() =>
buildSamaCliInstallScript([{ path: "/etc/passwd", content: "x\n" }]),
).toThrow(/path escape/);
});
test("missing trailing newline still terminates heredoc cleanly", () => {
// Content without trailing newline → emitter must add one so
// the closing marker is recognized.
const out = buildSamaCliInstallScript([
{ path: "no-nl", content: "line1\nline2" },
]);
// The marker must land on its own line, preceded by the content + \n.
expect(out).toMatch(/line2\n__SAMACLI_INSTALL_EOF__/);
});
test("repo + spec URLs default to tdd.md", () => {
const out = buildSamaCliInstallScript([]);
expect(out).toContain("https://tdd.md/GIT/tdd.md/tree/main/tools/sama-cli");
expect(out).toContain("https://tdd.md/sama/v2");
});
test("custom URLs override defaults", () => {
const out = buildSamaCliInstallScript([], {
repoUrl: "https://example.org/repo",
specUrl: "https://example.org/spec",
});
expect(out).toContain("https://example.org/repo");
expect(out).toContain("https://example.org/spec");
});
test("end-to-end: produces a bash script that, when executed, writes the file content verbatim", async () => {
// Run the emitted script in a temp dir, then read what it wrote.
const dir = await Bun.file(`/tmp/sama-cli-install-test-${Date.now()}`).name;
const out = buildSamaCliInstallScript([
{ path: "src/a31.sh", content: "X=1\nY=2\n" },
{ path: "sama", content: "#!/bin/sh\necho hi\n", executable: true },
]);
const proc = Bun.spawnSync({
cmd: ["bash", "-c", out],
env: {
...process.env,
SAMA_CLI_INSTALL_DIR: dir,
SAMA_CLI_BIN_LINK: `${dir}-bin/sama`,
},
});
expect(proc.exitCode).toBe(0);
const wrote = await Bun.file(`${dir}/src/a31.sh`).text();
expect(wrote).toBe("X=1\nY=2\n");
const samaContent = await Bun.file(`${dir}/sama`).text();
expect(samaContent).toBe("#!/bin/sh\necho hi\n");
// Cleanup
Bun.spawnSync({ cmd: ["rm", "-rf", dir, `${dir}-bin`] });
});
});