/** * Discovery Cache Fixture Generator * * Provides mock DiscoveryCache implementations for testing adapters * that use discovery (e.g., MCP adapters that list tools/prompts/resources). */ import type { DiscoveryCache } from '@wavespec/types'; /** * Discovery cache entry for pre-populating mock cache */ export interface DiscoveryCacheEntry { /** Entry type */ type: 'tools' | 'prompts' | 'resources'; /** Entry data */ data: T[]; } /** * Creates a mock DiscoveryCache for testing * * Generates a DiscoveryCache implementation with pre-populated data or empty caches. * The mock cache stores data in memory and supports all DiscoveryCache methods. * * Features: * - Pre-populate with entries parameter * - Lazy loading (fetcher only called if data not pre-populated) * - In-memory caching (fetcher called once per type) * - Type-safe generic support * * @param entries - Optional array of cache entries to pre-populate * @returns Mock DiscoveryCache implementation * * @example * ```typescript * // Empty cache (will call fetchers on first access) * const cache = createMockDiscoveryCache(); * * // Pre-populated with tools * const cache = createMockDiscoveryCache([ * { * type: 'tools', * data: [ * { name: 'calculator', description: 'Math operations' }, * { name: 'weather', description: 'Weather info' } * ] * } * ]); * * // Use in adapter tests * const tools = await cache.getTools(async () => { * // This fetcher won't be called since cache is pre-populated * return await adapter.listTools(); * }); * ``` */ export function createMockDiscoveryCache( entries: DiscoveryCacheEntry[] = [] ): DiscoveryCache { // Internal cache storage const cache = { tools: undefined as unknown[] | undefined, prompts: undefined as unknown[] | undefined, resources: undefined as unknown[] | undefined, }; // Pre-populate cache with provided entries for (const entry of entries) { switch (entry.type) { case 'tools': cache.tools = entry.data; break; case 'prompts': cache.prompts = entry.data; break; case 'resources': cache.resources = entry.data; break; } } return { async getTools(fetcher: () => Promise): Promise { if (cache.tools !== undefined) { return cache.tools as T[]; } const data = await fetcher(); cache.tools = data as unknown[]; return data; }, async getPrompts(fetcher: () => Promise): Promise { if (cache.prompts !== undefined) { return cache.prompts as T[]; } const data = await fetcher(); cache.prompts = data as unknown[]; return data; }, async getResources(fetcher: () => Promise): Promise { if (cache.resources !== undefined) { return cache.resources as T[]; } const data = await fetcher(); cache.resources = data as unknown[]; return data; }, }; }