UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

166 lines (146 loc) 4.38 kB
import { AlephaError } from "alepha"; import type { ShellProvider, ShellRunOptions } from "./ShellProvider.ts"; // --------------------------------------------------------------------------------------------------------------------- export interface MemoryShellCall { command: string; options: ShellRunOptions; } export interface MemoryShellProviderOptions { /** * Simulated outputs for specific commands. * Key is the command string, value is the stdout to return. */ outputs?: Record<string, string>; /** * Commands that should throw an error. * Key is the command string, value is the error message. */ errors?: Record<string, string>; /** * Commands that are considered "installed" in the system PATH. */ installedCommands?: string[]; } // --------------------------------------------------------------------------------------------------------------------- /** * In-memory implementation of ShellProvider for testing. * * Records all commands that would be executed without actually running them. * Can be configured to return specific outputs or throw errors for testing. * * @example * ```typescript * // In tests, substitute the real ShellProvider with MemoryShellProvider * const alepha = Alepha.create().with({ * provide: ShellProvider, * use: MemoryShellProvider, * }); * * // Configure mock behavior * const shell = alepha.inject(MemoryShellProvider); * shell.configure({ * outputs: { "echo hello": "hello\n" }, * errors: { "failing-cmd": "Command failed" }, * }); * * // Or use the fluent API * shell.outputs.set("another-cmd", "output"); * shell.errors.set("another-error", "Error message"); * * // Run code that uses ShellProvider * const service = alepha.inject(MyService); * await service.doSomething(); * * // Verify commands were called * expect(shell.calls).toHaveLength(2); * expect(shell.calls[0].command).toBe("yarn install"); * ``` */ export class MemoryShellProvider implements ShellProvider { /** * All recorded shell calls. */ public calls: MemoryShellCall[] = []; /** * Simulated outputs for specific commands. */ public outputs = new Map<string, string>(); /** * Commands that should throw an error. */ public errors = new Map<string, string>(); /** * Commands considered installed in the system PATH. */ public installedCommands = new Set<string>(); /** * Configure the mock with predefined outputs, errors, and installed commands. */ public configure(options: MemoryShellProviderOptions): this { if (options.outputs) { for (const [cmd, output] of Object.entries(options.outputs)) { this.outputs.set(cmd, output); } } if (options.errors) { for (const [cmd, error] of Object.entries(options.errors)) { this.errors.set(cmd, error); } } if (options.installedCommands) { for (const cmd of options.installedCommands) { this.installedCommands.add(cmd); } } return this; } /** * Record command and return simulated output. */ public async run( command: string, options: ShellRunOptions = {}, ): Promise<string> { this.calls.push({ command, options }); // Check for configured error const errorMsg = this.errors.get(command); if (errorMsg) { throw new AlephaError(errorMsg); } // Return configured output or empty string return this.outputs.get(command) ?? ""; } /** * Check if a specific command was called. */ public wasCalled(command: string): boolean { return this.calls.some((call) => call.command === command); } /** * Check if a command matching a pattern was called. */ public wasCalledMatching(pattern: RegExp): boolean { return this.calls.some((call) => pattern.test(call.command)); } /** * Get all calls matching a pattern. */ public getCallsMatching(pattern: RegExp): MemoryShellCall[] { return this.calls.filter((call) => pattern.test(call.command)); } /** * Check if a command is installed. */ public async isInstalled(command: string): Promise<boolean> { return this.installedCommands.has(command); } /** * Reset all recorded state. */ public reset(): void { this.calls = []; this.outputs.clear(); this.errors.clear(); this.installedCommands.clear(); } }