From 0c84b39b994fb9eab765e95cbe082fa667536ba7 Mon Sep 17 00:00:00 2001 From: wangjichao Date: Tue, 14 Apr 2026 10:53:43 +0800 Subject: [PATCH] test(embeddings): add chunkNode dispatch tests with mocked tree-sitter --- gitnexus/test/unit/chunker.test.ts | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/gitnexus/test/unit/chunker.test.ts b/gitnexus/test/unit/chunker.test.ts index 5f6fc33e4..c7cd2e8b3 100644 --- a/gitnexus/test/unit/chunker.test.ts +++ b/gitnexus/test/unit/chunker.test.ts @@ -4,6 +4,21 @@ import { describe, it, expect } from 'vitest'; import { characterChunk } from '../../src/core/embeddings/character-chunk.js'; +// Mock tree-sitter for chunkNode tests +import { vi } from 'vitest'; + +vi.mock('../../src/core/tree-sitter/parser-loader.js', () => ({ + loadParser: vi.fn(), + loadLanguage: vi.fn(), + isLanguageAvailable: vi.fn().mockReturnValue(true), +})); + +vi.mock('gitnexus-shared', () => ({ + getLanguageFromFilename: vi.fn().mockReturnValue('typescript'), +})); + +import { chunkNode } from '../../src/core/embeddings/chunker.js'; + describe('characterChunk', () => { it('returns single chunk when content fits', () => { const result = characterChunk('short content', 1, 5, 1200, 120); @@ -40,3 +55,39 @@ describe('characterChunk', () => { } }); }); + +describe('chunkNode', () => { + it('returns single chunk for short content', async () => { + const result = await chunkNode('Function', 'short', 'test.ts', 1, 5, 1200, 120); + expect(result).toHaveLength(1); + expect(result[0].chunkIndex).toBe(0); + expect(result[0].text).toBe('short'); + }); + + it('returns character chunks for Class label', async () => { + const content = 'x'.repeat(3000); + const result = await chunkNode('Class', content, 'test.ts', 1, 100, 1200, 120); + expect(result.length).toBeGreaterThan(1); + for (let i = 0; i < result.length; i++) { + expect(result[i].chunkIndex).toBe(i); + } + }); + + it('returns character chunks for Constructor label', async () => { + const content = 'c'.repeat(3000); + const result = await chunkNode('Constructor', content, 'test.ts', 1, 100, 1200, 120); + expect(result.length).toBeGreaterThan(1); + for (let i = 0; i < result.length; i++) { + expect(result[i].chunkIndex).toBe(i); + } + }); + + it('falls back to character chunks when AST fails', async () => { + const { loadParser } = await import('../../src/core/tree-sitter/parser-loader.js'); + (loadParser as ReturnType).mockRejectedValueOnce(new Error('no parser')); + + const content = 'x'.repeat(3000); + const result = await chunkNode('Function', content, 'test.ts', 1, 100, 1200, 120); + expect(result.length).toBeGreaterThan(1); + }); +});