Skip to main content
Glama

mcp-adr-analysis-server

by tosin2013
knowledge-generation.test.ts11.2 kB
/** * Unit tests for Knowledge Generation utility module * Tests the prompt-driven knowledge generation functionality */ import { generateArchitecturalKnowledge, generateDomainKnowledge, enhancePromptWithKnowledge, validateKnowledgeConfig, getSupportedDomains, getSupportedDepths, createDomainKnowledgeConfig, generateKnowledgeCacheKey } from '../src/utils/knowledge-generation.js'; import { ArchitecturalDomain, KnowledgeDepth, KnowledgeGenerationConfig } from '../src/types/knowledge-generation.js'; import { createTestPrompt, createTestKnowledgeConfig, validateKnowledgeResult, measureExecutionTime, runBenchmark } from './utils/advanced-prompting-test-utils.js'; describe('Knowledge Generation Module', () => { describe('generateArchitecturalKnowledge', () => { it('should generate knowledge prompt with valid structure', async () => { const projectInfo = { projectPath: './test-project', technologies: ['react', 'node'], patterns: ['mvc'], projectType: 'web-application' }; const config = createTestKnowledgeConfig(); const result = await generateArchitecturalKnowledge(projectInfo, config); expect(validateKnowledgeResult(result)).toBe(true); expect(result.prompt).toContain('Knowledge Generation Request'); expect(result.context.operation).toBe('knowledge_generation'); expect(result.context.domains).toEqual(config.domains); }); it('should handle different project types', async () => { const projectTypes = ['web-application', 'mobile-app', 'microservices', 'data-platform']; for (const projectType of projectTypes) { const projectInfo = { projectPath: './test-project', technologies: [], patterns: [], projectType }; const result = await generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig()); expect(validateKnowledgeResult(result)).toBe(true); expect(result.prompt).toContain(projectType); } }); it('should include all specified technologies in prompt', async () => { const technologies = ['react', 'node', 'postgresql', 'redis']; const projectInfo = { projectPath: './test-project', technologies, patterns: [], projectType: 'web-application' }; const result = await generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig()); technologies.forEach(tech => { expect(result.prompt.toLowerCase()).toContain(tech.toLowerCase()); }); }); it('should respect depth configuration', async () => { const projectInfo = { projectPath: './test-project', technologies: ['react'], patterns: [], projectType: 'web-application' }; const depths = ['basic', 'intermediate', 'advanced']; for (const depth of depths) { const config = createTestKnowledgeConfig({ depth }); const result = await generateArchitecturalKnowledge(projectInfo, config); expect(result.prompt).toContain(depth); expect(result.context.depth).toBe(depth); } }); it('should handle empty technologies gracefully', async () => { const projectInfo = { projectPath: './test-project', technologies: [], patterns: [], projectType: 'general' }; const result = await generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig()); expect(validateKnowledgeResult(result)).toBe(true); expect(result.prompt).toContain('auto-detect'); }); it('should generate cache key correctly', async () => { const projectInfo = { projectPath: './test-project', technologies: ['react'], patterns: [], projectType: 'web-application' }; const config = createTestKnowledgeConfig(); const result = await generateArchitecturalKnowledge(projectInfo, config); expect(result.context.cacheKey).toBeDefined(); expect(typeof result.context.cacheKey).toBe('string'); expect(result.context.cacheKey).toContain('knowledge'); }); }); describe('generateDomainKnowledge', () => { it('should generate domain-specific knowledge', async () => { const domains: ArchitecturalDomain[] = ['api-design', 'database-design']; for (const domain of domains) { const result = await generateDomainKnowledge(domain, 'intermediate' as KnowledgeDepth); expect(validateKnowledgeResult(result)).toBe(true); expect(result.prompt).toContain(domain); expect(result.context.domain).toBe(domain); } }); it('should handle invalid domains gracefully', async () => { await expect(generateDomainKnowledge('invalid-domain' as ArchitecturalDomain, 'basic' as KnowledgeDepth)) .rejects.toThrow('Unsupported domain'); }); }); describe('enhancePromptWithKnowledge', () => { it('should enhance prompt with knowledge context', async () => { const basePrompt = createTestPrompt(); const domains: ArchitecturalDomain[] = ['api-design', 'database-design']; const result = await enhancePromptWithKnowledge(basePrompt, domains); expect(result.prompt).toContain(basePrompt.prompt); expect(result.prompt).toContain('api-design'); expect(result.context.knowledgeEnhanced).toBe(true); }); it('should preserve original context', async () => { const basePrompt = createTestPrompt({ context: { customField: 'customValue' } }); const domains: ArchitecturalDomain[] = ['web-applications']; const result = await enhancePromptWithKnowledge(basePrompt, domains); expect(result.context.customField).toBe('customValue'); expect(result.context.knowledgeEnhanced).toBe(true); }); }); describe('Configuration Validation', () => { it('should validate correct configuration', () => { const validConfig = createTestKnowledgeConfig(); expect(() => validateKnowledgeConfig(validConfig)).not.toThrow(); }); it('should reject invalid max tokens', () => { const invalidConfig = createTestKnowledgeConfig({ maxTokens: -1 }); expect(() => validateKnowledgeConfig(invalidConfig)) .toThrow('Max tokens must be positive'); }); it('should reject invalid depth', () => { const invalidConfig = createTestKnowledgeConfig({ depth: 'invalid' }); expect(() => validateKnowledgeConfig(invalidConfig)) .toThrow('Invalid depth'); }); it('should reject empty domains', () => { const invalidConfig = createTestKnowledgeConfig({ domains: [] }); expect(() => validateKnowledgeConfig(invalidConfig)) .toThrow('At least one domain must be specified'); }); }); describe('Utility Functions', () => { it('should return supported domains', () => { const domains = getSupportedDomains(); expect(Array.isArray(domains)).toBe(true); expect(domains.length).toBeGreaterThan(0); expect(domains).toContain('api-design'); expect(domains).toContain('database-design'); }); it('should return supported depths', () => { const depths = getSupportedDepths(); expect(Array.isArray(depths)).toBe(true); expect(depths).toEqual(['basic', 'intermediate', 'advanced']); }); it('should create domain-specific configuration', () => { const config = createDomainKnowledgeConfig('api-design'); expect(config.domains).toContain('api-design'); expect(config.depth).toBeDefined(); expect(config.cacheEnabled).toBe(true); }); it('should generate consistent cache keys', () => { const domains: ArchitecturalDomain[] = ['web-applications', 'api-design']; const context = { projectPath: './test', technologies: ['react'], patterns: [], projectType: 'web-app' }; const config: KnowledgeGenerationConfig = createTestKnowledgeConfig(); const key1 = generateKnowledgeCacheKey(domains, context, config); const key2 = generateKnowledgeCacheKey(domains, context, config); expect(key1).toBe(key2); expect(key1).toContain('knowledge'); }); }); describe('Performance Tests', () => { it('should complete knowledge generation within time limit', async () => { const projectInfo = { projectPath: './test-project', technologies: ['react', 'node'], patterns: [], projectType: 'web-application' }; const { executionTime } = await measureExecutionTime(async () => { return await generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig()); }); expect(executionTime).toBeLessThan(1000); // Should complete within 1 second }); it('should handle multiple concurrent requests', async () => { const projectInfo = { projectPath: './test-project', technologies: ['react'], patterns: [], projectType: 'web-application' }; const promises = Array(5).fill(null).map(() => generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig()) ); const results = await Promise.all(promises); results.forEach(result => { expect(validateKnowledgeResult(result)).toBe(true); }); }); it('should maintain performance with large technology lists', async () => { const largeTechList = Array(20).fill(null).map((_, i) => `tech-${i}`); const projectInfo = { projectPath: './test-project', technologies: largeTechList, patterns: [], projectType: 'web-application' }; const benchmark = await runBenchmark(async () => { return await generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig()); }, { iterations: 3 }); expect(benchmark.averageTime).toBeLessThan(2000); // Should average under 2 seconds expect(benchmark.memoryUsage).toBeLessThan(50); // Should use less than 50MB }); }); describe('Error Handling', () => { it('should handle missing project path', async () => { const projectInfo = { projectPath: '', technologies: [], patterns: [], projectType: 'web-application' }; await expect(generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig())) .rejects.toThrow('Project path is required'); }); it('should handle invalid project type', async () => { const projectInfo = { projectPath: './test', technologies: [], patterns: [], projectType: 'invalid-type' }; const result = await generateArchitecturalKnowledge(projectInfo, createTestKnowledgeConfig()); // Should not throw, but should handle gracefully expect(validateKnowledgeResult(result)).toBe(true); }); }); });

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/tosin2013/mcp-adr-analysis-server'

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