UNPKG

knowledgegraph-mcp

Version:

MCP server for enabling persistent knowledge storage for Claude through a knowledge graph with multiple storage backends

176 lines 6.43 kB
/** * Backend-Specific Test Helpers * * Provides utilities for handling backend-specific behavior in tests, * such as different search capabilities and configuration requirements. */ import { StorageType } from '../../storage/types.js'; import { KnowledgeGraphManager } from '../../core.js'; /** * Get capabilities for a specific backend */ export function getBackendCapabilities(storageType) { switch (storageType) { case StorageType.SQLITE: return { supportsDatabaseSearch: false, // SQLite uses client-side fuzzy search supportsTransactions: true, supportsFullTextSearch: true, // SQLite FTS isInMemory: true, // For tests requiresExternalServer: false }; case StorageType.POSTGRESQL: return { supportsDatabaseSearch: true, // PostgreSQL has similarity functions supportsTransactions: true, supportsFullTextSearch: true, // PostgreSQL full-text search isInMemory: false, requiresExternalServer: true }; default: throw new Error(`Unknown storage type: ${storageType}`); } } /** * Create appropriate search configuration for a backend */ export function createSearchConfig(storageType) { const capabilities = getBackendCapabilities(storageType); return { useDatabaseSearch: capabilities.supportsDatabaseSearch, threshold: 0.3, clientSideFallback: true, fuseOptions: { threshold: 0.3, distance: 100, includeScore: true, keys: ['name', 'entityType', 'observations', 'tags'] } }; } /** * Create a KnowledgeGraphManager instance for testing with appropriate configuration */ export async function createTestManager(config, backendName, options = {}) { const searchConfig = createSearchConfig(config.type); // Apply custom search configuration if provided if (options.customSearchConfig) { Object.assign(searchConfig, options.customSearchConfig); } const manager = new KnowledgeGraphManager({ ...config, fuzzySearch: searchConfig }); // Wait for initialization with backend-specific timeout const timeout = options.timeout || (backendName === 'PostgreSQL' ? 2000 : 500); await new Promise(resolve => setTimeout(resolve, timeout)); return manager; } /** * Cleanup test manager and handle backend-specific cleanup */ export async function cleanupTestManager(manager, backendName) { try { await manager.close(); } catch (error) { console.warn(`Error closing ${backendName} manager:`, error); } } /** * Skip test if backend doesn't support required capability */ export function skipIfNotSupported(storageType, capability, testContext) { const capabilities = getBackendCapabilities(storageType); const isSupported = capabilities[capability]; if (!isSupported && testContext) { testContext.skip(); } return isSupported; } /** * Create backend-specific test expectations */ export function createBackendExpectations(storageType) { const capabilities = getBackendCapabilities(storageType); return { /** * Expect search to use database-level search if supported */ expectDatabaseSearch: (searchResults) => { if (capabilities.supportsDatabaseSearch) { // For PostgreSQL, we expect database-level search to be used // This would be verified by checking that the search was performed at DB level expect(searchResults).toBeDefined(); } else { // For SQLite, we expect client-side search expect(searchResults).toBeDefined(); } }, /** * Expect appropriate search performance characteristics */ expectSearchPerformance: (duration) => { if (capabilities.supportsDatabaseSearch) { // Database search might be slower due to network overhead expect(duration).toBeLessThan(5000); // 5 seconds max } else { // Client-side search should be faster expect(duration).toBeLessThan(1000); // 1 second max } }, /** * Expect backend-specific error handling */ expectErrorHandling: (error) => { if (capabilities.requiresExternalServer) { // PostgreSQL might have connection errors expect(error.message).toMatch(/connection|timeout|server/i); } else { // SQLite errors are usually file/memory related expect(error.message).toMatch(/database|file|memory/i); } } }; } /** * Generate backend-specific test data */ export function generateTestData(storageType, size = 10) { const capabilities = getBackendCapabilities(storageType); const prefix = storageType.toLowerCase(); return Array.from({ length: size }, (_, i) => ({ name: `${prefix}_entity_${i}`, entityType: `${prefix}_type`, observations: [ `Test observation ${i} for ${storageType}`, capabilities.isInMemory ? 'In-memory test data' : 'Persistent test data' ], tags: [`${prefix}`, 'test', `item_${i}`] })); } /** * Wait for backend-specific operations to complete */ export async function waitForBackendOperation(storageType, operation) { const capabilities = getBackendCapabilities(storageType); const timeout = capabilities.requiresExternalServer ? 10000 : 5000; return Promise.race([ operation(), new Promise((_, reject) => setTimeout(() => reject(new Error(`${storageType} operation timed out after ${timeout}ms`)), timeout)) ]); } /** * Create a test project name that's unique per backend */ export function createBackendTestProject(storageType, testName, suffix) { const timestamp = Date.now(); const backendPrefix = storageType.toLowerCase(); const sanitizedTestName = testName.replace(/[^a-zA-Z0-9]/g, '_'); const suffixPart = suffix ? `_${suffix}` : ''; return `${backendPrefix}_${sanitizedTestName}_${timestamp}${suffixPart}`; } //# sourceMappingURL=backend-test-helpers.js.map