// Shared test utilities for hook script tests. // Uses node:child_process to pipe JSON stdin to hook scripts. import { execSync } from 'child_process'; import { mkdtempSync, rmSync, mkdirSync, writeFileSync, readFileSync, existsSync } from 'fs'; import { join } from 'path'; import { tmpdir } from 'os'; const SCRIPTS_DIR = join(import.meta.dirname, '..', 'hooks', 'scripts'); export function runHook(scriptName, stdinJson, dataDir) { const input = typeof stdinJson === 'string' ? stdinJson : JSON.stringify(stdinJson); const env = { ...process.env, CLAUDE_PLUGIN_DATA: dataDir }; const stdout = execSync(`node ${join(SCRIPTS_DIR, scriptName)}`, { input, env, encoding: 'utf8', timeout: 5000, }); try { return JSON.parse(stdout.trim()); } catch { return { raw: stdout.trim() }; } } export function setupTestDir() { const dir = mkdtempSync(join(tmpdir(), 'ia-test-')); mkdirSync(join(dir, 'state'), { recursive: true }); return dir; } export function cleanupTestDir(dir) { rmSync(dir, { recursive: true, force: true }); } export function createStateFile(dir, sid, state) { writeFileSync(join(dir, 'state', `${sid}.json`), JSON.stringify(state, null, 2)); } export function readState(dir, sid) { const f = join(dir, 'state', `${sid}.json`); if (!existsSync(f)) return null; return JSON.parse(readFileSync(f, 'utf8')); } export function readJsonl(filePath) { if (!existsSync(filePath)) return []; return readFileSync(filePath, 'utf8') .split('\n') .filter(Boolean) .map(line => JSON.parse(line)); }