Skip to main content
Glama
searchService.test.ts5.62 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; // Import the services we'll test (these don't exist yet) import { SearchService } from '../../src/search/searchService'; import { RepositoryManager } from '../../src/core/repositoryManager'; import { Repository } from '../../src/core/repository'; import { LocalGitAdapter } from '../../src/adapters/localGitAdapter'; // Get the current directory const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Path to test repositories const TEST_REPOS_DIR = path.join(__dirname, '..', '..', 'test-repos'); const REPO1_PATH = path.join(TEST_REPOS_DIR, 'repo1'); const REPO2_PATH = path.join(TEST_REPOS_DIR, 'repo2'); describe('SearchService', () => { let repositoryManager: RepositoryManager; let searchService: SearchService; let repo1: Repository; let repo2: Repository; let repo1Id: string; let repo2Id: string; beforeEach(async () => { // Create test repositories directories [REPO1_PATH, REPO2_PATH].forEach(repoPath => { if (!fs.existsSync(repoPath)) { fs.mkdirSync(repoPath, { recursive: true }); } }); // Initialize repositories const adapter = new LocalGitAdapter(); repo1 = await adapter.initialize(REPO1_PATH); repo2 = await adapter.initialize(REPO2_PATH); // Create repository manager repositoryManager = new RepositoryManager(); repo1Id = await repositoryManager.registerRepository('repo1', repo1); repo2Id = await repositoryManager.registerRepository('repo2', repo2); // Create test files in repositories const testFiles = [ { repo: repo1, path: 'doc1.md', content: '# Document 1\n\nThis is a test document about **artificial intelligence** and machine learning.' }, { repo: repo1, path: 'doc2.md', content: '# Document 2\n\nThis document discusses **git** repositories and version control systems.' }, { repo: repo2, path: 'doc3.md', content: '# Document 3\n\nHere we talk about **artificial intelligence** applications in business.' }, { repo: repo2, path: 'doc4.md', content: '# Document 4\n\nThis is about software development and **programming** best practices.' }, ]; for (const file of testFiles) { await file.repo.writeFile(file.path, file.content); await file.repo.commit(`Add ${file.path}`); } // Create search service searchService = new SearchService(repositoryManager); // Initialize search index await searchService.initializeIndex(); }); afterEach(() => { // Clean up test repositories [REPO1_PATH, REPO2_PATH].forEach(repoPath => { if (fs.existsSync(repoPath)) { fs.rmSync(repoPath, { recursive: true, force: true }); } }); }); it('should perform keyword search across repositories', async () => { // Search for the keyword "artificial intelligence" const results = await searchService.keywordSearch('artificial intelligence'); // Should find 2 documents expect(results).toHaveLength(2); // Verify the results expect(results).toContainEqual(expect.objectContaining({ repositoryId: repo1Id, path: 'doc1.md', score: expect.any(Number), })); expect(results).toContainEqual(expect.objectContaining({ repositoryId: repo2Id, path: 'doc3.md', score: expect.any(Number), })); // Results should be sorted by score (highest first) expect(results[0].score).toBeGreaterThanOrEqual(results[1].score); }); it('should perform semantic search using embeddings', async () => { // Search for semantically similar content to "AI applications" const results = await searchService.semanticSearch('AI applications'); // Should find relevant documents expect(results.length).toBeGreaterThan(0); // The first result should be doc3.md (most relevant to AI applications) expect(results[0]).toEqual(expect.objectContaining({ repositoryId: repo2Id, path: 'doc3.md', score: expect.any(Number) })); }); it('should filter search results by repository', async () => { // Search only in repo1 const results = await searchService.keywordSearch('document', { repositoryId: repo1Id }); // Should find documents only from repo1 expect(results.length).toBeGreaterThan(0); results.forEach(result => { expect(result.repositoryId).toBe(repo1Id); }); }); it('should update search index when files change', async () => { // Add a new file to repo1 await repo1.writeFile('new-doc.md', '# New Document\n\nThis document is about **quantum computing**.'); await repo1.commit('Add new-doc.md'); // Update the index await searchService.updateIndex(repo1Id); // Search for "quantum" const results = await searchService.keywordSearch('quantum'); // Should find the new document expect(results).toHaveLength(1); expect(results[0]).toEqual(expect.objectContaining({ repositoryId: repo1Id, path: 'new-doc.md', score: expect.any(Number) })); }); it('should search for related files', async () => { // Find files related to doc1.md const results = await searchService.findRelatedFiles(repo1Id, 'doc1.md'); // Should find doc3.md as related (both about AI) expect(results).toContainEqual(expect.objectContaining({ repositoryId: repo2Id, path: 'doc3.md', score: expect.any(Number) })); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Lspace-io/lspace-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server