Skip to content

Commit 010b1ea

Browse files
committed
test(02-tree-sitter-02): add symbol chunk merge regression
- index a temp project with two small exported functions - assert symbol-aware chunks for a and b remain separate and unmerged
1 parent fd02625 commit 010b1ea

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

tests/symbol-chunk-merge.test.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
2+
import { promises as fs } from 'fs';
3+
import os from 'os';
4+
import path from 'path';
5+
import { CodebaseIndexer } from '../src/core/indexer.js';
6+
import { analyzerRegistry } from '../src/core/analyzer-registry.js';
7+
import { GenericAnalyzer } from '../src/analyzers/generic/index.js';
8+
import {
9+
CODEBASE_CONTEXT_DIRNAME,
10+
KEYWORD_INDEX_FILENAME
11+
} from '../src/constants/codebase-context.js';
12+
13+
describe('Symbol-aware chunk merge guard', () => {
14+
let tempDir: string;
15+
16+
beforeEach(async () => {
17+
analyzerRegistry.register(new GenericAnalyzer());
18+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'symbol-chunk-merge-'));
19+
await fs.writeFile(
20+
path.join(tempDir, 'package.json'),
21+
JSON.stringify({ name: 'symbol-chunk-test' })
22+
);
23+
});
24+
25+
afterEach(async () => {
26+
await fs.rm(tempDir, { recursive: true, force: true });
27+
});
28+
29+
it('keeps small symbol chunks separate during indexing', async () => {
30+
await fs.writeFile(
31+
path.join(tempDir, 'utils.ts'),
32+
[
33+
'export function a(): number {',
34+
' return 1;',
35+
'}',
36+
'',
37+
'export function b(): number {',
38+
' return 2;',
39+
'}'
40+
].join('\n')
41+
);
42+
43+
const indexer = new CodebaseIndexer({
44+
rootPath: tempDir,
45+
config: { skipEmbedding: true }
46+
});
47+
48+
await indexer.index();
49+
50+
const indexPath = path.join(tempDir, CODEBASE_CONTEXT_DIRNAME, KEYWORD_INDEX_FILENAME);
51+
const allChunks = JSON.parse(await fs.readFile(indexPath, 'utf-8')) as Array<{
52+
filePath: string;
53+
relativePath: string;
54+
metadata?: {
55+
componentName?: string;
56+
symbolAware?: boolean;
57+
merged?: boolean;
58+
};
59+
}>;
60+
61+
const utilsChunks = allChunks.filter((chunk) => {
62+
const fileNameFromFilePath = chunk.filePath.split(/[\\/]/).pop();
63+
const fileNameFromRelativePath = chunk.relativePath.split(/[\\/]/).pop();
64+
return fileNameFromFilePath === 'utils.ts' || fileNameFromRelativePath === 'utils.ts';
65+
});
66+
67+
expect(utilsChunks.length).toBeGreaterThanOrEqual(2);
68+
69+
const aChunk = utilsChunks.find((chunk) => chunk.metadata?.componentName === 'a');
70+
const bChunk = utilsChunks.find((chunk) => chunk.metadata?.componentName === 'b');
71+
72+
expect(aChunk).toBeDefined();
73+
expect(bChunk).toBeDefined();
74+
expect(aChunk?.metadata?.symbolAware).toBe(true);
75+
expect(bChunk?.metadata?.symbolAware).toBe(true);
76+
expect(aChunk?.metadata?.merged).not.toBe(true);
77+
expect(bChunk?.metadata?.merged).not.toBe(true);
78+
});
79+
});

0 commit comments

Comments
 (0)