Initial commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
// tests/mutator/claude.test.ts — Test Claude settings hook injection
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
import { SCRIPT_NAME } from "../../src/utils/config";
|
||||
|
||||
describe("Claude settings hook format", () => {
|
||||
const testDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-test-"));
|
||||
const settingsPath = path.join(testDir, ".claude", "settings.json");
|
||||
|
||||
beforeEach(() => {
|
||||
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fs.rmSync(testDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test("creates nested hook structure from empty settings", () => {
|
||||
const hookCommand = "bun run ~/.claude/package/opensearch_init.js";
|
||||
|
||||
// Start with empty settings
|
||||
fs.writeFileSync(settingsPath, "{}", "utf-8");
|
||||
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
||||
settings.hooks = {};
|
||||
settings.hooks.SessionStart = [];
|
||||
settings.hooks.SessionStart.push({
|
||||
matcher: "*",
|
||||
hooks: [{ type: "command", command: hookCommand }],
|
||||
});
|
||||
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
||||
|
||||
const result = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
||||
expect(result.hooks).toBeDefined();
|
||||
expect(result.hooks.SessionStart).toBeInstanceOf(Array);
|
||||
expect(result.hooks.SessionStart[0]).toEqual({
|
||||
matcher: "*",
|
||||
hooks: [{ type: "command", command: hookCommand }],
|
||||
});
|
||||
});
|
||||
|
||||
test("appends to existing nested hook", () => {
|
||||
const hookCommand1 = "bun run ~/.claude/package/opensearch_init.js";
|
||||
const hookCommand2 = "bun run ~/.codex/package/opensearch_init.js";
|
||||
|
||||
const existing = {
|
||||
hooks: {
|
||||
SessionStart: [
|
||||
{
|
||||
matcher: "*",
|
||||
hooks: [
|
||||
{ type: "command", command: ".vscode/setup.mjs" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
fs.writeFileSync(settingsPath, JSON.stringify(existing, null, 2), "utf-8");
|
||||
|
||||
// Simulate adding two hooks
|
||||
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
||||
const entry = settings.hooks.SessionStart[0];
|
||||
entry.hooks.push({ type: "command", command: hookCommand1 });
|
||||
entry.hooks.push({ type: "command", command: hookCommand2 });
|
||||
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
||||
|
||||
const result = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
||||
expect(result.hooks.SessionStart[0].hooks.length).toBe(3);
|
||||
expect(result.hooks.SessionStart[0].hooks[1]).toEqual({
|
||||
type: "command",
|
||||
command: hookCommand1,
|
||||
});
|
||||
expect(result.hooks.SessionStart[0].hooks[2]).toEqual({
|
||||
type: "command",
|
||||
command: hookCommand2,
|
||||
});
|
||||
});
|
||||
|
||||
test("creates matcher entry when SessionStart is empty array", () => {
|
||||
const hookCommand = "bun run ~/.codex/package/opensearch_init.js";
|
||||
fs.writeFileSync(settingsPath, "{}", "utf-8");
|
||||
|
||||
const settings = { hooks: { SessionStart: [] as any[] } };
|
||||
settings.hooks.SessionStart.push({
|
||||
matcher: "*",
|
||||
hooks: [{ type: "command", command: hookCommand }],
|
||||
});
|
||||
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
||||
|
||||
const result = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
||||
expect(result.hooks.SessionStart[0]).toEqual({
|
||||
matcher: "*",
|
||||
hooks: [{ type: "command", command: hookCommand }],
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user