UNPKG

@alvinveroy/codecompass

Version:

AI-powered MCP server for codebase navigation and LLM prompt optimization

174 lines (173 loc) 10.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); (0, vitest_1.describe)('Config Module', () => { // Save original environment variables const originalEnv = { ...process.env }; (0, vitest_1.beforeEach)(() => { // Restore process.env to original state before each test process.env = { ...originalEnv }; // Ensure OLLAMA_HOST and QDRANT_HOST are unset so ConfigService uses its internal defaults // for tests relying on those defaults (e.g., "Default Configuration" tests). // Tests that specifically override these variables will set them after this block. delete process.env.OLLAMA_HOST; delete process.env.QDRANT_HOST; // Explicitly reset global variables that ConfigService might use/set // These globals are set by ConfigService.initializeGlobalState() // Resetting them ensures a clean slate for each test's ConfigService instantiation. const g = globalThis; g.CURRENT_LLM_PROVIDER = undefined; // Assign undefined directly g.CURRENT_SUGGESTION_PROVIDER = undefined; // Assign undefined directly g.CURRENT_EMBEDDING_PROVIDER = undefined; // Assign undefined directly g.CURRENT_SUGGESTION_MODEL = undefined; // Assign undefined directly vitest_1.vi.resetModules(); // This is key for re-importing and re-instantiating ConfigService }); (0, vitest_1.afterEach)(() => { // Restore original environment variables fully after each test process.env = { ...originalEnv }; vitest_1.vi.restoreAllMocks(); vitest_1.vi.resetModules(); }); (0, vitest_1.describe)('Default Configuration', () => { let currentConfigService; // Use the imported type (0, vitest_1.beforeEach)(async () => { // Dynamically import configService to ensure a fresh instance for each test // after vi.resetModules() in the outer beforeEach has run, // and after OLLAMA_HOST/QDRANT_HOST env vars have been deleted. const mod = await import('../lib/config-service.js'); currentConfigService = mod.configService; }); (0, vitest_1.it)('should have default values for all required configuration', () => { (0, vitest_1.expect)(currentConfigService.OLLAMA_HOST).toBeDefined(); (0, vitest_1.expect)(currentConfigService.QDRANT_HOST).toBeDefined(); (0, vitest_1.expect)(currentConfigService.COLLECTION_NAME).toBeDefined(); (0, vitest_1.expect)(currentConfigService.EMBEDDING_MODEL).toBeDefined(); (0, vitest_1.expect)(currentConfigService.SUGGESTION_MODEL).toBeDefined(); (0, vitest_1.expect)(currentConfigService.MAX_RETRIES).toBeGreaterThan(0); (0, vitest_1.expect)(currentConfigService.RETRY_DELAY).toBeGreaterThan(0); (0, vitest_1.expect)(currentConfigService.MAX_INPUT_LENGTH).toBeGreaterThan(0); }); (0, vitest_1.it)('should have valid URL formats for host configurations', () => { const urlPattern = /^https?:\/\/.+/; (0, vitest_1.expect)(currentConfigService.OLLAMA_HOST).toMatch(urlPattern); (0, vitest_1.expect)(currentConfigService.QDRANT_HOST).toMatch(urlPattern); }); (0, vitest_1.it)('should have reasonable limits for MAX_INPUT_LENGTH', () => { (0, vitest_1.expect)(currentConfigService.MAX_INPUT_LENGTH).toBeGreaterThan(100); (0, vitest_1.expect)(currentConfigService.MAX_INPUT_LENGTH).toBeLessThan(100000); // Assuming there's some reasonable upper limit }); (0, vitest_1.it)('should have reasonable values for retry configuration', () => { (0, vitest_1.expect)(currentConfigService.MAX_RETRIES).toBeGreaterThanOrEqual(1); (0, vitest_1.expect)(currentConfigService.MAX_RETRIES).toBeLessThanOrEqual(10); // Assuming there's some reasonable upper limit (0, vitest_1.expect)(currentConfigService.RETRY_DELAY).toBeGreaterThanOrEqual(100); // At least 100ms (0, vitest_1.expect)(currentConfigService.RETRY_DELAY).toBeLessThanOrEqual(30000); // Not more than 30 seconds }); }); (0, vitest_1.describe)('Logger Configuration', () => { let currentConfigService; // Use the imported type (0, vitest_1.beforeEach)(async () => { // Dynamically import for a fresh instance const mod = await import('../lib/config-service.js'); currentConfigService = mod.configService; }); (0, vitest_1.it)('should have a properly configured logger', () => { (0, vitest_1.expect)(currentConfigService.logger).toBeDefined(); (0, vitest_1.expect)(typeof currentConfigService.logger.info).toBe('function'); (0, vitest_1.expect)(typeof currentConfigService.logger.error).toBe('function'); (0, vitest_1.expect)(typeof currentConfigService.logger.warn).toBe('function'); (0, vitest_1.expect)(typeof currentConfigService.logger.debug).toBe('function'); }); (0, vitest_1.it)('should be able to log messages without throwing errors', () => { // Mock console methods to prevent actual logging during tests const originalInfo = console.info; const originalError = console.error; const originalWarn = console.warn; const originalDebug = console.debug; console.info = vitest_1.vi.fn(); console.error = vitest_1.vi.fn(); console.warn = vitest_1.vi.fn(); console.debug = vitest_1.vi.fn(); (0, vitest_1.expect)(() => currentConfigService.logger.info('Test info message')).not.toThrow(); (0, vitest_1.expect)(() => currentConfigService.logger.error('Test error message')).not.toThrow(); (0, vitest_1.expect)(() => currentConfigService.logger.warn('Test warning message')).not.toThrow(); (0, vitest_1.expect)(() => currentConfigService.logger.debug('Test debug message')).not.toThrow(); // Restore console methods console.info = originalInfo; console.error = originalError; console.warn = originalWarn; console.debug = originalDebug; }); }); (0, vitest_1.describe)('Environment Variable Overrides', () => { (0, vitest_1.beforeEach)(() => { // Mock 'fs' specifically for this suite. // This ensures that ConfigService does not load from actual config files during these tests. vitest_1.vi.doMock('fs', async () => { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const actualFs = await vitest_1.vi.importActual('fs'); // Keep 'typeof import("fs")' for precision return { ...actualFs, existsSync: vitest_1.vi.fn((pathToCheck) => { if (typeof pathToCheck === 'string' && (pathToCheck.endsWith('model-config.json') || pathToCheck.endsWith('deepseek-config.json'))) { return false; } return actualFs.existsSync(pathToCheck); }), readFileSync: vitest_1.vi.fn((pathToCheck, options) => { if (typeof pathToCheck === 'string' && (pathToCheck.endsWith('model-config.json') || pathToCheck.endsWith('deepseek-config.json'))) { const e = new Error(`ENOENT: no such file or directory, open '${pathToCheck}' (mocked)`); const errorWithCode = e; errorWithCode.code = 'ENOENT'; throw e; } return actualFs.readFileSync(pathToCheck, options); }), mkdirSync: actualFs.mkdirSync, }; }); }); (0, vitest_1.afterEach)(() => { vitest_1.vi.doUnmock('fs'); // Clean up the 'fs' mock after this suite }); (0, vitest_1.it)('should respect OLLAMA_HOST environment variable if set', async () => { const testUrl = 'http://test-ollama-host:11434'; process.env.OLLAMA_HOST = testUrl; vitest_1.vi.resetModules(); // Ensure configService is re-initialized const mod = await import('../lib/config-service.js'); const freshConfigService = mod.configService; // reloadConfigsFromFile is implicitly called by constructor if resetModules works as expected // or call it explicitly if needed after re-import freshConfigService.reloadConfigsFromFile(true); (0, vitest_1.expect)(freshConfigService.OLLAMA_HOST).toBe(testUrl); }); (0, vitest_1.it)('should respect QDRANT_HOST environment variable if set', async () => { const testUrl = 'http://test-qdrant-host:6333'; process.env.QDRANT_HOST = testUrl; vitest_1.vi.resetModules(); const mod = await import('../lib/config-service.js'); const freshConfigService = mod.configService; freshConfigService.reloadConfigsFromFile(true); (0, vitest_1.expect)(freshConfigService.QDRANT_HOST).toBe(testUrl); }); (0, vitest_1.it)('should respect custom model configurations if set via environment variables', async () => { const testModel = 'test-model-from-env'; const testProvider = 'ollama'; // Set environment variables *before* any potential module import or reset process.env.EMBEDDING_MODEL = testModel; process.env.SUGGESTION_MODEL = testModel; process.env.SUGGESTION_PROVIDER = testProvider; // Ensure a completely fresh import of config-service after env vars are set vitest_1.vi.resetModules(); const { configService: freshConfigService } = await import('../lib/config-service.js'); // The ConfigService constructor should have picked up these env vars. // reloadConfigsFromFile(true) is called by the constructor. // If we call it again, it re-initializes from env vars then attempts file load. // This should be redundant if vi.resetModules() + import works as expected. // However, to be absolutely sure it re-evaluates with current process.env: freshConfigService.reloadConfigsFromFile(true); (0, vitest_1.expect)(freshConfigService.EMBEDDING_MODEL).toBe(testModel); (0, vitest_1.expect)(freshConfigService.SUGGESTION_MODEL).toBe(testModel); (0, vitest_1.expect)(freshConfigService.SUGGESTION_PROVIDER).toBe(testProvider); }); }); });