/** * Completion Test Harness * * Provides utilities for testing CLI completion by invoking --get-completions directly. * This bypasses shell complexity and tests the completion function itself. */ import { expect } from 'bun:test'; import type { CLIContext } from './cli-context'; /** * Test harness for CLI completion */ export class CompletionHarness { constructor(private cli: CLIContext) {} /** * Get completions for a given set of words * * @param words - The command words (e.g., ['celilo', 'service']) * @param partial - If true, complete the last word (for prefix matching). If false (default), complete after all words * @returns Array of completion suggestions */ async getCompletions(words: string[], partial = false): Promise { // If partial=true, we're completing the last word itself (prefix matching) // If partial=false, we're completing the next word after all current words const currentIndex = partial && words.length > 0 ? words.length - 1 : words.length; try { const result = await this.cli.run(`--get-completions ${words.join(' ')} ${currentIndex}`); // Parse completion output (one per line) return result.stdout.split('\n').filter(Boolean); } catch (_error) { // Completion errors return empty array return []; } } /** * Assert that completions include all expected values * * @param words - The command words * @param expected - Expected completion values */ async expectCompletionsInclude(words: string[], expected: string[]): Promise { const actual = await this.getCompletions(words); for (const exp of expected) { expect(actual).toContain(exp); } } /** * Assert that completions exactly match expected values (order-independent) * * @param words - The command words * @param expected - Expected completion values */ async expectCompletionsExact(words: string[], expected: string[]): Promise { const actual = await this.getCompletions(words); expect(actual.sort()).toEqual(expected.sort()); } /** * Assert that no completions are returned * * @param words - The command words */ async expectNoCompletions(words: string[]): Promise { const actual = await this.getCompletions(words); expect(actual).toEqual([]); } /** * Assert that at least one completion is returned * * @param words - The command words */ async expectSomeCompletions(words: string[]): Promise { const actual = await this.getCompletions(words); expect(actual.length).toBeGreaterThan(0); } }