@alvinveroy/codecompass
Version:
AI-powered MCP server for codebase navigation and LLM prompt optimization
174 lines (173 loc) • 10.9 kB
JavaScript
;
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);
});
});
});