@kb-labs/shared-testing 2.88.0 → 2.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -183,14 +183,15 @@ function mockLLM() {
|
|
|
183
183
|
return (...args) => {
|
|
184
184
|
built = null;
|
|
185
185
|
const result = method(...args);
|
|
186
|
-
if (result === target || result && typeof result === "object" && "respondWith" in result) {
|
|
186
|
+
if (result === target || result !== null && typeof result === "object" && "respondWith" in result) {
|
|
187
187
|
if (result === target) {
|
|
188
188
|
return proxy;
|
|
189
189
|
}
|
|
190
|
+
const resultWithRespond = result;
|
|
190
191
|
return {
|
|
191
192
|
respondWith: (...rArgs) => {
|
|
192
193
|
built = null;
|
|
193
|
-
|
|
194
|
+
resultWithRespond.respondWith(...rArgs);
|
|
194
195
|
return proxy;
|
|
195
196
|
}
|
|
196
197
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/setup-platform.ts","../src/mock-llm.ts","../src/mock-cache.ts","../src/mock-storage.ts","../src/mock-logger.ts","../src/create-test-context.ts","../src/test-command.ts"],"names":["vi","platform"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/shared-testing/setup-platform\n *\n * Solves the \"singleton gap\" problem: composables (useLLM, useCache, etc.)\n * read from the global platform singleton, but createTestContext() only\n * populates ctx.platform. This module bridges the gap by setting test mocks\n * directly into the global singleton.\n */\n\nimport { platform, resetPlatform } from '@kb-labs/core-runtime';\nimport type {\n ILLM,\n ICache,\n IEmbeddings,\n IVectorStore,\n IStorage,\n IAnalytics,\n ILogger,\n IEventBus,\n} from '@kb-labs/core-platform';\n\n/**\n * Options for setting up the test platform.\n * Only adapters that are provided will be registered.\n * Omitted adapters will use the PlatformContainer's built-in fallbacks.\n */\nexport interface TestPlatformOptions {\n llm?: ILLM;\n cache?: ICache;\n embeddings?: IEmbeddings;\n vectorStore?: IVectorStore;\n storage?: IStorage;\n analytics?: IAnalytics;\n logger?: ILogger;\n eventBus?: IEventBus;\n}\n\nexport interface TestPlatformResult {\n /** The global platform singleton (with test mocks applied) */\n platform: typeof platform;\n /** Call in afterEach() to reset the singleton to a clean state */\n cleanup: () => void;\n}\n\n/**\n * Setup the global platform singleton with test mocks.\n *\n * This ensures that useLLM(), useCache() and other composables\n * return the test mocks instead of uninitialized/stale adapters.\n *\n * @example\n * ```typescript\n * import { setupTestPlatform, mockLLM } from '@kb-labs/shared-testing';\n *\n * describe('my handler', () => {\n * let cleanup: () => void;\n *\n * beforeEach(() => {\n * const result = setupTestPlatform({\n * llm: mockLLM().onAnyComplete().respondWith('hello'),\n * });\n * cleanup = result.cleanup;\n * });\n *\n * afterEach(() => cleanup());\n *\n * it('uses LLM', async () => {\n * const llm = useLLM(); // Returns the test mock!\n * const res = await llm!.complete('test');\n * expect(res.content).toBe('hello');\n * });\n * });\n * ```\n */\nexport function setupTestPlatform(options: TestPlatformOptions = {}): TestPlatformResult {\n // Reset everything first — clean slate\n resetPlatform();\n\n // Register provided adapters into the global singleton\n const adapterMap: Array<[string, unknown]> = [\n ['llm', options.llm],\n ['cache', options.cache],\n ['embeddings', options.embeddings],\n ['vectorStore', options.vectorStore],\n ['storage', options.storage],\n ['analytics', options.analytics],\n ['logger', options.logger],\n ['eventBus', options.eventBus],\n ];\n\n for (const [key, instance] of adapterMap) {\n if (instance !== undefined) {\n platform.setAdapter(key, instance);\n }\n }\n\n return {\n platform,\n cleanup: () => resetPlatform(),\n };\n}\n","/**\n * @module @kb-labs/shared-testing/mock-llm\n *\n * LLM mock builder with fluent API and call tracking.\n *\n * @example\n * ```typescript\n * const llm = mockLLM()\n * .onComplete('Generate commit').respondWith('feat: add login')\n * .onComplete(/explain/i).respondWith('This function does X')\n * .onAnyComplete().respondWith('default answer');\n *\n * const res = await llm.complete('Generate commit message');\n * expect(res.content).toBe('feat: add login');\n * expect(llm.complete).toHaveBeenCalledOnce();\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMToolCall,\n} from '@kb-labs/core-platform';\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\n/** Recorded call to complete() */\nexport interface LLMCall {\n prompt: string;\n options?: LLMOptions;\n response: LLMResponse;\n}\n\n/** Recorded call to chatWithTools() */\nexport interface LLMToolCallRecord {\n messages: LLMMessage[];\n options: LLMToolCallOptions;\n response: LLMToolCallResponse;\n}\n\ntype PromptMatcher = string | RegExp | ((prompt: string) => boolean);\n\ninterface CompletionRule {\n matcher: PromptMatcher;\n response: string | LLMResponse | ((prompt: string) => string | LLMResponse);\n}\n\n/**\n * Mock LLM instance with call tracking and fluent API.\n * All methods are vi.fn() spies.\n */\nexport interface MockLLMInstance extends ILLM {\n /** All recorded complete() calls */\n calls: LLMCall[];\n /** Last complete() call (or undefined) */\n lastCall: LLMCall | undefined;\n /** All recorded chatWithTools() calls */\n toolCalls: LLMToolCallRecord[];\n /** Reset all recorded calls and spies */\n resetCalls: () => void;\n}\n\n/** Public type returned by mockLLM() — builder fluent API + ILLM spy instance */\nexport interface MockLLM extends MockLLMInstance {\n onComplete(matcher: PromptMatcher): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLM };\n onAnyComplete(): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLM };\n streaming(chunks: string[]): MockLLM;\n failing(error: Error): MockLLM;\n withToolCalls(calls: LLMToolCall[], content?: string): MockLLM;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Builder\n// ────────────────────────────────────────────────────────────────────\n\nclass MockLLMBuilder {\n private rules: CompletionRule[] = [];\n private defaultResponse: string | LLMResponse | ((prompt: string) => string | LLMResponse) = 'mock response';\n private streamChunks: string[] = ['mock'];\n private errorToThrow: Error | null = null;\n private toolCallsToReturn: LLMToolCall[] = [];\n private toolCallResponseContent = '';\n\n /**\n * Match a specific prompt (exact string or regex).\n * Returns a handler to set the response.\n */\n onComplete(matcher: PromptMatcher): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLMBuilder } {\n return {\n respondWith: (response) => {\n this.rules.push({ matcher, response });\n return this;\n },\n };\n }\n\n /**\n * Set the default response for any prompt that doesn't match a rule.\n */\n onAnyComplete(): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLMBuilder } {\n return {\n respondWith: (response) => {\n this.defaultResponse = response;\n return this;\n },\n };\n }\n\n /**\n * Configure streaming to yield specific chunks.\n */\n streaming(chunks: string[]): MockLLMBuilder {\n this.streamChunks = chunks;\n return this;\n }\n\n /**\n * Make the LLM throw an error on every call.\n */\n failing(error: Error): MockLLMBuilder {\n this.errorToThrow = error;\n return this;\n }\n\n /**\n * Configure chatWithTools() to return specific tool calls.\n */\n withToolCalls(calls: LLMToolCall[], content = ''): MockLLMBuilder {\n this.toolCallsToReturn = calls;\n this.toolCallResponseContent = content;\n return this;\n }\n\n /**\n * Build the mock ILLM instance. Called automatically by mockLLM().\n */\n build(): MockLLMInstance {\n const calls: LLMCall[] = [];\n const toolCallRecords: LLMToolCallRecord[] = [];\n const rules = this.rules;\n const defaultResponse = this.defaultResponse;\n const streamChunks = this.streamChunks;\n const errorToThrow = this.errorToThrow;\n const toolCallsToReturn = this.toolCallsToReturn;\n const toolCallResponseContent = this.toolCallResponseContent;\n\n function resolveResponse(prompt: string): LLMResponse {\n // Check rules in order\n for (const rule of rules) {\n if (matchesPrompt(rule.matcher, prompt)) {\n return toResponse(rule.response, prompt);\n }\n }\n // Fallback\n return toResponse(defaultResponse, prompt);\n }\n\n const completeFn = vi.fn(async (prompt: string, options?: LLMOptions): Promise<LLMResponse> => {\n if (errorToThrow) {throw errorToThrow;}\n const response = resolveResponse(prompt);\n calls.push({ prompt, options, response });\n return response;\n });\n\n const streamFn = vi.fn(async function* (_prompt: string, _options?: LLMOptions): AsyncIterable<string> {\n if (errorToThrow) {throw errorToThrow;}\n for (const chunk of streamChunks) {\n yield chunk;\n }\n });\n\n const chatWithToolsFn = vi.fn(async (messages: LLMMessage[], options: LLMToolCallOptions): Promise<LLMToolCallResponse> => {\n if (errorToThrow) {throw errorToThrow;}\n\n const lastUserMsg = messages.filter(m => m.role === 'user').pop();\n const prompt = lastUserMsg?.content ?? '';\n const baseResponse = resolveResponse(prompt);\n\n const response: LLMToolCallResponse = {\n ...baseResponse,\n content: toolCallsToReturn.length > 0 ? toolCallResponseContent : baseResponse.content,\n toolCalls: toolCallsToReturn.length > 0 ? toolCallsToReturn : undefined,\n };\n\n toolCallRecords.push({ messages, options, response });\n return response;\n });\n\n const instance: MockLLMInstance = {\n complete: completeFn,\n stream: streamFn,\n chatWithTools: chatWithToolsFn,\n calls,\n toolCalls: toolCallRecords,\n get lastCall() {\n return calls[calls.length - 1];\n },\n resetCalls: () => {\n calls.length = 0;\n toolCallRecords.length = 0;\n completeFn.mockClear();\n streamFn.mockClear();\n chatWithToolsFn.mockClear();\n },\n };\n\n return instance;\n }\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────────\n\nfunction matchesPrompt(matcher: PromptMatcher, prompt: string): boolean {\n if (typeof matcher === 'string') {return prompt.includes(matcher);}\n if (matcher instanceof RegExp) {return matcher.test(prompt);}\n return matcher(prompt);\n}\n\nfunction toResponse(\n value: string | LLMResponse | ((prompt: string) => string | LLMResponse),\n prompt: string,\n): LLMResponse {\n const resolved = typeof value === 'function' ? value(prompt) : value;\n if (typeof resolved === 'string') {\n return {\n content: resolved,\n usage: { promptTokens: 0, completionTokens: 0 },\n model: 'mock',\n };\n }\n return resolved;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Public API\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Create a mock LLM with fluent builder API.\n *\n * @example\n * ```typescript\n * // Simple: always returns same response\n * const llm = mockLLM();\n *\n * // With specific responses\n * const llm = mockLLM()\n * .onComplete('generate commit').respondWith('feat: add feature')\n * .onComplete(/explain/i).respondWith('This code does...')\n * .onAnyComplete().respondWith('default');\n *\n * // Streaming\n * const llm = mockLLM().streaming(['chunk1', 'chunk2', 'chunk3']);\n *\n * // Error simulation\n * const llm = mockLLM().failing(new Error('rate limit exceeded'));\n *\n * // Tool calling\n * const llm = mockLLM().withToolCalls([\n * { id: 'call-1', name: 'search', input: { query: 'test' } },\n * ]);\n * ```\n */\nexport function mockLLM(): MockLLM {\n const builder = new MockLLMBuilder();\n\n // Create a Proxy that acts as both builder and built instance.\n // Builder methods are forwarded to the builder.\n // ILLM methods (complete, stream, etc.) trigger auto-build on first access.\n let built: MockLLMInstance | null = null;\n\n function ensureBuilt(): MockLLMInstance {\n if (!built) {built = builder.build();}\n return built;\n }\n\n const proxy = new Proxy(builder, {\n get(target, prop, _receiver) {\n // Builder methods — return from builder\n if (prop in target && typeof (target as any)[prop] === 'function') {\n const method = (target as any)[prop].bind(target);\n // After calling a builder method, invalidate the built instance\n return (...args: unknown[]) => {\n built = null;\n const result = method(...args);\n // If the result is the builder itself (chaining), return the proxy\n if (result === target || (result && typeof result === 'object' && 'respondWith' in result)) {\n if (result === target) {return proxy;}\n // Wrap respondWith to return proxy\n return {\n respondWith: (...rArgs: unknown[]) => {\n built = null;\n (result as any).respondWith(...rArgs);\n return proxy;\n },\n };\n }\n return result;\n };\n }\n\n // ILLM instance properties — auto-build\n const instance = ensureBuilt();\n // Return functions directly (not bound) to preserve vi.fn() spy identity\n return (instance as any)[prop];\n },\n });\n\n return proxy as unknown as MockLLM;\n}\n","/**\n * @module @kb-labs/shared-testing/mock-cache\n *\n * In-memory cache mock that actually stores data (unlike noop mocks).\n * All methods are vi.fn() spies for assertion.\n *\n * @example\n * ```typescript\n * const cache = mockCache();\n * await cache.set('key', { data: 42 }, 5000);\n * expect(await cache.get('key')).toEqual({ data: 42 });\n * expect(cache.set).toHaveBeenCalledWith('key', { data: 42 }, 5000);\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type { ICache } from '@kb-labs/core-platform';\n\ninterface CacheEntry {\n value: unknown;\n expiresAt: number | null; // null = no TTL\n}\n\ninterface SortedSetMember {\n score: number;\n member: string;\n}\n\n/**\n * Mock cache instance with working in-memory storage.\n * All methods are vi.fn() spies.\n */\nexport interface MockCacheInstance extends ICache {\n /** Direct access to the internal store (for assertions) */\n readonly store: Map<string, CacheEntry>;\n /** Direct access to sorted sets (for assertions) */\n readonly sortedSets: Map<string, SortedSetMember[]>;\n /** Reset all data and spy call history */\n reset: () => void;\n}\n\n/**\n * Create a mock cache with working in-memory storage.\n *\n * Unlike noop mocks, this cache actually stores and retrieves data,\n * respects TTL, and supports sorted set operations.\n *\n * @param initial - Optional initial data to populate the cache\n *\n * @example\n * ```typescript\n * // Empty cache\n * const cache = mockCache();\n *\n * // Pre-populated cache\n * const cache = mockCache({ 'user:1': { name: 'Alice' } });\n *\n * // TTL works\n * await cache.set('temp', 'value', 100); // expires in 100ms\n * await new Promise(r => setTimeout(r, 150));\n * expect(await cache.get('temp')).toBeNull(); // expired\n * ```\n */\nexport function mockCache(initial?: Record<string, unknown>): MockCacheInstance {\n const store = new Map<string, CacheEntry>();\n const sortedSets = new Map<string, SortedSetMember[]>();\n\n // Populate initial data\n if (initial) {\n for (const [key, value] of Object.entries(initial)) {\n store.set(key, { value, expiresAt: null });\n }\n }\n\n function isExpired(entry: CacheEntry): boolean {\n return entry.expiresAt !== null && Date.now() > entry.expiresAt;\n }\n\n // Keep raw vi.fn() references for mockClear() in reset.\n // The ICache-typed versions are cast below for the public interface.\n const spies: ReturnType<typeof vi.fn>[] = [];\n\n function spy<T extends (...args: any[]) => any>(fn: T): T {\n const s = vi.fn(fn) as unknown as T;\n spies.push(s as unknown as ReturnType<typeof vi.fn>);\n return s;\n }\n\n const getFn = spy(async (key: string): Promise<unknown> => {\n const entry = store.get(key);\n if (!entry || isExpired(entry)) {\n if (entry) {store.delete(key);} // cleanup expired\n return null;\n }\n return entry.value;\n });\n\n const setFn = spy(async (key: string, value: unknown, ttl?: number): Promise<void> => {\n store.set(key, {\n value,\n expiresAt: ttl ? Date.now() + ttl : null,\n });\n });\n\n const deleteFn = spy(async (key: string): Promise<void> => {\n store.delete(key);\n });\n\n const clearFn = spy(async (pattern?: string): Promise<void> => {\n if (!pattern) {\n store.clear();\n return;\n }\n // Simple glob matching: only support trailing *\n const prefix = pattern.replace(/\\*$/, '');\n for (const key of store.keys()) {\n if (key.startsWith(prefix)) {\n store.delete(key);\n }\n }\n });\n\n const zaddFn = spy(async (key: string, score: number, member: string): Promise<void> => {\n if (!sortedSets.has(key)) {sortedSets.set(key, []);}\n const set = sortedSets.get(key)!;\n // Remove existing member\n const idx = set.findIndex(m => m.member === member);\n if (idx >= 0) {set.splice(idx, 1);}\n // Add with new score\n set.push({ score, member });\n // Keep sorted by score\n set.sort((a, b) => a.score - b.score);\n });\n\n const zrangebyscoreFn = spy(async (key: string, min: number, max: number): Promise<string[]> => {\n const set = sortedSets.get(key);\n if (!set) {return [];}\n return set\n .filter(m => m.score >= min && m.score <= max)\n .map(m => m.member);\n });\n\n const zremFn = spy(async (key: string, member: string): Promise<void> => {\n const set = sortedSets.get(key);\n if (!set) {return;}\n const idx = set.findIndex(m => m.member === member);\n if (idx >= 0) {set.splice(idx, 1);}\n });\n\n const setIfNotExistsFn = spy(async (key: string, value: unknown, ttl?: number): Promise<boolean> => {\n const existing = store.get(key);\n if (existing && !isExpired(existing)) {return false;}\n store.set(key, {\n value,\n expiresAt: ttl ? Date.now() + ttl : null,\n });\n return true;\n });\n\n const instance: MockCacheInstance = {\n get: getFn as unknown as ICache['get'],\n set: setFn as unknown as ICache['set'],\n delete: deleteFn,\n clear: clearFn,\n zadd: zaddFn,\n zrangebyscore: zrangebyscoreFn,\n zrem: zremFn,\n setIfNotExists: setIfNotExistsFn as unknown as ICache['setIfNotExists'],\n get store() { return store; },\n get sortedSets() { return sortedSets; },\n reset: () => {\n store.clear();\n sortedSets.clear();\n for (const s of spies) {s.mockClear();}\n },\n };\n\n return instance;\n}\n","/**\n * @module @kb-labs/shared-testing/mock-storage\n *\n * Virtual filesystem mock for IStorage interface.\n * All methods are vi.fn() spies.\n *\n * @example\n * ```typescript\n * const storage = mockStorage({\n * 'config.json': '{\"key\": \"value\"}',\n * 'data/file.txt': 'hello world',\n * });\n *\n * const content = await storage.read('config.json');\n * expect(content?.toString()).toBe('{\"key\": \"value\"}');\n * expect(storage.read).toHaveBeenCalledWith('config.json');\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type { IStorage } from '@kb-labs/core-platform';\n\n/**\n * Mock storage instance with in-memory virtual filesystem.\n */\nexport interface MockStorageInstance extends IStorage {\n /** Direct access to the virtual filesystem (for assertions) */\n readonly files: Map<string, Buffer>;\n /** Reset all files and spy call history */\n reset: () => void;\n}\n\n/**\n * Create a mock storage with in-memory virtual filesystem.\n *\n * @param initial - Optional initial files. Keys are paths, values are content (string or Buffer).\n *\n * @example\n * ```typescript\n * const storage = mockStorage({\n * 'data.json': JSON.stringify({ items: [] }),\n * 'binary.dat': Buffer.from([0x00, 0x01]),\n * });\n *\n * // Write and read\n * await storage.write('new.txt', Buffer.from('hello'));\n * expect(await storage.exists('new.txt')).toBe(true);\n *\n * // List files\n * const files = await storage.list('');\n * expect(files).toContain('new.txt');\n * ```\n */\nexport function mockStorage(initial?: Record<string, string | Buffer>): MockStorageInstance {\n const files = new Map<string, Buffer>();\n\n // Populate initial files\n if (initial) {\n for (const [path, content] of Object.entries(initial)) {\n files.set(path, typeof content === 'string' ? Buffer.from(content) : content);\n }\n }\n\n const readFn = vi.fn(async (path: string): Promise<Buffer | null> => {\n return files.get(path) ?? null;\n });\n\n const writeFn = vi.fn(async (path: string, data: Buffer): Promise<void> => {\n files.set(path, data);\n });\n\n const deleteFn = vi.fn(async (path: string): Promise<void> => {\n files.delete(path);\n });\n\n const listFn = vi.fn(async (prefix: string): Promise<string[]> => {\n const result: string[] = [];\n for (const path of files.keys()) {\n if (path.startsWith(prefix)) {\n result.push(path);\n }\n }\n return result.sort();\n });\n\n const existsFn = vi.fn(async (path: string): Promise<boolean> => {\n return files.has(path);\n });\n\n const instance: MockStorageInstance = {\n read: readFn,\n write: writeFn,\n delete: deleteFn,\n list: listFn,\n exists: existsFn,\n get files() { return files; },\n reset: () => {\n files.clear();\n readFn.mockClear();\n writeFn.mockClear();\n deleteFn.mockClear();\n listFn.mockClear();\n existsFn.mockClear();\n },\n };\n\n return instance;\n}\n","/**\n * @module @kb-labs/shared-testing/mock-logger\n *\n * Logger mock with message recording and vi.fn() spies.\n *\n * @example\n * ```typescript\n * const logger = mockLogger();\n * logger.info('hello', { extra: 'data' });\n * logger.error('oops', new Error('fail'));\n *\n * expect(logger.messages).toEqual([\n * { level: 'info', msg: 'hello', meta: { extra: 'data' } },\n * { level: 'error', msg: 'oops', error: expect.any(Error), meta: undefined },\n * ]);\n * expect(logger.info).toHaveBeenCalledWith('hello', { extra: 'data' });\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type { ILogger } from '@kb-labs/core-platform';\n\n/** Recorded log entry */\nexport interface LogEntry {\n level: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n msg: string;\n error?: Error;\n meta?: Record<string, unknown>;\n}\n\n/**\n * Mock logger instance with message recording.\n */\nexport interface MockLoggerInstance extends ILogger {\n /** All recorded log messages */\n readonly messages: LogEntry[];\n /** Reset messages and spy call history */\n reset: () => void;\n}\n\n/**\n * Create a mock logger with message recording.\n *\n * All log methods are vi.fn() spies. Messages are collected\n * into a `.messages` array for easy assertion.\n *\n * Child loggers share the same messages array.\n *\n * @example\n * ```typescript\n * const logger = mockLogger();\n * const child = logger.child({ module: 'auth' });\n *\n * child.info('user logged in');\n * expect(logger.messages).toHaveLength(1);\n * expect(logger.messages[0].msg).toBe('user logged in');\n * ```\n */\nexport function mockLogger(sharedMessages?: LogEntry[]): MockLoggerInstance {\n const messages: LogEntry[] = sharedMessages ?? [];\n\n // trace, debug, info, warn: (message, meta?)\n function createSimpleLogMethod(level: LogEntry['level']) {\n return vi.fn((msg: string, meta?: Record<string, unknown>) => {\n messages.push({ level, msg, meta });\n });\n }\n\n // error, fatal: (message, error?, meta?)\n function createErrorLogMethod(level: 'error' | 'fatal') {\n return vi.fn((msg: string, error?: Error, meta?: Record<string, unknown>) => {\n messages.push({ level, msg, error, meta });\n });\n }\n\n const instance: MockLoggerInstance = {\n trace: createSimpleLogMethod('trace'),\n debug: createSimpleLogMethod('debug'),\n info: createSimpleLogMethod('info'),\n warn: createSimpleLogMethod('warn'),\n error: createErrorLogMethod('error'),\n fatal: createErrorLogMethod('fatal'),\n child: (_bindings?: Record<string, unknown>) => mockLogger(messages),\n get messages() { return messages; },\n reset: () => {\n messages.length = 0;\n (instance.trace as ReturnType<typeof vi.fn>).mockClear();\n (instance.debug as ReturnType<typeof vi.fn>).mockClear();\n (instance.info as ReturnType<typeof vi.fn>).mockClear();\n (instance.warn as ReturnType<typeof vi.fn>).mockClear();\n (instance.error as ReturnType<typeof vi.fn>).mockClear();\n (instance.fatal as ReturnType<typeof vi.fn>).mockClear();\n },\n };\n\n return instance;\n}\n","/**\n * @module @kb-labs/shared-testing/create-test-context\n *\n * Enhanced test context factory that bridges ctx.platform and the global singleton.\n *\n * Unlike the original createTestContext() from SDK, this version:\n * - Uses mockLLM/mockCache/mockLogger with vi.fn() spies (not noop functions)\n * - Syncs ctx.platform adapters with the global singleton via setupTestPlatform()\n * - Provides a cleanup function to reset the singleton in afterEach()\n *\n * @example\n * ```typescript\n * import { createTestContext, mockLLM } from '@kb-labs/shared-testing';\n *\n * const llm = mockLLM().onAnyComplete().respondWith('hello');\n * const { ctx, cleanup } = createTestContext({ platform: { llm } });\n *\n * // Both work — ctx.platform and useLLM() return the same mock\n * await handler.execute(ctx, args);\n * expect(llm.complete).toHaveBeenCalled();\n *\n * cleanup(); // Reset singleton in afterEach\n * ```\n */\n\nimport type {\n PluginContextV3,\n HostContext,\n PlatformServices,\n UIFacade,\n TraceContext,\n RuntimeAPI,\n PluginAPI,\n FSShim,\n FetchShim,\n EnvShim,\n InvokeAPI,\n EnvironmentAPI,\n WorkspaceAPI,\n SnapshotAPI,\n} from '@kb-labs/plugin-contracts';\n\nimport { setupTestPlatform } from './setup-platform.js';\nimport { mockLLM } from './mock-llm.js';\nimport { mockCache } from './mock-cache.js';\nimport { mockStorage } from './mock-storage.js';\nimport { mockLogger } from './mock-logger.js';\nimport { vi } from 'vitest';\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\nexport interface CreateTestContextOptions {\n pluginId?: string;\n pluginVersion?: string;\n host?: 'cli' | 'rest' | 'workflow' | 'webhook';\n hostContext?: HostContext;\n config?: unknown;\n cwd?: string;\n outdir?: string;\n tenantId?: string;\n signal?: AbortSignal;\n /** Override platform services. Also synced to global singleton. */\n platform?: Partial<PlatformServices>;\n /** Override UI facade */\n ui?: Partial<UIFacade>;\n /**\n * If true, sync platform adapters to the global singleton\n * so that useLLM(), useCache(), etc. return the test mocks.\n * @default true\n */\n syncSingleton?: boolean;\n}\n\nexport interface TestContextResult<TConfig = unknown> {\n /** The plugin context with test mocks */\n ctx: PluginContextV3<TConfig>;\n /** Call in afterEach() to reset the global singleton */\n cleanup: () => void;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Mock factories\n// ────────────────────────────────────────────────────────────────────\n\nexport function createMockTrace(): TraceContext {\n return {\n traceId: 'test-trace-id',\n spanId: 'test-span-id',\n parentSpanId: undefined,\n addEvent: () => {},\n setAttribute: () => {},\n recordError: () => {},\n };\n}\n\nexport function createMockUI(): UIFacade {\n const messages: string[] = [];\n\n const mockColor = (text: string) => text;\n const mockColors = {\n success: mockColor,\n error: mockColor,\n warning: mockColor,\n info: mockColor,\n primary: mockColor,\n accent: mockColor,\n highlight: mockColor,\n secondary: mockColor,\n emphasis: mockColor,\n muted: mockColor,\n foreground: mockColor,\n dim: mockColor,\n bold: mockColor,\n underline: mockColor,\n inverse: mockColor,\n };\n\n return {\n colors: mockColors,\n symbols: {\n success: '+',\n error: 'x',\n warning: '!',\n info: 'i',\n bullet: '-',\n clock: 'T',\n folder: 'D',\n package: 'P',\n pointer: '>',\n section: '#',\n separator: '-',\n border: '|',\n topLeft: '+',\n topRight: '+',\n bottomLeft: '+',\n bottomRight: '+',\n leftT: '+',\n rightT: '+',\n },\n write: vi.fn((text) => messages.push(`WRITE: ${text}`)),\n info: vi.fn((msg) => messages.push(`INFO: ${msg}`)),\n success: vi.fn((msg) => messages.push(`SUCCESS: ${msg}`)),\n warn: vi.fn((msg) => messages.push(`WARN: ${msg}`)),\n error: vi.fn((err) => messages.push(`ERROR: ${err instanceof Error ? err.message : err}`)),\n debug: vi.fn((msg) => messages.push(`DEBUG: ${msg}`)),\n spinner: vi.fn((msg) => {\n messages.push(`SPINNER: ${msg}`);\n return {\n update: vi.fn((m: string) => messages.push(`SPINNER UPDATE: ${m}`)),\n succeed: vi.fn((m?: string) => messages.push(`SPINNER SUCCEED: ${m ?? msg}`)),\n fail: vi.fn((m?: string) => messages.push(`SPINNER FAIL: ${m ?? msg}`)),\n stop: vi.fn(),\n };\n }),\n table: vi.fn((data) => messages.push(`TABLE: ${JSON.stringify(data)}`)),\n json: vi.fn((data) => messages.push(`JSON: ${JSON.stringify(data)}`)),\n newline: vi.fn(() => messages.push('')),\n divider: vi.fn(() => messages.push('-'.repeat(40))),\n box: vi.fn((content, title) => {\n if (title) {messages.push(`+- ${title} -+`);}\n messages.push(content);\n if (title) {messages.push(`+${'-'.repeat(title.length + 4)}+`);}\n }),\n sideBox: vi.fn((options) => {\n messages.push(`+- ${options.title} -+`);\n if (options.summary) {\n Object.entries(options.summary).forEach(([key, value]) => {\n messages.push(` ${key}: ${value}`);\n });\n }\n if (options.sections) {\n options.sections.forEach((section: any) => {\n if (section.header) {messages.push(` ${section.header}:`);}\n section.items.forEach((item: string) => messages.push(` ${item}`));\n });\n }\n if (options.timing) {\n messages.push(` Timing: ${options.timing}ms`);\n }\n messages.push('+' + '-'.repeat(options.title.length + 4) + '+');\n }),\n confirm: vi.fn(async () => true),\n prompt: vi.fn(async () => ''),\n };\n}\n\nexport function createMockRuntime(): RuntimeAPI {\n const mockFS: FSShim = {\n readFile: vi.fn(async () => ''),\n readFileBuffer: vi.fn(async () => new Uint8Array()),\n writeFile: vi.fn(async () => {}),\n readdir: vi.fn(async () => []),\n readdirWithStats: vi.fn(async () => []),\n mkdir: vi.fn(async () => {}),\n rm: vi.fn(async () => {}),\n copy: vi.fn(async () => {}),\n move: vi.fn(async () => {}),\n glob: vi.fn(async () => []),\n stat: vi.fn(async () => ({\n isFile: () => false,\n isDirectory: () => false,\n size: 0,\n mtime: Date.now(),\n ctime: Date.now(),\n })),\n exists: vi.fn(async () => false),\n resolve: (path: string) => path,\n relative: (path: string) => path,\n join: (...segments: string[]) => segments.join('/'),\n dirname: (path: string) => path.split('/').slice(0, -1).join('/'),\n basename: (path: string) => path.split('/').pop() ?? '',\n extname: (path: string) => {\n const base = path.split('/').pop() ?? '';\n const idx = base.lastIndexOf('.');\n return idx > 0 ? base.slice(idx) : '';\n },\n };\n\n const mockFetch: FetchShim = vi.fn(async () => new Response('mock'));\n const mockEnv: EnvShim = vi.fn((_key: string) => undefined) as EnvShim;\n\n return {\n fs: mockFS,\n fetch: mockFetch,\n env: mockEnv,\n };\n}\n\nexport function createMockEnvironmentAPI(): EnvironmentAPI {\n return {\n create: vi.fn(async () => ({\n environmentId: 'env_mock_1',\n provider: 'mock',\n status: 'ready' as const,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n })),\n status: vi.fn(async (environmentId: string) => ({\n environmentId,\n status: 'ready' as const,\n updatedAt: new Date().toISOString(),\n })),\n destroy: vi.fn(async () => {}),\n renewLease: vi.fn(async () => ({\n leaseId: 'lease_mock_1',\n acquiredAt: new Date().toISOString(),\n expiresAt: new Date(Date.now() + 10 * 60 * 1000).toISOString(),\n })),\n };\n}\n\nexport function createMockWorkspaceAPI(): WorkspaceAPI {\n return {\n materialize: vi.fn(async () => ({\n workspaceId: 'ws_mock_1',\n provider: 'mock',\n status: 'ready' as const,\n rootPath: '/tmp/ws_mock_1',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n })),\n attach: vi.fn(async (request) => ({\n workspaceId: request.workspaceId,\n environmentId: request.environmentId,\n mountPath: request.mountPath ?? '/workspace',\n attachedAt: new Date().toISOString(),\n })),\n release: vi.fn(async () => {}),\n status: vi.fn(async (workspaceId: string) => ({\n workspaceId,\n status: 'ready' as const,\n updatedAt: new Date().toISOString(),\n })),\n };\n}\n\nexport function createMockSnapshotAPI(): SnapshotAPI {\n return {\n capture: vi.fn(async (request) => ({\n snapshotId: request.snapshotId ?? 'snap_mock_1',\n provider: 'mock',\n status: 'ready' as const,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n workspaceId: request.workspaceId,\n environmentId: request.environmentId,\n })),\n restore: vi.fn(async (request) => ({\n snapshotId: request.snapshotId,\n restoredAt: new Date().toISOString(),\n workspaceId: request.workspaceId,\n environmentId: request.environmentId,\n targetPath: request.targetPath,\n })),\n status: vi.fn(async (snapshotId: string) => ({\n snapshotId,\n status: 'ready' as const,\n updatedAt: new Date().toISOString(),\n })),\n delete: vi.fn(async () => {}),\n gc: vi.fn(async (request) => ({\n scanned: 0,\n deleted: 0,\n dryRun: request?.dryRun ?? false,\n })),\n };\n}\n\nexport function createInfraApiMocks(): Pick<PluginAPI, 'environment' | 'workspace' | 'snapshot'> {\n return {\n environment: createMockEnvironmentAPI(),\n workspace: createMockWorkspaceAPI(),\n snapshot: createMockSnapshotAPI(),\n };\n}\n\nexport function createMockPluginAPI(): PluginAPI {\n const infra = createInfraApiMocks();\n return {\n lifecycle: {\n onCleanup: vi.fn(),\n },\n state: {\n get: vi.fn(async () => undefined),\n set: vi.fn(async () => {}),\n delete: vi.fn(async () => {}),\n has: vi.fn(async () => false),\n getMany: vi.fn(async () => new Map()),\n setMany: vi.fn(async () => {}),\n },\n artifacts: {\n write: vi.fn(async () => '/mock/path'),\n list: vi.fn(async () => []),\n read: vi.fn(async () => ''),\n readBuffer: vi.fn(async () => new Uint8Array()),\n exists: vi.fn(async () => false),\n path: vi.fn(() => '/mock/path'),\n },\n shell: {\n exec: vi.fn(async () => ({ code: 0, stdout: '', stderr: '', ok: true })),\n },\n events: {\n emit: vi.fn(async () => {}),\n },\n invoke: {\n call: vi.fn(async (_pluginId: string, _input?: unknown, _options?: unknown) => undefined) as InvokeAPI['call'],\n },\n workflows: {\n run: vi.fn(async () => 'mock-run-id'),\n wait: vi.fn(async () => undefined),\n status: vi.fn(async () => null),\n cancel: vi.fn(async () => {}),\n list: vi.fn(async () => []),\n },\n jobs: {\n submit: vi.fn(async () => 'mock-job-id'),\n schedule: vi.fn(async () => 'mock-scheduled-job-id'),\n wait: vi.fn(async () => undefined),\n status: vi.fn(async () => null),\n cancel: vi.fn(async () => false),\n list: vi.fn(async () => []),\n },\n cron: {\n register: vi.fn(async () => {}),\n unregister: vi.fn(async () => {}),\n list: vi.fn(async () => []),\n pause: vi.fn(async () => {}),\n resume: vi.fn(async () => {}),\n trigger: vi.fn(async () => {}),\n },\n environment: infra.environment,\n workspace: infra.workspace,\n snapshot: infra.snapshot,\n };\n}\n\nexport const createMockPlatformApi = createMockPluginAPI;\n\nexport function createMockPluginContextV3<TConfig = unknown>(\n options: CreateTestContextOptions = {}\n): TestContextResult<TConfig> {\n return createTestContext<TConfig>(options);\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Public API\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Create a test context for plugin development.\n *\n * Unlike the original SDK version, this:\n * - Uses mock builders with vi.fn() spies (not noop functions)\n * - Syncs platform adapters to the global singleton by default\n * - Returns a cleanup function for afterEach()\n *\n * @example\n * ```typescript\n * import { createTestContext, mockLLM } from '@kb-labs/shared-testing';\n *\n * describe('my handler', () => {\n * let cleanup: () => void;\n *\n * beforeEach(() => {\n * const llm = mockLLM().onAnyComplete().respondWith('ok');\n * const result = createTestContext({ platform: { llm } });\n * cleanup = result.cleanup;\n * // Use result.ctx in your tests\n * });\n *\n * afterEach(() => cleanup());\n * });\n * ```\n */\nexport function createTestContext<TConfig = unknown>(\n options: CreateTestContextOptions = {}\n): TestContextResult<TConfig> {\n const {\n pluginId = 'test-plugin',\n pluginVersion = '0.0.0',\n host = 'cli',\n hostContext,\n config,\n cwd = process.cwd(),\n outdir,\n tenantId,\n signal,\n platform: platformOverrides,\n ui: uiOverrides,\n syncSingleton = true,\n } = options;\n\n const resolvedOutdir = outdir ?? `${cwd}/.kb/output`;\n\n // Build default host context\n const defaultHostContext: HostContext =\n hostContext ??\n (() => {\n switch (host) {\n case 'cli':\n return { host: 'cli', argv: ['test'], flags: {} };\n case 'rest':\n return {\n host: 'rest',\n method: 'GET',\n path: '/test',\n requestId: 'test-req-001',\n traceId: 'test-trace-001',\n };\n case 'workflow':\n return { host: 'workflow', workflowId: 'test-wf', runId: 'test-run', stepId: 'test-step' };\n case 'webhook':\n return { host: 'webhook', event: 'test:event' };\n }\n })();\n\n // Create default mocks (with spies, not noop)\n const defaultLogger = mockLogger();\n const defaultLLM = mockLLM();\n const defaultCache = mockCache();\n const defaultStorage = mockStorage();\n\n const defaultPlatform: PlatformServices = {\n logger: defaultLogger,\n llm: defaultLLM,\n embeddings: {\n embed: vi.fn(async () => []),\n embedBatch: vi.fn(async () => [[]]),\n dimensions: 1536,\n getDimensions: vi.fn(async () => 1536),\n },\n vectorStore: {\n search: vi.fn(async () => []),\n upsert: vi.fn(async () => {}),\n delete: vi.fn(async () => {}),\n count: vi.fn(async () => 0),\n },\n cache: defaultCache,\n storage: defaultStorage,\n analytics: {\n track: vi.fn(async () => {}),\n identify: vi.fn(async () => {}),\n flush: vi.fn(async () => {}),\n },\n eventBus: {\n publish: vi.fn(async () => {}),\n subscribe: vi.fn(() => () => {}),\n },\n config: {\n getConfig: vi.fn(async () => ({})),\n getRawConfig: vi.fn(async () => ({})),\n },\n invoke: {\n call: vi.fn(async () => ({ success: true, data: null })),\n isAvailable: vi.fn(async () => false),\n } as PlatformServices['invoke'],\n sqlDatabase: {\n query: vi.fn(async () => ({ rows: [], rowCount: 0 })),\n transaction: vi.fn(async () => ({ query: vi.fn(), commit: vi.fn(), rollback: vi.fn() })),\n close: vi.fn(async () => {}),\n },\n documentDatabase: {\n find: vi.fn(async () => []),\n findById: vi.fn(async () => null),\n insertOne: vi.fn(async () => ({ id: 'mock', createdAt: 0, updatedAt: 0 })),\n updateMany: vi.fn(async () => 0),\n updateById: vi.fn(async () => null),\n deleteMany: vi.fn(async () => 0),\n deleteById: vi.fn(async () => false),\n count: vi.fn(async () => 0),\n close: vi.fn(async () => {}),\n } as PlatformServices['documentDatabase'],\n logs: {\n query: vi.fn(async () => ({ logs: [], total: 0, hasMore: false, source: 'buffer' as const })),\n getById: vi.fn(async () => null),\n search: vi.fn(async () => ({ logs: [], total: 0, hasMore: false })),\n subscribe: vi.fn(() => () => {}),\n getStats: vi.fn(async () => ({})),\n getCapabilities: vi.fn(() => ({ hasBuffer: false, hasPersistence: false, hasSearch: false, hasStreaming: false })),\n },\n };\n\n // Merge overrides\n const finalPlatform: PlatformServices = {\n ...defaultPlatform,\n ...platformOverrides,\n };\n\n // Sync to global singleton\n let cleanupFn = () => {};\n if (syncSingleton) {\n const result = setupTestPlatform({\n llm: finalPlatform.llm,\n cache: finalPlatform.cache,\n storage: finalPlatform.storage,\n logger: finalPlatform.logger,\n analytics: finalPlatform.analytics,\n embeddings: finalPlatform.embeddings,\n vectorStore: finalPlatform.vectorStore,\n eventBus: finalPlatform.eventBus,\n });\n cleanupFn = result.cleanup;\n }\n\n // UI\n const defaultUI = createMockUI();\n const finalUI: UIFacade = {\n ...defaultUI,\n ...uiOverrides,\n };\n\n // Build context\n const ctx: PluginContextV3<TConfig> = {\n host,\n requestId: 'test-trace:test-span',\n pluginId,\n pluginVersion,\n tenantId,\n cwd,\n outdir: resolvedOutdir,\n config: config as TConfig,\n signal,\n trace: createMockTrace(),\n hostContext: defaultHostContext,\n ui: finalUI,\n platform: finalPlatform,\n runtime: createMockRuntime(),\n api: createMockPluginAPI(),\n };\n\n return { ctx, cleanup: cleanupFn };\n}\n","/**\n * @module @kb-labs/shared-testing/test-command\n *\n * Single-function test runner for plugin command handlers.\n *\n * Eliminates boilerplate: no manual context creation, no descriptor setup,\n * no mock wiring. Import your handler, call testCommand(), assert on result.\n *\n * @example\n * ```typescript\n * import { testCommand, mockLLM } from '@kb-labs/shared-testing';\n * import handler from '../src/commands/greet.js';\n *\n * it('greets the user', async () => {\n * const result = await testCommand(handler, {\n * flags: { name: 'Alice' },\n * });\n *\n * expect(result.exitCode).toBe(0);\n * expect(result.result).toEqual({ message: 'Hello, Alice!' });\n * expect(result.ui.success).toHaveBeenCalledWith('Hello, Alice!');\n * });\n * ```\n */\n\nimport type {\n PluginContextV3,\n CommandResult,\n UIFacade,\n PlatformServices,\n} from '@kb-labs/plugin-contracts';\n\nimport {\n createTestContext,\n type CreateTestContextOptions,\n} from './create-test-context.js';\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Any handler that has an execute(ctx, input) method.\n * Covers CommandHandlerV3, RouteHandler, Handler, and raw objects.\n */\nexport interface TestableHandler<TConfig = unknown, TInput = unknown, TResult = unknown> {\n execute(\n context: PluginContextV3<TConfig>,\n input: TInput\n ): Promise<TResult> | TResult;\n cleanup?(): Promise<void> | void;\n}\n\n/**\n * Options for testCommand().\n *\n * Provide only what you need — everything else gets sensible defaults.\n */\nexport interface TestCommandOptions<TConfig = unknown> {\n // ── Input ──────────────────────────────────────────────────────\n\n /** CLI flags (sugar for input: { flags, argv }) */\n flags?: Record<string, unknown>;\n\n /** CLI positional arguments (default: []) */\n argv?: string[];\n\n /** REST query params (sugar for input: { query }) */\n query?: Record<string, unknown>;\n\n /** REST request body (sugar for input: { body }) */\n body?: unknown;\n\n /** REST route params (sugar for input: { params }) */\n params?: Record<string, unknown>;\n\n /**\n * Raw input object. If provided, flags/argv/query/body/params are ignored.\n * Use this when your handler expects a custom input shape.\n */\n input?: unknown;\n\n // ── Context ────────────────────────────────────────────────────\n\n /** Host type (default: 'cli') */\n host?: 'cli' | 'rest' | 'workflow' | 'webhook';\n\n /** Plugin config passed as ctx.config */\n config?: TConfig;\n\n /** Working directory (default: process.cwd()) */\n cwd?: string;\n\n /** Tenant ID */\n tenantId?: string;\n\n /** Abort signal */\n signal?: AbortSignal;\n\n // ── Mocks ──────────────────────────────────────────────────────\n\n /** Override platform services (e.g., { llm: mockLLM().onAnyComplete().respondWith('ok') }) */\n platform?: Partial<PlatformServices>;\n\n /** Override UI facade (individual methods are merged with default spy UI) */\n ui?: Partial<UIFacade>;\n\n /**\n * Sync platform mocks to global singleton for composables (useLLM, useCache, etc.)\n * @default true\n */\n syncSingleton?: boolean;\n}\n\n/**\n * Result of testCommand() — everything you need for assertions.\n */\nexport interface TestCommandResult<TResult = unknown> {\n /** Exit code from CommandResult (0 = success). Defaults to 0 if handler returns raw data. */\n exitCode: number;\n\n /** The result data from the handler */\n result: TResult | undefined;\n\n /** Custom metadata from CommandResult.meta */\n meta: Record<string, unknown> | undefined;\n\n /** The raw return value from handler.execute() — useful for non-CommandResult handlers */\n raw: unknown;\n\n /** UI facade with vi.fn() spies — assert on ui.success, ui.error, etc. */\n ui: UIFacade;\n\n /** The full context that was passed to the handler */\n ctx: PluginContextV3;\n\n /** Call in afterEach() to reset the global platform singleton */\n cleanup: () => void;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Implementation\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Test a plugin command handler with minimal boilerplate.\n *\n * Creates a test context, builds the input object, calls handler.execute(),\n * and returns a result with UI spies for assertions.\n *\n * @example CLI command\n * ```typescript\n * import handler from '../src/commands/greet.js';\n *\n * const result = await testCommand(handler, {\n * flags: { name: 'Alice' },\n * });\n * expect(result.exitCode).toBe(0);\n * expect(result.ui.success).toHaveBeenCalledWith('Hello, Alice!');\n * ```\n *\n * @example REST handler\n * ```typescript\n * import handler from '../src/routes/create-plan.js';\n *\n * const result = await testCommand(handler, {\n * host: 'rest',\n * body: { name: 'v2.0' },\n * query: { workspace: 'root' },\n * });\n * expect(result.result).toMatchObject({ name: 'v2.0' });\n * ```\n *\n * @example With LLM mock\n * ```typescript\n * import { testCommand, mockLLM } from '@kb-labs/shared-testing';\n * import handler from '../src/commands/analyze.js';\n *\n * const llm = mockLLM().onAnyComplete().respondWith('looks good');\n * const result = await testCommand(handler, {\n * flags: { file: 'index.ts' },\n * platform: { llm },\n * });\n * expect(llm.complete).toHaveBeenCalled();\n * expect(result.exitCode).toBe(0);\n * ```\n */\nexport async function testCommand<TResult = unknown, TConfig = unknown>(\n handler: TestableHandler<TConfig, any, any>,\n options: TestCommandOptions<TConfig> = {}\n): Promise<TestCommandResult<TResult>> {\n const {\n flags,\n argv = [],\n query,\n body,\n params,\n input: rawInput,\n host = 'cli',\n config,\n cwd,\n tenantId,\n signal,\n platform,\n ui,\n syncSingleton = true,\n } = options;\n\n // ── Build context ──────────────────────────────────────────────\n\n const ctxOptions: CreateTestContextOptions = {\n host,\n config,\n cwd,\n tenantId,\n signal,\n platform,\n ui,\n syncSingleton,\n };\n\n const { ctx, cleanup } = createTestContext<TConfig>(ctxOptions);\n\n // ── Build input ────────────────────────────────────────────────\n\n let input: unknown;\n\n if (rawInput !== undefined) {\n // Explicit raw input takes precedence\n input = rawInput;\n } else if (host === 'rest') {\n // REST handlers expect { query?, body?, params? }\n input = {\n ...(query !== undefined ? { query } : {}),\n ...(body !== undefined ? { body } : {}),\n ...(params !== undefined ? { params } : {}),\n };\n } else {\n // CLI/workflow handlers expect { flags, argv }\n input = { flags: flags ?? {}, argv };\n }\n\n // ── Execute ────────────────────────────────────────────────────\n\n let raw: unknown;\n try {\n raw = await handler.execute(ctx as PluginContextV3<TConfig>, input as any);\n } finally {\n // Call cleanup if handler has one\n await handler.cleanup?.();\n }\n\n // ── Normalize result ───────────────────────────────────────────\n\n // Handler may return CommandResult<T>, void, or raw data.\n // Detect by checking for exitCode property.\n let exitCode = 0;\n let result: TResult | undefined;\n let meta: Record<string, unknown> | undefined;\n\n if (raw != null && typeof raw === 'object' && 'exitCode' in raw) {\n // CommandResult shape\n const cmdResult = raw as CommandResult<TResult>;\n exitCode = cmdResult.exitCode;\n result = cmdResult.result;\n meta = cmdResult.meta;\n } else if (raw === undefined || raw === null) {\n // void return (RouteHandler can return void)\n exitCode = 0;\n result = undefined;\n meta = undefined;\n } else {\n // Raw data (Handler from defineHandler returns data directly)\n exitCode = 0;\n result = raw as TResult;\n meta = undefined;\n }\n\n return {\n exitCode,\n result,\n meta,\n raw,\n ui: ctx.ui,\n ctx: ctx as PluginContextV3,\n cleanup,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/setup-platform.ts","../src/mock-llm.ts","../src/mock-cache.ts","../src/mock-storage.ts","../src/mock-logger.ts","../src/create-test-context.ts","../src/test-command.ts"],"names":["vi","platform"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/shared-testing/setup-platform\n *\n * Solves the \"singleton gap\" problem: composables (useLLM, useCache, etc.)\n * read from the global platform singleton, but createTestContext() only\n * populates ctx.platform. This module bridges the gap by setting test mocks\n * directly into the global singleton.\n */\n\nimport { platform, resetPlatform } from '@kb-labs/core-runtime';\nimport type {\n ILLM,\n ICache,\n IEmbeddings,\n IVectorStore,\n IStorage,\n IAnalytics,\n ILogger,\n IEventBus,\n} from '@kb-labs/core-platform';\n\n/**\n * Options for setting up the test platform.\n * Only adapters that are provided will be registered.\n * Omitted adapters will use the PlatformContainer's built-in fallbacks.\n */\nexport interface TestPlatformOptions {\n llm?: ILLM;\n cache?: ICache;\n embeddings?: IEmbeddings;\n vectorStore?: IVectorStore;\n storage?: IStorage;\n analytics?: IAnalytics;\n logger?: ILogger;\n eventBus?: IEventBus;\n}\n\nexport interface TestPlatformResult {\n /** The global platform singleton (with test mocks applied) */\n platform: typeof platform;\n /** Call in afterEach() to reset the singleton to a clean state */\n cleanup: () => void;\n}\n\n/**\n * Setup the global platform singleton with test mocks.\n *\n * This ensures that useLLM(), useCache() and other composables\n * return the test mocks instead of uninitialized/stale adapters.\n *\n * @example\n * ```typescript\n * import { setupTestPlatform, mockLLM } from '@kb-labs/shared-testing';\n *\n * describe('my handler', () => {\n * let cleanup: () => void;\n *\n * beforeEach(() => {\n * const result = setupTestPlatform({\n * llm: mockLLM().onAnyComplete().respondWith('hello'),\n * });\n * cleanup = result.cleanup;\n * });\n *\n * afterEach(() => cleanup());\n *\n * it('uses LLM', async () => {\n * const llm = useLLM(); // Returns the test mock!\n * const res = await llm!.complete('test');\n * expect(res.content).toBe('hello');\n * });\n * });\n * ```\n */\nexport function setupTestPlatform(options: TestPlatformOptions = {}): TestPlatformResult {\n // Reset everything first — clean slate\n resetPlatform();\n\n // Register provided adapters into the global singleton\n const adapterMap: Array<[string, unknown]> = [\n ['llm', options.llm],\n ['cache', options.cache],\n ['embeddings', options.embeddings],\n ['vectorStore', options.vectorStore],\n ['storage', options.storage],\n ['analytics', options.analytics],\n ['logger', options.logger],\n ['eventBus', options.eventBus],\n ];\n\n for (const [key, instance] of adapterMap) {\n if (instance !== undefined) {\n platform.setAdapter(key, instance);\n }\n }\n\n return {\n platform,\n cleanup: () => resetPlatform(),\n };\n}\n","/**\n * @module @kb-labs/shared-testing/mock-llm\n *\n * LLM mock builder with fluent API and call tracking.\n *\n * @example\n * ```typescript\n * const llm = mockLLM()\n * .onComplete('Generate commit').respondWith('feat: add login')\n * .onComplete(/explain/i).respondWith('This function does X')\n * .onAnyComplete().respondWith('default answer');\n *\n * const res = await llm.complete('Generate commit message');\n * expect(res.content).toBe('feat: add login');\n * expect(llm.complete).toHaveBeenCalledOnce();\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMToolCall,\n} from '@kb-labs/core-platform';\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\n/** Recorded call to complete() */\nexport interface LLMCall {\n prompt: string;\n options?: LLMOptions;\n response: LLMResponse;\n}\n\n/** Recorded call to chatWithTools() */\nexport interface LLMToolCallRecord {\n messages: LLMMessage[];\n options: LLMToolCallOptions;\n response: LLMToolCallResponse;\n}\n\ntype PromptMatcher = string | RegExp | ((prompt: string) => boolean);\n\ninterface CompletionRule {\n matcher: PromptMatcher;\n response: string | LLMResponse | ((prompt: string) => string | LLMResponse);\n}\n\n/**\n * Mock LLM instance with call tracking and fluent API.\n * All methods are vi.fn() spies.\n */\nexport interface MockLLMInstance extends ILLM {\n /** All recorded complete() calls */\n calls: LLMCall[];\n /** Last complete() call (or undefined) */\n lastCall: LLMCall | undefined;\n /** All recorded chatWithTools() calls */\n toolCalls: LLMToolCallRecord[];\n /** Reset all recorded calls and spies */\n resetCalls: () => void;\n}\n\n/** Public type returned by mockLLM() — builder fluent API + ILLM spy instance */\nexport interface MockLLM extends MockLLMInstance {\n onComplete(matcher: PromptMatcher): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLM };\n onAnyComplete(): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLM };\n streaming(chunks: string[]): MockLLM;\n failing(error: Error): MockLLM;\n withToolCalls(calls: LLMToolCall[], content?: string): MockLLM;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Builder\n// ────────────────────────────────────────────────────────────────────\n\nclass MockLLMBuilder {\n private rules: CompletionRule[] = [];\n private defaultResponse: string | LLMResponse | ((prompt: string) => string | LLMResponse) = 'mock response';\n private streamChunks: string[] = ['mock'];\n private errorToThrow: Error | null = null;\n private toolCallsToReturn: LLMToolCall[] = [];\n private toolCallResponseContent = '';\n\n /**\n * Match a specific prompt (exact string or regex).\n * Returns a handler to set the response.\n */\n onComplete(matcher: PromptMatcher): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLMBuilder } {\n return {\n respondWith: (response) => {\n this.rules.push({ matcher, response });\n return this;\n },\n };\n }\n\n /**\n * Set the default response for any prompt that doesn't match a rule.\n */\n onAnyComplete(): { respondWith: (response: string | LLMResponse | ((prompt: string) => string | LLMResponse)) => MockLLMBuilder } {\n return {\n respondWith: (response) => {\n this.defaultResponse = response;\n return this;\n },\n };\n }\n\n /**\n * Configure streaming to yield specific chunks.\n */\n streaming(chunks: string[]): MockLLMBuilder {\n this.streamChunks = chunks;\n return this;\n }\n\n /**\n * Make the LLM throw an error on every call.\n */\n failing(error: Error): MockLLMBuilder {\n this.errorToThrow = error;\n return this;\n }\n\n /**\n * Configure chatWithTools() to return specific tool calls.\n */\n withToolCalls(calls: LLMToolCall[], content = ''): MockLLMBuilder {\n this.toolCallsToReturn = calls;\n this.toolCallResponseContent = content;\n return this;\n }\n\n /**\n * Build the mock ILLM instance. Called automatically by mockLLM().\n */\n build(): MockLLMInstance {\n const calls: LLMCall[] = [];\n const toolCallRecords: LLMToolCallRecord[] = [];\n const rules = this.rules;\n const defaultResponse = this.defaultResponse;\n const streamChunks = this.streamChunks;\n const errorToThrow = this.errorToThrow;\n const toolCallsToReturn = this.toolCallsToReturn;\n const toolCallResponseContent = this.toolCallResponseContent;\n\n function resolveResponse(prompt: string): LLMResponse {\n // Check rules in order\n for (const rule of rules) {\n if (matchesPrompt(rule.matcher, prompt)) {\n return toResponse(rule.response, prompt);\n }\n }\n // Fallback\n return toResponse(defaultResponse, prompt);\n }\n\n const completeFn = vi.fn(async (prompt: string, options?: LLMOptions): Promise<LLMResponse> => {\n if (errorToThrow) {throw errorToThrow;}\n const response = resolveResponse(prompt);\n calls.push({ prompt, options, response });\n return response;\n });\n\n const streamFn = vi.fn(async function* (_prompt: string, _options?: LLMOptions): AsyncIterable<string> {\n if (errorToThrow) {throw errorToThrow;}\n for (const chunk of streamChunks) {\n yield chunk;\n }\n });\n\n const chatWithToolsFn = vi.fn(async (messages: LLMMessage[], options: LLMToolCallOptions): Promise<LLMToolCallResponse> => {\n if (errorToThrow) {throw errorToThrow;}\n\n const lastUserMsg = messages.filter(m => m.role === 'user').pop();\n const prompt = lastUserMsg?.content ?? '';\n const baseResponse = resolveResponse(prompt);\n\n const response: LLMToolCallResponse = {\n ...baseResponse,\n content: toolCallsToReturn.length > 0 ? toolCallResponseContent : baseResponse.content,\n toolCalls: toolCallsToReturn.length > 0 ? toolCallsToReturn : undefined,\n };\n\n toolCallRecords.push({ messages, options, response });\n return response;\n });\n\n const instance: MockLLMInstance = {\n complete: completeFn,\n stream: streamFn,\n chatWithTools: chatWithToolsFn,\n calls,\n toolCalls: toolCallRecords,\n get lastCall() {\n return calls[calls.length - 1];\n },\n resetCalls: () => {\n calls.length = 0;\n toolCallRecords.length = 0;\n completeFn.mockClear();\n streamFn.mockClear();\n chatWithToolsFn.mockClear();\n },\n };\n\n return instance;\n }\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────────\n\nfunction matchesPrompt(matcher: PromptMatcher, prompt: string): boolean {\n if (typeof matcher === 'string') {return prompt.includes(matcher);}\n if (matcher instanceof RegExp) {return matcher.test(prompt);}\n return matcher(prompt);\n}\n\nfunction toResponse(\n value: string | LLMResponse | ((prompt: string) => string | LLMResponse),\n prompt: string,\n): LLMResponse {\n const resolved = typeof value === 'function' ? value(prompt) : value;\n if (typeof resolved === 'string') {\n return {\n content: resolved,\n usage: { promptTokens: 0, completionTokens: 0 },\n model: 'mock',\n };\n }\n return resolved;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Public API\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Create a mock LLM with fluent builder API.\n *\n * @example\n * ```typescript\n * // Simple: always returns same response\n * const llm = mockLLM();\n *\n * // With specific responses\n * const llm = mockLLM()\n * .onComplete('generate commit').respondWith('feat: add feature')\n * .onComplete(/explain/i).respondWith('This code does...')\n * .onAnyComplete().respondWith('default');\n *\n * // Streaming\n * const llm = mockLLM().streaming(['chunk1', 'chunk2', 'chunk3']);\n *\n * // Error simulation\n * const llm = mockLLM().failing(new Error('rate limit exceeded'));\n *\n * // Tool calling\n * const llm = mockLLM().withToolCalls([\n * { id: 'call-1', name: 'search', input: { query: 'test' } },\n * ]);\n * ```\n */\nexport function mockLLM(): MockLLM {\n const builder = new MockLLMBuilder();\n\n // Create a Proxy that acts as both builder and built instance.\n // Builder methods are forwarded to the builder.\n // ILLM methods (complete, stream, etc.) trigger auto-build on first access.\n let built: MockLLMInstance | null = null;\n\n function ensureBuilt(): MockLLMInstance {\n if (!built) {built = builder.build();}\n return built;\n }\n\n // Use Record<string, unknown> index signatures so we can introspect builder / instance\n // properties without falling back to `any`. The Proxy target is the builder.\n type BuilderRecord = MockLLMBuilder & Record<string, unknown>;\n type InstanceRecord = MockLLMInstance & Record<string, unknown>;\n\n const proxy = new Proxy(builder as BuilderRecord, {\n get(target: BuilderRecord, prop: string | symbol, _receiver: unknown): unknown {\n // Builder methods — return from builder\n if (prop in target && typeof target[prop as string] === 'function') {\n const method = (target[prop as string] as (...args: unknown[]) => unknown).bind(target);\n // After calling a builder method, invalidate the built instance\n return (...args: unknown[]): unknown => {\n built = null;\n const result = method(...args);\n // If the result is the builder itself (chaining), return the proxy\n if (result === target || (result !== null && typeof result === 'object' && 'respondWith' in result)) {\n if (result === target) {return proxy;}\n // Wrap respondWith to return proxy\n const resultWithRespond = result as { respondWith: (...rArgs: unknown[]) => unknown };\n return {\n respondWith: (...rArgs: unknown[]): unknown => {\n built = null;\n resultWithRespond.respondWith(...rArgs);\n return proxy;\n },\n };\n }\n return result;\n };\n }\n\n // ILLM instance properties — auto-build\n const instance = ensureBuilt() as InstanceRecord;\n // Return functions directly (not bound) to preserve vi.fn() spy identity\n return instance[prop as string];\n },\n });\n\n return proxy as unknown as MockLLM;\n}\n","/**\n * @module @kb-labs/shared-testing/mock-cache\n *\n * In-memory cache mock that actually stores data (unlike noop mocks).\n * All methods are vi.fn() spies for assertion.\n *\n * @example\n * ```typescript\n * const cache = mockCache();\n * await cache.set('key', { data: 42 }, 5000);\n * expect(await cache.get('key')).toEqual({ data: 42 });\n * expect(cache.set).toHaveBeenCalledWith('key', { data: 42 }, 5000);\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type { ICache } from '@kb-labs/core-platform';\n\ninterface CacheEntry {\n value: unknown;\n expiresAt: number | null; // null = no TTL\n}\n\ninterface SortedSetMember {\n score: number;\n member: string;\n}\n\n/**\n * Mock cache instance with working in-memory storage.\n * All methods are vi.fn() spies.\n */\nexport interface MockCacheInstance extends ICache {\n /** Direct access to the internal store (for assertions) */\n readonly store: Map<string, CacheEntry>;\n /** Direct access to sorted sets (for assertions) */\n readonly sortedSets: Map<string, SortedSetMember[]>;\n /** Reset all data and spy call history */\n reset: () => void;\n}\n\n/**\n * Create a mock cache with working in-memory storage.\n *\n * Unlike noop mocks, this cache actually stores and retrieves data,\n * respects TTL, and supports sorted set operations.\n *\n * @param initial - Optional initial data to populate the cache\n *\n * @example\n * ```typescript\n * // Empty cache\n * const cache = mockCache();\n *\n * // Pre-populated cache\n * const cache = mockCache({ 'user:1': { name: 'Alice' } });\n *\n * // TTL works\n * await cache.set('temp', 'value', 100); // expires in 100ms\n * await new Promise(r => setTimeout(r, 150));\n * expect(await cache.get('temp')).toBeNull(); // expired\n * ```\n */\nexport function mockCache(initial?: Record<string, unknown>): MockCacheInstance {\n const store = new Map<string, CacheEntry>();\n const sortedSets = new Map<string, SortedSetMember[]>();\n\n // Populate initial data\n if (initial) {\n for (const [key, value] of Object.entries(initial)) {\n store.set(key, { value, expiresAt: null });\n }\n }\n\n function isExpired(entry: CacheEntry): boolean {\n return entry.expiresAt !== null && Date.now() > entry.expiresAt;\n }\n\n // Keep raw vi.fn() references for mockClear() in reset.\n // The ICache-typed versions are cast below for the public interface.\n const spies: ReturnType<typeof vi.fn>[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function spy<T extends (...args: any[]) => unknown>(fn: T): T {\n const s = vi.fn(fn) as unknown as T;\n spies.push(s as unknown as ReturnType<typeof vi.fn>);\n return s;\n }\n\n const getFn = spy(async (key: string): Promise<unknown> => {\n const entry = store.get(key);\n if (!entry || isExpired(entry)) {\n if (entry) {store.delete(key);} // cleanup expired\n return null;\n }\n return entry.value;\n });\n\n const setFn = spy(async (key: string, value: unknown, ttl?: number): Promise<void> => {\n store.set(key, {\n value,\n expiresAt: ttl ? Date.now() + ttl : null,\n });\n });\n\n const deleteFn = spy(async (key: string): Promise<void> => {\n store.delete(key);\n });\n\n const clearFn = spy(async (pattern?: string): Promise<void> => {\n if (!pattern) {\n store.clear();\n return;\n }\n // Simple glob matching: only support trailing *\n const prefix = pattern.replace(/\\*$/, '');\n for (const key of store.keys()) {\n if (key.startsWith(prefix)) {\n store.delete(key);\n }\n }\n });\n\n const zaddFn = spy(async (key: string, score: number, member: string): Promise<void> => {\n if (!sortedSets.has(key)) {sortedSets.set(key, []);}\n const set = sortedSets.get(key)!;\n // Remove existing member\n const idx = set.findIndex(m => m.member === member);\n if (idx >= 0) {set.splice(idx, 1);}\n // Add with new score\n set.push({ score, member });\n // Keep sorted by score\n set.sort((a, b) => a.score - b.score);\n });\n\n const zrangebyscoreFn = spy(async (key: string, min: number, max: number): Promise<string[]> => {\n const set = sortedSets.get(key);\n if (!set) {return [];}\n return set\n .filter(m => m.score >= min && m.score <= max)\n .map(m => m.member);\n });\n\n const zremFn = spy(async (key: string, member: string): Promise<void> => {\n const set = sortedSets.get(key);\n if (!set) {return;}\n const idx = set.findIndex(m => m.member === member);\n if (idx >= 0) {set.splice(idx, 1);}\n });\n\n const setIfNotExistsFn = spy(async (key: string, value: unknown, ttl?: number): Promise<boolean> => {\n const existing = store.get(key);\n if (existing && !isExpired(existing)) {return false;}\n store.set(key, {\n value,\n expiresAt: ttl ? Date.now() + ttl : null,\n });\n return true;\n });\n\n const instance: MockCacheInstance = {\n get: getFn as unknown as ICache['get'],\n set: setFn as unknown as ICache['set'],\n delete: deleteFn,\n clear: clearFn,\n zadd: zaddFn,\n zrangebyscore: zrangebyscoreFn,\n zrem: zremFn,\n setIfNotExists: setIfNotExistsFn as unknown as ICache['setIfNotExists'],\n get store() { return store; },\n get sortedSets() { return sortedSets; },\n reset: () => {\n store.clear();\n sortedSets.clear();\n for (const s of spies) {s.mockClear();}\n },\n };\n\n return instance;\n}\n","/**\n * @module @kb-labs/shared-testing/mock-storage\n *\n * Virtual filesystem mock for IStorage interface.\n * All methods are vi.fn() spies.\n *\n * @example\n * ```typescript\n * const storage = mockStorage({\n * 'config.json': '{\"key\": \"value\"}',\n * 'data/file.txt': 'hello world',\n * });\n *\n * const content = await storage.read('config.json');\n * expect(content?.toString()).toBe('{\"key\": \"value\"}');\n * expect(storage.read).toHaveBeenCalledWith('config.json');\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type { IStorage } from '@kb-labs/core-platform';\n\n/**\n * Mock storage instance with in-memory virtual filesystem.\n */\nexport interface MockStorageInstance extends IStorage {\n /** Direct access to the virtual filesystem (for assertions) */\n readonly files: Map<string, Buffer>;\n /** Reset all files and spy call history */\n reset: () => void;\n}\n\n/**\n * Create a mock storage with in-memory virtual filesystem.\n *\n * @param initial - Optional initial files. Keys are paths, values are content (string or Buffer).\n *\n * @example\n * ```typescript\n * const storage = mockStorage({\n * 'data.json': JSON.stringify({ items: [] }),\n * 'binary.dat': Buffer.from([0x00, 0x01]),\n * });\n *\n * // Write and read\n * await storage.write('new.txt', Buffer.from('hello'));\n * expect(await storage.exists('new.txt')).toBe(true);\n *\n * // List files\n * const files = await storage.list('');\n * expect(files).toContain('new.txt');\n * ```\n */\nexport function mockStorage(initial?: Record<string, string | Buffer>): MockStorageInstance {\n const files = new Map<string, Buffer>();\n\n // Populate initial files\n if (initial) {\n for (const [path, content] of Object.entries(initial)) {\n files.set(path, typeof content === 'string' ? Buffer.from(content) : content);\n }\n }\n\n const readFn = vi.fn(async (path: string): Promise<Buffer | null> => {\n return files.get(path) ?? null;\n });\n\n const writeFn = vi.fn(async (path: string, data: Buffer): Promise<void> => {\n files.set(path, data);\n });\n\n const deleteFn = vi.fn(async (path: string): Promise<void> => {\n files.delete(path);\n });\n\n const listFn = vi.fn(async (prefix: string): Promise<string[]> => {\n const result: string[] = [];\n for (const path of files.keys()) {\n if (path.startsWith(prefix)) {\n result.push(path);\n }\n }\n return result.sort();\n });\n\n const existsFn = vi.fn(async (path: string): Promise<boolean> => {\n return files.has(path);\n });\n\n const instance: MockStorageInstance = {\n read: readFn,\n write: writeFn,\n delete: deleteFn,\n list: listFn,\n exists: existsFn,\n get files() { return files; },\n reset: () => {\n files.clear();\n readFn.mockClear();\n writeFn.mockClear();\n deleteFn.mockClear();\n listFn.mockClear();\n existsFn.mockClear();\n },\n };\n\n return instance;\n}\n","/**\n * @module @kb-labs/shared-testing/mock-logger\n *\n * Logger mock with message recording and vi.fn() spies.\n *\n * @example\n * ```typescript\n * const logger = mockLogger();\n * logger.info('hello', { extra: 'data' });\n * logger.error('oops', new Error('fail'));\n *\n * expect(logger.messages).toEqual([\n * { level: 'info', msg: 'hello', meta: { extra: 'data' } },\n * { level: 'error', msg: 'oops', error: expect.any(Error), meta: undefined },\n * ]);\n * expect(logger.info).toHaveBeenCalledWith('hello', { extra: 'data' });\n * ```\n */\n\nimport { vi } from 'vitest';\nimport type { ILogger } from '@kb-labs/core-platform';\n\n/** Recorded log entry */\nexport interface LogEntry {\n level: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n msg: string;\n error?: Error;\n meta?: Record<string, unknown>;\n}\n\n/**\n * Mock logger instance with message recording.\n */\nexport interface MockLoggerInstance extends ILogger {\n /** All recorded log messages */\n readonly messages: LogEntry[];\n /** Reset messages and spy call history */\n reset: () => void;\n}\n\n/**\n * Create a mock logger with message recording.\n *\n * All log methods are vi.fn() spies. Messages are collected\n * into a `.messages` array for easy assertion.\n *\n * Child loggers share the same messages array.\n *\n * @example\n * ```typescript\n * const logger = mockLogger();\n * const child = logger.child({ module: 'auth' });\n *\n * child.info('user logged in');\n * expect(logger.messages).toHaveLength(1);\n * expect(logger.messages[0].msg).toBe('user logged in');\n * ```\n */\nexport function mockLogger(sharedMessages?: LogEntry[]): MockLoggerInstance {\n const messages: LogEntry[] = sharedMessages ?? [];\n\n // trace, debug, info, warn: (message, meta?)\n function createSimpleLogMethod(level: LogEntry['level']) {\n return vi.fn((msg: string, meta?: Record<string, unknown>) => {\n messages.push({ level, msg, meta });\n });\n }\n\n // error, fatal: (message, error?, meta?)\n function createErrorLogMethod(level: 'error' | 'fatal') {\n return vi.fn((msg: string, error?: Error, meta?: Record<string, unknown>) => {\n messages.push({ level, msg, error, meta });\n });\n }\n\n const instance: MockLoggerInstance = {\n trace: createSimpleLogMethod('trace'),\n debug: createSimpleLogMethod('debug'),\n info: createSimpleLogMethod('info'),\n warn: createSimpleLogMethod('warn'),\n error: createErrorLogMethod('error'),\n fatal: createErrorLogMethod('fatal'),\n child: (_bindings?: Record<string, unknown>) => mockLogger(messages),\n get messages() { return messages; },\n reset: () => {\n messages.length = 0;\n (instance.trace as ReturnType<typeof vi.fn>).mockClear();\n (instance.debug as ReturnType<typeof vi.fn>).mockClear();\n (instance.info as ReturnType<typeof vi.fn>).mockClear();\n (instance.warn as ReturnType<typeof vi.fn>).mockClear();\n (instance.error as ReturnType<typeof vi.fn>).mockClear();\n (instance.fatal as ReturnType<typeof vi.fn>).mockClear();\n },\n };\n\n return instance;\n}\n","/**\n * @module @kb-labs/shared-testing/create-test-context\n *\n * Enhanced test context factory that bridges ctx.platform and the global singleton.\n *\n * Unlike the original createTestContext() from SDK, this version:\n * - Uses mockLLM/mockCache/mockLogger with vi.fn() spies (not noop functions)\n * - Syncs ctx.platform adapters with the global singleton via setupTestPlatform()\n * - Provides a cleanup function to reset the singleton in afterEach()\n *\n * @example\n * ```typescript\n * import { createTestContext, mockLLM } from '@kb-labs/shared-testing';\n *\n * const llm = mockLLM().onAnyComplete().respondWith('hello');\n * const { ctx, cleanup } = createTestContext({ platform: { llm } });\n *\n * // Both work — ctx.platform and useLLM() return the same mock\n * await handler.execute(ctx, args);\n * expect(llm.complete).toHaveBeenCalled();\n *\n * cleanup(); // Reset singleton in afterEach\n * ```\n */\n\nimport type {\n PluginContextV3,\n HostContext,\n PlatformServices,\n UIFacade,\n TraceContext,\n RuntimeAPI,\n PluginAPI,\n FSShim,\n FetchShim,\n EnvShim,\n InvokeAPI,\n EnvironmentAPI,\n WorkspaceAPI,\n SnapshotAPI,\n} from '@kb-labs/plugin-contracts';\n\nimport { setupTestPlatform } from './setup-platform.js';\nimport { mockLLM } from './mock-llm.js';\nimport { mockCache } from './mock-cache.js';\nimport { mockStorage } from './mock-storage.js';\nimport { mockLogger } from './mock-logger.js';\nimport { vi } from 'vitest';\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\nexport interface CreateTestContextOptions {\n pluginId?: string;\n pluginVersion?: string;\n host?: 'cli' | 'rest' | 'workflow' | 'webhook';\n hostContext?: HostContext;\n config?: unknown;\n cwd?: string;\n outdir?: string;\n tenantId?: string;\n signal?: AbortSignal;\n /** Override platform services. Also synced to global singleton. */\n platform?: Partial<PlatformServices>;\n /** Override UI facade */\n ui?: Partial<UIFacade>;\n /**\n * If true, sync platform adapters to the global singleton\n * so that useLLM(), useCache(), etc. return the test mocks.\n * @default true\n */\n syncSingleton?: boolean;\n}\n\nexport interface TestContextResult<TConfig = unknown> {\n /** The plugin context with test mocks */\n ctx: PluginContextV3<TConfig>;\n /** Call in afterEach() to reset the global singleton */\n cleanup: () => void;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Mock factories\n// ────────────────────────────────────────────────────────────────────\n\nexport function createMockTrace(): TraceContext {\n return {\n traceId: 'test-trace-id',\n spanId: 'test-span-id',\n parentSpanId: undefined,\n addEvent: () => {},\n setAttribute: () => {},\n recordError: () => {},\n };\n}\n\nexport function createMockUI(): UIFacade {\n const messages: string[] = [];\n\n const mockColor = (text: string) => text;\n const mockColors = {\n success: mockColor,\n error: mockColor,\n warning: mockColor,\n info: mockColor,\n primary: mockColor,\n accent: mockColor,\n highlight: mockColor,\n secondary: mockColor,\n emphasis: mockColor,\n muted: mockColor,\n foreground: mockColor,\n dim: mockColor,\n bold: mockColor,\n underline: mockColor,\n inverse: mockColor,\n };\n\n return {\n colors: mockColors,\n symbols: {\n success: '+',\n error: 'x',\n warning: '!',\n info: 'i',\n bullet: '-',\n clock: 'T',\n folder: 'D',\n package: 'P',\n pointer: '>',\n section: '#',\n separator: '-',\n border: '|',\n topLeft: '+',\n topRight: '+',\n bottomLeft: '+',\n bottomRight: '+',\n leftT: '+',\n rightT: '+',\n },\n write: vi.fn((text) => messages.push(`WRITE: ${text}`)),\n info: vi.fn((msg) => messages.push(`INFO: ${msg}`)),\n success: vi.fn((msg) => messages.push(`SUCCESS: ${msg}`)),\n warn: vi.fn((msg) => messages.push(`WARN: ${msg}`)),\n error: vi.fn((err) => messages.push(`ERROR: ${err instanceof Error ? err.message : err}`)),\n debug: vi.fn((msg) => messages.push(`DEBUG: ${msg}`)),\n spinner: vi.fn((msg) => {\n messages.push(`SPINNER: ${msg}`);\n return {\n update: vi.fn((m: string) => messages.push(`SPINNER UPDATE: ${m}`)),\n succeed: vi.fn((m?: string) => messages.push(`SPINNER SUCCEED: ${m ?? msg}`)),\n fail: vi.fn((m?: string) => messages.push(`SPINNER FAIL: ${m ?? msg}`)),\n stop: vi.fn(),\n };\n }),\n table: vi.fn((data) => messages.push(`TABLE: ${JSON.stringify(data)}`)),\n json: vi.fn((data) => messages.push(`JSON: ${JSON.stringify(data)}`)),\n newline: vi.fn(() => messages.push('')),\n divider: vi.fn(() => messages.push('-'.repeat(40))),\n box: vi.fn((content, title) => {\n if (title) {messages.push(`+- ${title} -+`);}\n messages.push(content);\n if (title) {messages.push(`+${'-'.repeat(title.length + 4)}+`);}\n }),\n sideBox: vi.fn((options) => {\n messages.push(`+- ${options.title} -+`);\n if (options.summary) {\n Object.entries(options.summary).forEach(([key, value]) => {\n messages.push(` ${key}: ${value}`);\n });\n }\n if (options.sections) {\n options.sections.forEach((section: { header?: string; items: string[] }) => {\n if (section.header) {messages.push(` ${section.header}:`);}\n section.items.forEach((item: string) => messages.push(` ${item}`));\n });\n }\n if (options.timing) {\n messages.push(` Timing: ${options.timing}ms`);\n }\n messages.push('+' + '-'.repeat(options.title.length + 4) + '+');\n }),\n confirm: vi.fn(async () => true),\n prompt: vi.fn(async () => ''),\n };\n}\n\nexport function createMockRuntime(): RuntimeAPI {\n const mockFS: FSShim = {\n readFile: vi.fn(async () => ''),\n readFileBuffer: vi.fn(async () => new Uint8Array()),\n writeFile: vi.fn(async () => {}),\n readdir: vi.fn(async () => []),\n readdirWithStats: vi.fn(async () => []),\n mkdir: vi.fn(async () => {}),\n rm: vi.fn(async () => {}),\n copy: vi.fn(async () => {}),\n move: vi.fn(async () => {}),\n glob: vi.fn(async () => []),\n stat: vi.fn(async () => ({\n isFile: () => false,\n isDirectory: () => false,\n size: 0,\n mtime: Date.now(),\n ctime: Date.now(),\n })),\n exists: vi.fn(async () => false),\n resolve: (path: string) => path,\n relative: (path: string) => path,\n join: (...segments: string[]) => segments.join('/'),\n dirname: (path: string) => path.split('/').slice(0, -1).join('/'),\n basename: (path: string) => path.split('/').pop() ?? '',\n extname: (path: string) => {\n const base = path.split('/').pop() ?? '';\n const idx = base.lastIndexOf('.');\n return idx > 0 ? base.slice(idx) : '';\n },\n };\n\n const mockFetch: FetchShim = vi.fn(async () => new Response('mock'));\n const mockEnv: EnvShim = vi.fn((_key: string) => undefined) as EnvShim;\n\n return {\n fs: mockFS,\n fetch: mockFetch,\n env: mockEnv,\n };\n}\n\nexport function createMockEnvironmentAPI(): EnvironmentAPI {\n return {\n create: vi.fn(async () => ({\n environmentId: 'env_mock_1',\n provider: 'mock',\n status: 'ready' as const,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n })),\n status: vi.fn(async (environmentId: string) => ({\n environmentId,\n status: 'ready' as const,\n updatedAt: new Date().toISOString(),\n })),\n destroy: vi.fn(async () => {}),\n renewLease: vi.fn(async () => ({\n leaseId: 'lease_mock_1',\n acquiredAt: new Date().toISOString(),\n expiresAt: new Date(Date.now() + 10 * 60 * 1000).toISOString(),\n })),\n };\n}\n\nexport function createMockWorkspaceAPI(): WorkspaceAPI {\n return {\n materialize: vi.fn(async () => ({\n workspaceId: 'ws_mock_1',\n provider: 'mock',\n status: 'ready' as const,\n rootPath: '/tmp/ws_mock_1',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n })),\n attach: vi.fn(async (request) => ({\n workspaceId: request.workspaceId,\n environmentId: request.environmentId,\n mountPath: request.mountPath ?? '/workspace',\n attachedAt: new Date().toISOString(),\n })),\n release: vi.fn(async () => {}),\n status: vi.fn(async (workspaceId: string) => ({\n workspaceId,\n status: 'ready' as const,\n updatedAt: new Date().toISOString(),\n })),\n };\n}\n\nexport function createMockSnapshotAPI(): SnapshotAPI {\n return {\n capture: vi.fn(async (request) => ({\n snapshotId: request.snapshotId ?? 'snap_mock_1',\n provider: 'mock',\n status: 'ready' as const,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n workspaceId: request.workspaceId,\n environmentId: request.environmentId,\n })),\n restore: vi.fn(async (request) => ({\n snapshotId: request.snapshotId,\n restoredAt: new Date().toISOString(),\n workspaceId: request.workspaceId,\n environmentId: request.environmentId,\n targetPath: request.targetPath,\n })),\n status: vi.fn(async (snapshotId: string) => ({\n snapshotId,\n status: 'ready' as const,\n updatedAt: new Date().toISOString(),\n })),\n delete: vi.fn(async () => {}),\n gc: vi.fn(async (request) => ({\n scanned: 0,\n deleted: 0,\n dryRun: request?.dryRun ?? false,\n })),\n };\n}\n\nexport function createInfraApiMocks(): Pick<PluginAPI, 'environment' | 'workspace' | 'snapshot'> {\n return {\n environment: createMockEnvironmentAPI(),\n workspace: createMockWorkspaceAPI(),\n snapshot: createMockSnapshotAPI(),\n };\n}\n\nexport function createMockPluginAPI(): PluginAPI {\n const infra = createInfraApiMocks();\n return {\n lifecycle: {\n onCleanup: vi.fn(),\n },\n state: {\n get: vi.fn(async () => undefined),\n set: vi.fn(async () => {}),\n delete: vi.fn(async () => {}),\n has: vi.fn(async () => false),\n getMany: vi.fn(async () => new Map()),\n setMany: vi.fn(async () => {}),\n },\n artifacts: {\n write: vi.fn(async () => '/mock/path'),\n list: vi.fn(async () => []),\n read: vi.fn(async () => ''),\n readBuffer: vi.fn(async () => new Uint8Array()),\n exists: vi.fn(async () => false),\n path: vi.fn(() => '/mock/path'),\n },\n shell: {\n exec: vi.fn(async () => ({ code: 0, stdout: '', stderr: '', ok: true })),\n },\n events: {\n emit: vi.fn(async () => {}),\n },\n invoke: {\n call: vi.fn(async (_pluginId: string, _input?: unknown, _options?: unknown) => undefined) as InvokeAPI['call'],\n },\n workflows: {\n run: vi.fn(async () => 'mock-run-id'),\n wait: vi.fn(async () => undefined),\n status: vi.fn(async () => null),\n cancel: vi.fn(async () => {}),\n list: vi.fn(async () => []),\n },\n jobs: {\n submit: vi.fn(async () => 'mock-job-id'),\n schedule: vi.fn(async () => 'mock-scheduled-job-id'),\n wait: vi.fn(async () => undefined),\n status: vi.fn(async () => null),\n cancel: vi.fn(async () => false),\n list: vi.fn(async () => []),\n },\n cron: {\n register: vi.fn(async () => {}),\n unregister: vi.fn(async () => {}),\n list: vi.fn(async () => []),\n pause: vi.fn(async () => {}),\n resume: vi.fn(async () => {}),\n trigger: vi.fn(async () => {}),\n },\n environment: infra.environment,\n workspace: infra.workspace,\n snapshot: infra.snapshot,\n };\n}\n\nexport const createMockPlatformApi = createMockPluginAPI;\n\nexport function createMockPluginContextV3<TConfig = unknown>(\n options: CreateTestContextOptions = {}\n): TestContextResult<TConfig> {\n return createTestContext<TConfig>(options);\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Public API\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Create a test context for plugin development.\n *\n * Unlike the original SDK version, this:\n * - Uses mock builders with vi.fn() spies (not noop functions)\n * - Syncs platform adapters to the global singleton by default\n * - Returns a cleanup function for afterEach()\n *\n * @example\n * ```typescript\n * import { createTestContext, mockLLM } from '@kb-labs/shared-testing';\n *\n * describe('my handler', () => {\n * let cleanup: () => void;\n *\n * beforeEach(() => {\n * const llm = mockLLM().onAnyComplete().respondWith('ok');\n * const result = createTestContext({ platform: { llm } });\n * cleanup = result.cleanup;\n * // Use result.ctx in your tests\n * });\n *\n * afterEach(() => cleanup());\n * });\n * ```\n */\nexport function createTestContext<TConfig = unknown>(\n options: CreateTestContextOptions = {}\n): TestContextResult<TConfig> {\n const {\n pluginId = 'test-plugin',\n pluginVersion = '0.0.0',\n host = 'cli',\n hostContext,\n config,\n cwd = process.cwd(),\n outdir,\n tenantId,\n signal,\n platform: platformOverrides,\n ui: uiOverrides,\n syncSingleton = true,\n } = options;\n\n const resolvedOutdir = outdir ?? `${cwd}/.kb/output`;\n\n // Build default host context\n const defaultHostContext: HostContext =\n hostContext ??\n (() => {\n switch (host) {\n case 'cli':\n return { host: 'cli', argv: ['test'], flags: {} };\n case 'rest':\n return {\n host: 'rest',\n method: 'GET',\n path: '/test',\n requestId: 'test-req-001',\n traceId: 'test-trace-001',\n };\n case 'workflow':\n return { host: 'workflow', workflowId: 'test-wf', runId: 'test-run', stepId: 'test-step' };\n case 'webhook':\n return { host: 'webhook', event: 'test:event' };\n }\n })();\n\n // Create default mocks (with spies, not noop)\n const defaultLogger = mockLogger();\n const defaultLLM = mockLLM();\n const defaultCache = mockCache();\n const defaultStorage = mockStorage();\n\n const defaultPlatform: PlatformServices = {\n logger: defaultLogger,\n llm: defaultLLM,\n embeddings: {\n embed: vi.fn(async () => []),\n embedBatch: vi.fn(async () => [[]]),\n dimensions: 1536,\n getDimensions: vi.fn(async () => 1536),\n },\n vectorStore: {\n search: vi.fn(async () => []),\n upsert: vi.fn(async () => {}),\n delete: vi.fn(async () => {}),\n count: vi.fn(async () => 0),\n },\n cache: defaultCache,\n storage: defaultStorage,\n analytics: {\n track: vi.fn(async () => {}),\n identify: vi.fn(async () => {}),\n flush: vi.fn(async () => {}),\n },\n eventBus: {\n publish: vi.fn(async () => {}),\n subscribe: vi.fn(() => () => {}),\n },\n config: {\n getConfig: vi.fn(async () => ({})),\n getRawConfig: vi.fn(async () => ({})),\n },\n invoke: {\n call: vi.fn(async () => ({ success: true, data: null })),\n isAvailable: vi.fn(async () => false),\n } as PlatformServices['invoke'],\n sqlDatabase: {\n query: vi.fn(async () => ({ rows: [], rowCount: 0 })),\n transaction: vi.fn(async () => ({ query: vi.fn(), commit: vi.fn(), rollback: vi.fn() })),\n close: vi.fn(async () => {}),\n },\n documentDatabase: {\n find: vi.fn(async () => []),\n findById: vi.fn(async () => null),\n insertOne: vi.fn(async () => ({ id: 'mock', createdAt: 0, updatedAt: 0 })),\n updateMany: vi.fn(async () => 0),\n updateById: vi.fn(async () => null),\n deleteMany: vi.fn(async () => 0),\n deleteById: vi.fn(async () => false),\n count: vi.fn(async () => 0),\n close: vi.fn(async () => {}),\n } as PlatformServices['documentDatabase'],\n logs: {\n query: vi.fn(async () => ({ logs: [], total: 0, hasMore: false, source: 'buffer' as const })),\n getById: vi.fn(async () => null),\n search: vi.fn(async () => ({ logs: [], total: 0, hasMore: false })),\n subscribe: vi.fn(() => () => {}),\n getStats: vi.fn(async () => ({})),\n getCapabilities: vi.fn(() => ({ hasBuffer: false, hasPersistence: false, hasSearch: false, hasStreaming: false })),\n },\n };\n\n // Merge overrides\n const finalPlatform: PlatformServices = {\n ...defaultPlatform,\n ...platformOverrides,\n };\n\n // Sync to global singleton\n let cleanupFn = () => {};\n if (syncSingleton) {\n const result = setupTestPlatform({\n llm: finalPlatform.llm,\n cache: finalPlatform.cache,\n storage: finalPlatform.storage,\n logger: finalPlatform.logger,\n analytics: finalPlatform.analytics,\n embeddings: finalPlatform.embeddings,\n vectorStore: finalPlatform.vectorStore,\n eventBus: finalPlatform.eventBus,\n });\n cleanupFn = result.cleanup;\n }\n\n // UI\n const defaultUI = createMockUI();\n const finalUI: UIFacade = {\n ...defaultUI,\n ...uiOverrides,\n };\n\n // Build context\n const ctx: PluginContextV3<TConfig> = {\n host,\n requestId: 'test-trace:test-span',\n pluginId,\n pluginVersion,\n tenantId,\n cwd,\n outdir: resolvedOutdir,\n config: config as TConfig,\n signal,\n trace: createMockTrace(),\n hostContext: defaultHostContext,\n ui: finalUI,\n platform: finalPlatform,\n runtime: createMockRuntime(),\n api: createMockPluginAPI(),\n };\n\n return { ctx, cleanup: cleanupFn };\n}\n","/**\n * @module @kb-labs/shared-testing/test-command\n *\n * Single-function test runner for plugin command handlers.\n *\n * Eliminates boilerplate: no manual context creation, no descriptor setup,\n * no mock wiring. Import your handler, call testCommand(), assert on result.\n *\n * @example\n * ```typescript\n * import { testCommand, mockLLM } from '@kb-labs/shared-testing';\n * import handler from '../src/commands/greet.js';\n *\n * it('greets the user', async () => {\n * const result = await testCommand(handler, {\n * flags: { name: 'Alice' },\n * });\n *\n * expect(result.exitCode).toBe(0);\n * expect(result.result).toEqual({ message: 'Hello, Alice!' });\n * expect(result.ui.success).toHaveBeenCalledWith('Hello, Alice!');\n * });\n * ```\n */\n\nimport type {\n PluginContextV3,\n CommandResult,\n UIFacade,\n PlatformServices,\n} from '@kb-labs/plugin-contracts';\n\nimport {\n createTestContext,\n type CreateTestContextOptions,\n} from './create-test-context.js';\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Any handler that has an execute(ctx, input) method.\n * Covers CommandHandlerV3, RouteHandler, Handler, and raw objects.\n */\nexport interface TestableHandler<TConfig = unknown, TInput = unknown, TResult = unknown> {\n execute(\n context: PluginContextV3<TConfig>,\n input: TInput\n ): Promise<TResult> | TResult;\n cleanup?(): Promise<void> | void;\n}\n\n/**\n * Options for testCommand().\n *\n * Provide only what you need — everything else gets sensible defaults.\n */\nexport interface TestCommandOptions<TConfig = unknown> {\n // ── Input ──────────────────────────────────────────────────────\n\n /** CLI flags (sugar for input: { flags, argv }) */\n flags?: Record<string, unknown>;\n\n /** CLI positional arguments (default: []) */\n argv?: string[];\n\n /** REST query params (sugar for input: { query }) */\n query?: Record<string, unknown>;\n\n /** REST request body (sugar for input: { body }) */\n body?: unknown;\n\n /** REST route params (sugar for input: { params }) */\n params?: Record<string, unknown>;\n\n /**\n * Raw input object. If provided, flags/argv/query/body/params are ignored.\n * Use this when your handler expects a custom input shape.\n */\n input?: unknown;\n\n // ── Context ────────────────────────────────────────────────────\n\n /** Host type (default: 'cli') */\n host?: 'cli' | 'rest' | 'workflow' | 'webhook';\n\n /** Plugin config passed as ctx.config */\n config?: TConfig;\n\n /** Working directory (default: process.cwd()) */\n cwd?: string;\n\n /** Tenant ID */\n tenantId?: string;\n\n /** Abort signal */\n signal?: AbortSignal;\n\n // ── Mocks ──────────────────────────────────────────────────────\n\n /** Override platform services (e.g., { llm: mockLLM().onAnyComplete().respondWith('ok') }) */\n platform?: Partial<PlatformServices>;\n\n /** Override UI facade (individual methods are merged with default spy UI) */\n ui?: Partial<UIFacade>;\n\n /**\n * Sync platform mocks to global singleton for composables (useLLM, useCache, etc.)\n * @default true\n */\n syncSingleton?: boolean;\n}\n\n/**\n * Result of testCommand() — everything you need for assertions.\n */\nexport interface TestCommandResult<TResult = unknown> {\n /** Exit code from CommandResult (0 = success). Defaults to 0 if handler returns raw data. */\n exitCode: number;\n\n /** The result data from the handler */\n result: TResult | undefined;\n\n /** Custom metadata from CommandResult.meta */\n meta: Record<string, unknown> | undefined;\n\n /** The raw return value from handler.execute() — useful for non-CommandResult handlers */\n raw: unknown;\n\n /** UI facade with vi.fn() spies — assert on ui.success, ui.error, etc. */\n ui: UIFacade;\n\n /** The full context that was passed to the handler */\n ctx: PluginContextV3;\n\n /** Call in afterEach() to reset the global platform singleton */\n cleanup: () => void;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Implementation\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Test a plugin command handler with minimal boilerplate.\n *\n * Creates a test context, builds the input object, calls handler.execute(),\n * and returns a result with UI spies for assertions.\n *\n * @example CLI command\n * ```typescript\n * import handler from '../src/commands/greet.js';\n *\n * const result = await testCommand(handler, {\n * flags: { name: 'Alice' },\n * });\n * expect(result.exitCode).toBe(0);\n * expect(result.ui.success).toHaveBeenCalledWith('Hello, Alice!');\n * ```\n *\n * @example REST handler\n * ```typescript\n * import handler from '../src/routes/create-plan.js';\n *\n * const result = await testCommand(handler, {\n * host: 'rest',\n * body: { name: 'v2.0' },\n * query: { workspace: 'root' },\n * });\n * expect(result.result).toMatchObject({ name: 'v2.0' });\n * ```\n *\n * @example With LLM mock\n * ```typescript\n * import { testCommand, mockLLM } from '@kb-labs/shared-testing';\n * import handler from '../src/commands/analyze.js';\n *\n * const llm = mockLLM().onAnyComplete().respondWith('looks good');\n * const result = await testCommand(handler, {\n * flags: { file: 'index.ts' },\n * platform: { llm },\n * });\n * expect(llm.complete).toHaveBeenCalled();\n * expect(result.exitCode).toBe(0);\n * ```\n */\nexport async function testCommand<TResult = unknown, TConfig = unknown>(\n handler: TestableHandler<TConfig, any, any>,\n options: TestCommandOptions<TConfig> = {}\n): Promise<TestCommandResult<TResult>> {\n const {\n flags,\n argv = [],\n query,\n body,\n params,\n input: rawInput,\n host = 'cli',\n config,\n cwd,\n tenantId,\n signal,\n platform,\n ui,\n syncSingleton = true,\n } = options;\n\n // ── Build context ──────────────────────────────────────────────\n\n const ctxOptions: CreateTestContextOptions = {\n host,\n config,\n cwd,\n tenantId,\n signal,\n platform,\n ui,\n syncSingleton,\n };\n\n const { ctx, cleanup } = createTestContext<TConfig>(ctxOptions);\n\n // ── Build input ────────────────────────────────────────────────\n\n let input: unknown;\n\n if (rawInput !== undefined) {\n // Explicit raw input takes precedence\n input = rawInput;\n } else if (host === 'rest') {\n // REST handlers expect { query?, body?, params? }\n input = {\n ...(query !== undefined ? { query } : {}),\n ...(body !== undefined ? { body } : {}),\n ...(params !== undefined ? { params } : {}),\n };\n } else {\n // CLI/workflow handlers expect { flags, argv }\n input = { flags: flags ?? {}, argv };\n }\n\n // ── Execute ────────────────────────────────────────────────────\n\n let raw: unknown;\n try {\n raw = await handler.execute(ctx as PluginContextV3<TConfig>, input);\n } finally {\n // Call cleanup if handler has one\n await handler.cleanup?.();\n }\n\n // ── Normalize result ───────────────────────────────────────────\n\n // Handler may return CommandResult<T>, void, or raw data.\n // Detect by checking for exitCode property.\n let exitCode = 0;\n let result: TResult | undefined;\n let meta: Record<string, unknown> | undefined;\n\n if (raw != null && typeof raw === 'object' && 'exitCode' in raw) {\n // CommandResult shape\n const cmdResult = raw as CommandResult<TResult>;\n exitCode = cmdResult.exitCode;\n result = cmdResult.result;\n meta = cmdResult.meta;\n } else if (raw === undefined || raw === null) {\n // void return (RouteHandler can return void)\n exitCode = 0;\n result = undefined;\n meta = undefined;\n } else {\n // Raw data (Handler from defineHandler returns data directly)\n exitCode = 0;\n result = raw as TResult;\n meta = undefined;\n }\n\n return {\n exitCode,\n result,\n meta,\n raw,\n ui: ctx.ui,\n ctx: ctx as PluginContextV3,\n cleanup,\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/shared-testing",
|
|
3
3
|
"description": "Test utilities for KB Labs plugin development — mock builders, platform setup, test context",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.93.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -18,16 +18,16 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"vitest": "^3.2.4",
|
|
21
|
-
"@kb-labs/core-platform": "2.
|
|
22
|
-
"@kb-labs/
|
|
23
|
-
"@kb-labs/
|
|
21
|
+
"@kb-labs/core-platform": "2.93.0",
|
|
22
|
+
"@kb-labs/core-runtime": "2.93.0",
|
|
23
|
+
"@kb-labs/plugin-contracts": "2.93.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^24.3.3",
|
|
27
27
|
"rimraf": "^6.0.1",
|
|
28
28
|
"tsup": "^8.5.0",
|
|
29
29
|
"typescript": "^5.6.3",
|
|
30
|
-
"@kb-labs/devkit": "2.
|
|
30
|
+
"@kb-labs/devkit": "2.93.0"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=20.0.0",
|