import { strict as assert } from 'node:assert'; export interface IRunMxCliResult { readonly logs: string[]; readonly errors: string[]; readonly exitCode: number; } async function loadMxCli(): Promise<{ createProgram: () => import('commander').Command }> { const mxCliUrl = new URL('../../src/index.ts', import.meta.url).href; return await import(`${mxCliUrl}?test=${Date.now()}-${Math.random().toString(16).slice(2)}`); } export async function runMxCli(argv: string[], options: { cwd?: string } = {}): Promise { const logs: string[] = []; const errors: string[] = []; let exitCode = 0; const originalLog = console.log; const originalError = console.error; const originalExit = process.exit; const originalCwd = process.cwd(); const { createProgram } = await loadMxCli(); console.log = (...args: unknown[]) => { logs.push(args.map((arg) => String(arg)).join(' ')); }; console.error = (...args: unknown[]) => { errors.push(args.map((arg) => String(arg)).join(' ')); }; (process as unknown as { exit: (code?: number) => never }).exit = ((code?: number) => { exitCode = code ?? 0; throw new Error(`process.exit(${exitCode})`); }) as never; if (options.cwd) { process.chdir(options.cwd); } try { const program = createProgram(); await program.parseAsync(argv); } catch (err) { const message = err instanceof Error ? err.message : String(err); if (!message.startsWith('process.exit(')) { throw err; } } finally { if (options.cwd) { process.chdir(originalCwd); } console.log = originalLog; console.error = originalError; (process as unknown as { exit: typeof process.exit }).exit = originalExit; } return { logs, errors, exitCode }; } export function parseLastJson(lines: readonly string[]): unknown { for (let i = lines.length - 1; i >= 0; i--) { const value = lines[i]?.trim() ?? ''; if (!value) continue; try { return JSON.parse(value); } catch { // continue } } throw new Error(`No JSON payload found in output:\n${lines.join('\n')}`); } export function assertExitCode(result: IRunMxCliResult, expected: number): void { assert.equal(result.exitCode, expected, `Expected exit code ${expected}, got ${result.exitCode}`); }