test: add stress test and PostToolUse preservation tests

- Add stress test for 15 duplicate hooks (verifies O(n) scaling)
- Add test verifying PostToolUse/PreToolCall remain untouched
- Add optional debug logging when duplicates removed (CCS_DEBUG)

Addresses review feedback from PR #452
This commit is contained in:
kaitranntt
2026-02-04 11:44:33 -05:00
parent 57d4b04c68
commit 2fe6c336d7
2 changed files with 86 additions and 1 deletions
+7 -1
View File
@@ -48,5 +48,11 @@ export function deduplicateCcsHooks(settings: Record<string, unknown>): boolean
return false; // Remove subsequent duplicates
});
return hooks.PreToolUse.length < originalLength;
const newLength = hooks.PreToolUse.length;
if (process.env.CCS_DEBUG && newLength < originalLength) {
const removedCount = originalLength - newLength;
console.error(`Removed ${removedCount} duplicate CCS WebSearch hook(s)`);
}
return newLength < originalLength;
}
@@ -289,4 +289,83 @@ describe('deduplicateCcsHooks', () => {
expect(result).toBe(false);
expect(settings.hooks.PreToolUse).toHaveLength(0);
});
test('Stress test: 15 duplicate CCS WebSearch hooks', () => {
const ccsHook = {
matcher: 'WebSearch',
hooks: [
{
command: 'node /home/user/.ccs/hooks/websearch-transformer/index.js',
},
],
};
const settings = {
hooks: {
PreToolUse: Array(15).fill(ccsHook),
},
};
const result = deduplicateCcsHooks(settings);
expect(result).toBe(true);
expect(settings.hooks.PreToolUse).toHaveLength(1);
expect(settings.hooks.PreToolUse[0]).toEqual(ccsHook);
});
test('Leaves PostToolUse and PreToolCall untouched', () => {
const postToolUseHook1 = {
matcher: 'CustomMatcher1',
hooks: [{ command: 'custom-command-1' }],
};
const postToolUseHook2 = {
matcher: 'CustomMatcher2',
hooks: [{ command: 'custom-command-2' }],
};
const preToolCallHook = {
matcher: 'CustomMatcher3',
hooks: [{ command: 'custom-command-3' }],
};
const settings = {
hooks: {
PreToolUse: [
{
matcher: 'WebSearch',
hooks: [
{
command: 'node /path1/.ccs/hooks/websearch-transformer/index.js',
},
],
},
{
matcher: 'WebSearch',
hooks: [
{
command: 'node /path2/.ccs/hooks/websearch-transformer/index.js',
},
],
},
{
matcher: 'WebSearch',
hooks: [
{
command: 'node /path3/.ccs/hooks/websearch-transformer/index.js',
},
],
},
],
PostToolUse: [postToolUseHook1, postToolUseHook2],
PreToolCall: [preToolCallHook],
},
};
const result = deduplicateCcsHooks(settings);
expect(result).toBe(true);
// PreToolUse should be deduplicated to 1 hook
expect(settings.hooks.PreToolUse).toHaveLength(1);
expect(settings.hooks.PreToolUse[0].matcher).toBe('WebSearch');
// PostToolUse should remain unchanged with 2 hooks
expect(settings.hooks.PostToolUse).toHaveLength(2);
expect(settings.hooks.PostToolUse[0]).toEqual(postToolUseHook1);
expect(settings.hooks.PostToolUse[1]).toEqual(postToolUseHook2);
// PreToolCall should remain unchanged with 1 hook
expect(settings.hooks.PreToolCall).toHaveLength(1);
expect(settings.hooks.PreToolCall[0]).toEqual(preToolCallHook);
});
});