test: add coverage for Claude Code JSONL format and assistant tool blocks

Tests the new transcript parsing from PR #215:
- entry.message.content format (string and array content)
- tool_use blocks nested in assistant message content arrays
- Verifies file paths and tool names extracted from both formats
This commit is contained in:
Affaan Mustafa
2026-02-13 01:07:23 -08:00
parent 654731f232
commit c1b6e0bf11

View File

@@ -814,6 +814,75 @@ async function runTests() {
cleanupTestDir(testDir);
})) passed++; else failed++;
if (await asyncTest('parses Claude Code JSONL format (entry.message.content)', async () => {
const testDir = createTestDir();
const transcriptPath = path.join(testDir, 'transcript.jsonl');
// Claude Code v2.1.41+ JSONL format: user messages nested in entry.message
const lines = [
'{"type":"user","message":{"role":"user","content":"Fix the build error"}}',
'{"type":"user","message":{"role":"user","content":[{"type":"text","text":"Also update tests"}]}}',
];
fs.writeFileSync(transcriptPath, lines.join('\n'));
const stdinJson = JSON.stringify({ transcript_path: transcriptPath });
const result = await runScript(path.join(scriptsDir, 'session-end.js'), stdinJson, {
HOME: testDir
});
assert.strictEqual(result.code, 0);
const claudeDir = path.join(testDir, '.claude', 'sessions');
if (fs.existsSync(claudeDir)) {
const files = fs.readdirSync(claudeDir).filter(f => f.endsWith('.tmp'));
if (files.length > 0) {
const content = fs.readFileSync(path.join(claudeDir, files[0]), 'utf8');
assert.ok(content.includes('Fix the build error'), 'Should extract string content from message');
assert.ok(content.includes('Also update tests'), 'Should extract array content from message');
}
}
cleanupTestDir(testDir);
})) passed++; else failed++;
if (await asyncTest('extracts tool_use from assistant message content blocks', async () => {
const testDir = createTestDir();
const transcriptPath = path.join(testDir, 'transcript.jsonl');
// Claude Code JSONL: tool uses nested in assistant message content array
const lines = [
'{"type":"user","content":"Edit the config"}',
JSON.stringify({
type: 'assistant',
message: {
role: 'assistant',
content: [
{ type: 'text', text: 'I will edit the file.' },
{ type: 'tool_use', name: 'Edit', input: { file_path: '/src/app.ts' } },
{ type: 'tool_use', name: 'Write', input: { file_path: '/src/new.ts' } },
]
}
}),
];
fs.writeFileSync(transcriptPath, lines.join('\n'));
const stdinJson = JSON.stringify({ transcript_path: transcriptPath });
const result = await runScript(path.join(scriptsDir, 'session-end.js'), stdinJson, {
HOME: testDir
});
assert.strictEqual(result.code, 0);
const claudeDir = path.join(testDir, '.claude', 'sessions');
if (fs.existsSync(claudeDir)) {
const files = fs.readdirSync(claudeDir).filter(f => f.endsWith('.tmp'));
if (files.length > 0) {
const content = fs.readFileSync(path.join(claudeDir, files[0]), 'utf8');
assert.ok(content.includes('Edit'), 'Should extract Edit tool from content blocks');
assert.ok(content.includes('/src/app.ts'), 'Should extract file path from Edit block');
assert.ok(content.includes('/src/new.ts'), 'Should extract file path from Write block');
}
}
cleanupTestDir(testDir);
})) passed++; else failed++;
// hooks.json validation
console.log('\nhooks.json Validation:');