Skip to content

Commit bf03bf8

Browse files
committed
test(02-03): cover get_symbol_references tool wiring
- verify tool registration through exported TOOLS metadata - validate tools/call response includes usageCount and structured usage snippets
1 parent 6f6bc3a commit bf03bf8

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2+
import { promises as fs } from 'fs';
3+
import os from 'os';
4+
import path from 'path';
5+
import {
6+
CODEBASE_CONTEXT_DIRNAME,
7+
KEYWORD_INDEX_FILENAME
8+
} from '../src/constants/codebase-context.js';
9+
10+
describe('get_symbol_references MCP tool', () => {
11+
let tempRoot: string | null = null;
12+
let originalArgv: string[] | null = null;
13+
let originalEnvRoot: string | undefined;
14+
15+
beforeEach(async () => {
16+
vi.resetModules();
17+
18+
originalArgv = [...process.argv];
19+
originalEnvRoot = process.env.CODEBASE_ROOT;
20+
21+
tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'codebase-context-symbol-refs-'));
22+
process.env.CODEBASE_ROOT = tempRoot;
23+
process.argv[2] = tempRoot;
24+
});
25+
26+
afterEach(async () => {
27+
if (originalArgv) {
28+
process.argv = originalArgv;
29+
}
30+
31+
if (originalEnvRoot === undefined) {
32+
delete process.env.CODEBASE_ROOT;
33+
} else {
34+
process.env.CODEBASE_ROOT = originalEnvRoot;
35+
}
36+
37+
if (tempRoot) {
38+
await fs.rm(tempRoot, { recursive: true, force: true });
39+
tempRoot = null;
40+
}
41+
});
42+
43+
it('registers get_symbol_references in TOOLS', async () => {
44+
const { TOOLS } = await import('../src/index.js');
45+
expect(TOOLS.some((tool) => tool.name === 'get_symbol_references')).toBe(true);
46+
});
47+
48+
it('returns usageCount and top usages from keyword index', async () => {
49+
if (!tempRoot) {
50+
throw new Error('tempRoot not initialized');
51+
}
52+
53+
const contextDir = path.join(tempRoot, CODEBASE_CONTEXT_DIRNAME);
54+
await fs.mkdir(contextDir, { recursive: true });
55+
56+
const chunks = [
57+
{
58+
content: 'export function alpha() {\n return beta(alpha);\n}',
59+
startLine: 10,
60+
relativePath: 'src/a.ts'
61+
},
62+
{
63+
content: 'const beta = alpha + 1;\n',
64+
startLine: 2,
65+
relativePath: 'src/b.ts'
66+
}
67+
];
68+
69+
await fs.writeFile(
70+
path.join(contextDir, KEYWORD_INDEX_FILENAME),
71+
JSON.stringify(chunks),
72+
'utf-8'
73+
);
74+
75+
const { server } = await import('../src/index.js');
76+
const handler = (server as any)._requestHandlers.get('tools/call');
77+
78+
const response = await handler({
79+
jsonrpc: '2.0',
80+
id: 1,
81+
method: 'tools/call',
82+
params: {
83+
name: 'get_symbol_references',
84+
arguments: {
85+
symbol: 'alpha',
86+
limit: 2
87+
}
88+
}
89+
});
90+
91+
const payload = JSON.parse(response.content[0].text);
92+
expect(payload.status).toBe('success');
93+
expect(payload.usageCount).toBeGreaterThan(0);
94+
expect(payload.usages.length).toBeLessThanOrEqual(2);
95+
96+
for (const usage of payload.usages) {
97+
expect(usage.file).toBeTypeOf('string');
98+
expect(usage.line).toBeTypeOf('number');
99+
expect(usage.preview).toBeTypeOf('string');
100+
expect(usage.preview.length).toBeGreaterThan(0);
101+
}
102+
});
103+
});

0 commit comments

Comments
 (0)