| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- import { describe, expect, test } from 'bun:test';
- import { SubagentDepthTracker } from './subagent-depth';
- describe('SubagentDepthTracker', () => {
- describe('constructor', () => {
- test('uses DEFAULT_MAX_SUBAGENT_DEPTH (3) by default', () => {
- const tracker = new SubagentDepthTracker();
- expect(tracker).toBeDefined();
- });
- test('accepts custom max depth', () => {
- const tracker = new SubagentDepthTracker(5);
- expect(tracker).toBeDefined();
- });
- });
- describe('getDepth', () => {
- test('returns 0 for untracked sessions (root sessions)', () => {
- const tracker = new SubagentDepthTracker();
- expect(tracker.getDepth('root-session')).toBe(0);
- expect(tracker.getDepth('untracked-session')).toBe(0);
- });
- test('returns tracked depth for registered sessions', () => {
- const tracker = new SubagentDepthTracker();
- tracker.registerChild('root-session', 'child-session');
- expect(tracker.getDepth('child-session')).toBe(1);
- });
- });
- describe('registerChild', () => {
- test('tracks depth correctly (parent=0, child=1, grandchild=2)', () => {
- const tracker = new SubagentDepthTracker();
- expect(tracker.getDepth('root')).toBe(0);
- const allowed1 = tracker.registerChild('root', 'child1');
- expect(allowed1).toBe(true);
- expect(tracker.getDepth('child1')).toBe(1);
- const allowed2 = tracker.registerChild('child1', 'grandchild');
- expect(allowed2).toBe(true);
- expect(tracker.getDepth('grandchild')).toBe(2);
- });
- test('returns false when max depth exceeded (depth 4 > max 3)', () => {
- const tracker = new SubagentDepthTracker(3);
- const root = 'root';
- const child1 = 'child1';
- const child2 = 'child2';
- const child3 = 'child3';
- const child4 = 'child4';
- expect(tracker.registerChild(root, child1)).toBe(true);
- expect(tracker.registerChild(child1, child2)).toBe(true);
- expect(tracker.registerChild(child2, child3)).toBe(true);
- expect(tracker.registerChild(child3, child4)).toBe(false);
- });
- test('tracks across multiple branches independently', () => {
- const tracker = new SubagentDepthTracker();
- const root = 'root';
- const branch1Child = 'branch1-child';
- const branch2Child = 'branch2-child';
- const branch1Grandchild = 'branch1-grandchild';
- const branch2Grandchild = 'branch2-grandchild';
- tracker.registerChild(root, branch1Child);
- tracker.registerChild(branch1Child, branch1Grandchild);
- tracker.registerChild(root, branch2Child);
- tracker.registerChild(branch2Child, branch2Grandchild);
- expect(tracker.getDepth(branch1Child)).toBe(1);
- expect(tracker.getDepth(branch2Child)).toBe(1);
- expect(tracker.getDepth(branch1Grandchild)).toBe(2);
- expect(tracker.getDepth(branch2Grandchild)).toBe(2);
- });
- test('does not re-register existing session', () => {
- const tracker = new SubagentDepthTracker();
- const root = 'root';
- const child = 'child';
- tracker.registerChild(root, child);
- expect(tracker.getDepth(child)).toBe(1);
- tracker.registerChild(root, child);
- expect(tracker.getDepth(child)).toBe(1);
- });
- test('updates depth if child is re-registered from different parent', () => {
- const tracker = new SubagentDepthTracker();
- const root = 'root';
- const child1 = 'child1';
- const child2 = 'child2';
- const grandchild = 'grandchild';
- tracker.registerChild(root, child1);
- tracker.registerChild(child1, grandchild);
- expect(tracker.getDepth(grandchild)).toBe(2);
- tracker.registerChild(root, child2);
- tracker.registerChild(child2, grandchild);
- expect(tracker.getDepth(grandchild)).toBe(2);
- });
- });
- describe('cleanup', () => {
- test('removes a specific session', () => {
- const tracker = new SubagentDepthTracker();
- const root = 'root';
- const child1 = 'child1';
- const child2 = 'child2';
- tracker.registerChild(root, child1);
- tracker.registerChild(root, child2);
- expect(tracker.getDepth(child1)).toBe(1);
- expect(tracker.getDepth(child2)).toBe(1);
- tracker.cleanup(child1);
- expect(tracker.getDepth(child1)).toBe(0);
- expect(tracker.getDepth(child2)).toBe(1);
- });
- test('does not throw when cleaning up untracked session', () => {
- const tracker = new SubagentDepthTracker();
- expect(() => tracker.cleanup('untracked')).not.toThrow();
- });
- });
- describe('cleanupAll', () => {
- test('removes all sessions', () => {
- const tracker = new SubagentDepthTracker();
- const root = 'root';
- const child1 = 'child1';
- const child2 = 'child2';
- const grandchild = 'grandchild';
- tracker.registerChild(root, child1);
- tracker.registerChild(root, child2);
- tracker.registerChild(child1, grandchild);
- expect(tracker.getDepth(child1)).toBe(1);
- expect(tracker.getDepth(child2)).toBe(1);
- expect(tracker.getDepth(grandchild)).toBe(2);
- tracker.cleanupAll();
- expect(tracker.getDepth(child1)).toBe(0);
- expect(tracker.getDepth(child2)).toBe(0);
- expect(tracker.getDepth(grandchild)).toBe(0);
- });
- test('does not throw when called on empty tracker', () => {
- const tracker = new SubagentDepthTracker();
- expect(() => tracker.cleanupAll()).not.toThrow();
- });
- });
- });
|