Files
gh-nathanvale-side-quest-ma…/hooks/hooks.test.ts
2025-11-30 08:42:05 +08:00

201 lines
4.9 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import type {
PreCompactHookInput,
SessionStartHookInput,
} from "@anthropic-ai/claude-agent-sdk";
// Test the hook input types and basic functionality
describe("SessionStartHookInput type", () => {
test("has correct shape", () => {
const input: SessionStartHookInput = {
session_id: "test-session-123",
transcript_path: "/tmp/transcript",
cwd: "/Users/test/code",
hook_event_name: "SessionStart",
source: "startup",
};
expect(input.session_id).toBe("test-session-123");
expect(input.cwd).toBe("/Users/test/code");
expect(input.hook_event_name).toBe("SessionStart");
expect(input.source).toBe("startup");
});
test("source can be startup, resume, clear, or compact", () => {
const sources: SessionStartHookInput["source"][] = [
"startup",
"resume",
"clear",
"compact",
];
sources.forEach((source) => {
const input: SessionStartHookInput = {
session_id: "test",
transcript_path: "/tmp",
cwd: "/tmp",
hook_event_name: "SessionStart",
source,
};
expect(input.source).toBe(source);
});
});
});
describe("PreCompactHookInput type", () => {
test("has correct shape", () => {
const input: PreCompactHookInput = {
session_id: "test-session-123",
transcript_path: "/tmp/transcript",
cwd: "/Users/test/code",
hook_event_name: "PreCompact",
trigger: "auto",
custom_instructions: null,
};
expect(input.session_id).toBe("test-session-123");
expect(input.hook_event_name).toBe("PreCompact");
expect(input.trigger).toBe("auto");
expect(input.custom_instructions).toBeNull();
});
test("trigger can be manual or auto", () => {
const triggers: PreCompactHookInput["trigger"][] = ["manual", "auto"];
triggers.forEach((trigger) => {
const input: PreCompactHookInput = {
session_id: "test",
transcript_path: "/tmp",
cwd: "/tmp",
hook_event_name: "PreCompact",
trigger,
custom_instructions: null,
};
expect(input.trigger).toBe(trigger);
});
});
test("custom_instructions can be string or null", () => {
const withInstructions: PreCompactHookInput = {
session_id: "test",
transcript_path: "/tmp",
cwd: "/tmp",
hook_event_name: "PreCompact",
trigger: "manual",
custom_instructions: "Focus on the auth changes",
};
const withoutInstructions: PreCompactHookInput = {
session_id: "test",
transcript_path: "/tmp",
cwd: "/tmp",
hook_event_name: "PreCompact",
trigger: "auto",
custom_instructions: null,
};
expect(withInstructions.custom_instructions).toBe(
"Focus on the auth changes",
);
expect(withoutInstructions.custom_instructions).toBeNull();
});
});
describe("git-context-loader", () => {
test("can be run with valid input", async () => {
const input: SessionStartHookInput = {
session_id: "test-123",
transcript_path: "/tmp/transcript",
cwd: import.meta.dir, // Use the hooks directory (which is in a git repo)
hook_event_name: "SessionStart",
source: "startup",
};
// Run the actual hook script using echo to pipe input
const proc = Bun.spawn(
[
"sh",
"-c",
`echo '${JSON.stringify(input)}' | bun run git-context-loader.ts`,
],
{
cwd: import.meta.dir,
stdout: "pipe",
stderr: "pipe",
},
);
// Wait for process to complete
const exitCode = await proc.exited;
const stdout = await new Response(proc.stdout).text();
expect(exitCode).toBe(0);
// Should output git context
expect(stdout).toContain("Git Context:");
expect(stdout).toContain("Branch:");
});
test("skips non-startup sources", async () => {
const input: SessionStartHookInput = {
session_id: "test-123",
transcript_path: "/tmp/transcript",
cwd: import.meta.dir,
hook_event_name: "SessionStart",
source: "resume", // Not startup
};
const proc = Bun.spawn(
[
"sh",
"-c",
`echo '${JSON.stringify(input)}' | bun run git-context-loader.ts`,
],
{
cwd: import.meta.dir,
stdout: "pipe",
stderr: "pipe",
},
);
const exitCode = await proc.exited;
const stdout = await new Response(proc.stdout).text();
expect(exitCode).toBe(0);
// Should NOT output git context for resume
expect(stdout).not.toContain("Git Context:");
});
});
describe("session-summary", () => {
test("can be run with valid input", async () => {
const input: PreCompactHookInput = {
session_id: "test-123",
transcript_path: "/tmp/transcript",
cwd: import.meta.dir,
hook_event_name: "PreCompact",
trigger: "manual",
custom_instructions: null,
};
const proc = Bun.spawn(
[
"sh",
"-c",
`echo '${JSON.stringify(input)}' | bun run session-summary.ts`,
],
{
cwd: import.meta.dir,
stdout: "pipe",
stderr: "pipe",
},
);
const exitCode = await proc.exited;
const stdout = await new Response(proc.stdout).text();
expect(exitCode).toBe(0);
expect(stdout).toContain("Session summary saved");
});
});