Skip to content

Commit 4117569

Browse files
committed
test: add tests for callee extraction and refs adapter
Scanner tests: - Extract callees from functions - Extract callees from methods - Include line numbers for callees - No callees for interfaces/type aliases - Deduplicate callees at same line - Handle method calls on objects RefsAdapter tests: - Tool definition validation - Input validation (name, direction, limit) - Callee queries - Caller queries (reverse lookup) - Bidirectional queries - Output formatting (markdown, tokens, duration) - Not found handling - Token estimation Utility tests: - startTimer() elapsed time - Multiple elapsed() calls - Immediate elapsed check All 1320 tests passing. Part of #80
1 parent b1c52e4 commit 4117569

File tree

3 files changed

+439
-1
lines changed

3 files changed

+439
-1
lines changed

packages/core/src/scanner/__tests__/scanner.test.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,4 +594,117 @@ describe('Scanner', () => {
594594
expect(docType?.metadata.imports).toEqual([]);
595595
});
596596
});
597+
598+
describe('Callee Extraction', () => {
599+
it('should extract callees from functions', async () => {
600+
const result = await scanRepository({
601+
repoRoot,
602+
include: ['packages/core/src/scanner/index.ts'],
603+
});
604+
605+
// createDefaultRegistry calls registry.register()
606+
const fn = result.documents.find((d) => d.metadata.name === 'createDefaultRegistry');
607+
expect(fn).toBeDefined();
608+
expect(fn?.metadata.callees).toBeDefined();
609+
expect(fn?.metadata.callees?.length).toBeGreaterThan(0);
610+
611+
// Should have calls to ScannerRegistry constructor and register method
612+
const calleeNames = fn?.metadata.callees?.map((c) => c.name) || [];
613+
expect(calleeNames.some((n) => n.includes('ScannerRegistry') || n.includes('new'))).toBe(
614+
true
615+
);
616+
});
617+
618+
it('should extract callees from methods', async () => {
619+
const result = await scanRepository({
620+
repoRoot,
621+
include: ['packages/core/src/scanner/typescript.ts'],
622+
exclude: ['**/*.test.ts'],
623+
});
624+
625+
// extractFromSourceFile calls other methods like extractFunction, extractClass
626+
const method = result.documents.find(
627+
(d) => d.type === 'method' && d.metadata.name === 'TypeScriptScanner.extractFromSourceFile'
628+
);
629+
expect(method).toBeDefined();
630+
expect(method?.metadata.callees).toBeDefined();
631+
expect(method?.metadata.callees?.length).toBeGreaterThan(0);
632+
633+
// Should call extractFunction, extractClass, etc.
634+
const calleeNames = method?.metadata.callees?.map((c) => c.name) || [];
635+
expect(calleeNames.some((n) => n.includes('extractFunction'))).toBe(true);
636+
});
637+
638+
it('should include line numbers for callees', async () => {
639+
const result = await scanRepository({
640+
repoRoot,
641+
include: ['packages/core/src/scanner/index.ts'],
642+
});
643+
644+
const fn = result.documents.find((d) => d.metadata.name === 'createDefaultRegistry');
645+
expect(fn?.metadata.callees).toBeDefined();
646+
647+
for (const callee of fn?.metadata.callees || []) {
648+
expect(callee.line).toBeDefined();
649+
expect(typeof callee.line).toBe('number');
650+
expect(callee.line).toBeGreaterThan(0);
651+
}
652+
});
653+
654+
it('should not have callees for interfaces', async () => {
655+
const result = await scanRepository({
656+
repoRoot,
657+
include: ['packages/core/src/scanner/types.ts'],
658+
});
659+
660+
// Interfaces don't have callees (no function body)
661+
const iface = result.documents.find((d) => d.metadata.name === 'Scanner');
662+
expect(iface).toBeDefined();
663+
expect(iface?.metadata.callees).toBeUndefined();
664+
});
665+
666+
it('should not have callees for type aliases', async () => {
667+
const result = await scanRepository({
668+
repoRoot,
669+
include: ['packages/core/src/scanner/types.ts'],
670+
});
671+
672+
// Type aliases don't have callees
673+
const typeAlias = result.documents.find((d) => d.metadata.name === 'DocumentType');
674+
expect(typeAlias).toBeDefined();
675+
expect(typeAlias?.metadata.callees).toBeUndefined();
676+
});
677+
678+
it('should deduplicate callees at same line', async () => {
679+
const result = await scanRepository({
680+
repoRoot,
681+
include: ['packages/core/src/scanner/index.ts'],
682+
});
683+
684+
const fn = result.documents.find((d) => d.metadata.name === 'createDefaultRegistry');
685+
expect(fn?.metadata.callees).toBeDefined();
686+
687+
// Check for no duplicates (same name + same line)
688+
const seen = new Set<string>();
689+
for (const callee of fn?.metadata.callees || []) {
690+
const key = `${callee.name}:${callee.line}`;
691+
expect(seen.has(key)).toBe(false);
692+
seen.add(key);
693+
}
694+
});
695+
696+
it('should handle method calls on objects', async () => {
697+
const result = await scanRepository({
698+
repoRoot,
699+
include: ['packages/core/src/scanner/index.ts'],
700+
});
701+
702+
const fn = result.documents.find((d) => d.metadata.name === 'createDefaultRegistry');
703+
expect(fn?.metadata.callees).toBeDefined();
704+
705+
// Should have registry.register() calls
706+
const calleeNames = fn?.metadata.callees?.map((c) => c.name) || [];
707+
expect(calleeNames.some((n) => n.includes('register'))).toBe(true);
708+
});
709+
});
597710
});

0 commit comments

Comments
 (0)