@bunli/test 0.1.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.
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../core/dist/index.js", "../src/test-command.ts", "../src/matchers.ts", "../src/helpers.ts"],
4
+ "sourcesContent": [
5
+ "// @bun\nvar __defProp = Object.defineProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, {\n get: all[name],\n enumerable: true,\n configurable: true,\n set: (newValue) => all[name] = () => newValue\n });\n};\nvar __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);\n\n// ../utils/dist/index.js\nvar exports_dist = {};\n__export(exports_dist, {\n validateFields: () => validateFields,\n validate: () => validate,\n utils: () => utils,\n spinner: () => createSpinner,\n select: () => select,\n prompt: () => prompt2,\n password: () => password,\n getDotPath: () => getDotPath2,\n confirm: () => confirm,\n colors: () => colors,\n SchemaError: () => SchemaError2\n});\nfunction createColorFunction(code) {\n return (text) => {\n if (!process.stdout.isTTY || process.env.NO_COLOR) {\n return text;\n }\n return `\\x1B[${code}m${text}\\x1B[0m`;\n };\n}\nfunction stripAnsi(text) {\n return text.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\nasync function readline(prompt) {\n process.stdout.write(prompt);\n for await (const line of console) {\n return line;\n }\n return \"\";\n}\nasync function prompt(message, options = {}) {\n const defaultHint = options.default ? ` (${options.default})` : \"\";\n const promptText = `${message}${defaultHint} `;\n while (true) {\n const input = await readline(promptText);\n const value = input.trim() || options.default || \"\";\n if (options.schema) {\n const result = await options.schema[\"~standard\"].validate(value);\n if (result.issues) {\n console.error(colors.red(\"Invalid input:\"));\n for (const issue of result.issues) {\n console.error(colors.dim(` \\u2022 ${issue.message}`));\n }\n console.error();\n continue;\n }\n return result.value;\n }\n if (options.validate) {\n const result = options.validate(value);\n if (result === true) {\n return value;\n } else if (typeof result === \"string\") {\n console.error(`\\u2717 ${result}`);\n continue;\n } else {\n console.error(\"\\u2717 Invalid input\");\n continue;\n }\n }\n return value;\n }\n}\nasync function confirm(message, options = {}) {\n const defaultHint = options.default === true ? \"Y/n\" : options.default === false ? \"y/N\" : \"y/n\";\n const promptText = `${message} (${defaultHint}) `;\n while (true) {\n const input = await readline(promptText);\n const value = input.trim().toLowerCase();\n if (!value && options.default !== undefined) {\n return options.default;\n }\n if (value === \"y\" || value === \"yes\") {\n return true;\n }\n if (value === \"n\" || value === \"no\") {\n return false;\n }\n console.error(\"\\u2717 Please answer with y/yes or n/no\");\n }\n}\nasync function select(message, options) {\n const { options: choices, default: defaultValue } = options;\n let selectedIndex = defaultValue ? choices.findIndex((opt) => opt.value === defaultValue) : 0;\n if (selectedIndex === -1)\n selectedIndex = 0;\n console.log(message);\n process.stdout.write(CURSOR_HIDE);\n drawOptions(choices, selectedIndex);\n return new Promise((resolve) => {\n process.stdin.setRawMode(true);\n process.stdin.resume();\n const cleanup = () => {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(CURSOR_SHOW);\n };\n process.stdin.on(\"data\", (data) => {\n const key = data.toString();\n if (key === \"\\x1B[A\") {\n selectedIndex = Math.max(0, selectedIndex - 1);\n drawOptions(choices, selectedIndex);\n } else if (key === \"\\x1B[B\") {\n selectedIndex = Math.min(choices.length - 1, selectedIndex + 1);\n drawOptions(choices, selectedIndex);\n } else if (key === \"\\r\" || key === `\n`) {\n cleanup();\n for (let i = 0;i < choices.length; i++) {\n process.stdout.write(`${CSI}1A${CLEAR_LINE}`);\n }\n const selected = choices[selectedIndex];\n if (selected) {\n console.log(`\\u2713 ${selected.label}`);\n resolve(selected.value);\n }\n } else if (key === \"\\x03\" || key === \"\\x1B\") {\n cleanup();\n process.exit(0);\n }\n });\n });\n}\nfunction drawOptions(options, selectedIndex) {\n for (let i = 0;i < options.length; i++) {\n process.stdout.write(`${CSI}1A`);\n }\n options.forEach((option, index) => {\n process.stdout.write(CLEAR_LINE + CURSOR_START);\n const prefix = index === selectedIndex ? \"\\u276F \" : \" \";\n const hint = option.hint ? ` (${option.hint})` : \"\";\n console.log(`${prefix}${option.label}${hint}`);\n });\n}\nasync function password(message, options = {}) {\n process.stdout.write(message + \" \");\n return new Promise((resolve) => {\n let input = \"\";\n process.stdin.setRawMode(true);\n process.stdin.resume();\n const cleanup = () => {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n console.log();\n };\n process.stdin.on(\"data\", async (data) => {\n const key = data.toString();\n if (key === \"\\r\" || key === `\n`) {\n cleanup();\n if (options.schema) {\n const result = await options.schema[\"~standard\"].validate(input);\n if (result.issues) {\n console.error(colors.red(\"Invalid input:\"));\n for (const issue of result.issues) {\n console.error(colors.dim(` \\u2022 ${issue.message}`));\n }\n console.error();\n password(message, options).then(resolve);\n return;\n }\n resolve(result.value);\n } else if (options.validate) {\n const result = options.validate(input);\n if (result === true) {\n resolve(input);\n } else {\n const errorMsg = typeof result === \"string\" ? result : \"Invalid input\";\n console.error(`\\u2717 ${errorMsg}`);\n password(message, options).then(resolve);\n }\n } else {\n resolve(input);\n }\n } else if (key === \"\\x03\") {\n cleanup();\n process.exit(0);\n } else if (key === \"\\x7F\" || key === \"\\b\") {\n if (input.length > 0) {\n input = input.slice(0, -1);\n process.stdout.write(\"\\b \\b\");\n }\n } else if (key.length === 1 && key >= \" \") {\n input += key;\n process.stdout.write(\"*\");\n }\n });\n });\n}\nfunction createSpinner(options) {\n const config = typeof options === \"string\" ? { text: options } : options || {};\n let isSpinning = false;\n let frameIndex = 0;\n let intervalId = null;\n let currentText = config.text || \"\";\n const render = (symbol, text) => {\n process.stdout.write(`${CLEAR_LINE2}${CURSOR_START2}${symbol} ${text}`);\n };\n const spinner = {\n start(text) {\n if (isSpinning)\n return;\n isSpinning = true;\n if (text !== undefined) {\n currentText = text;\n }\n process.stdout.write(\"\\x1B[?25l\");\n intervalId = setInterval(() => {\n const frame = SPINNER_FRAMES[frameIndex];\n render(frame, currentText);\n frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n }, 80);\n },\n stop(text) {\n if (!isSpinning)\n return;\n isSpinning = false;\n if (intervalId) {\n clearInterval(intervalId);\n intervalId = null;\n }\n process.stdout.write(CLEAR_LINE2 + CURSOR_START2);\n process.stdout.write(\"\\x1B[?25h\");\n if (text) {\n console.log(text);\n }\n },\n succeed(text) {\n this.stop();\n console.log(`\\u2705 ${text || currentText}`);\n },\n fail(text) {\n this.stop();\n console.log(`\\u274C ${text || currentText}`);\n },\n warn(text) {\n this.stop();\n console.log(`\\u26A0\\uFE0F ${text || currentText}`);\n },\n info(text) {\n this.stop();\n console.log(`\\u2139\\uFE0F ${text || currentText}`);\n },\n update(text) {\n currentText = text;\n if (isSpinning) {\n render(SPINNER_FRAMES[frameIndex], currentText);\n }\n }\n };\n process.on(\"exit\", () => spinner.stop());\n process.on(\"SIGINT\", () => {\n spinner.stop();\n process.exit(0);\n });\n return spinner;\n}\nfunction getDotPath2(issue) {\n if (issue.path?.length) {\n let dotPath = \"\";\n for (const item of issue.path) {\n const key = typeof item === \"object\" ? item.key : item;\n if (typeof key === \"string\" || typeof key === \"number\") {\n if (dotPath) {\n dotPath += `.${key}`;\n } else {\n dotPath += key;\n }\n } else {\n return null;\n }\n }\n return dotPath;\n }\n return null;\n}\nasync function validate(schema, value) {\n const result = await schema[\"~standard\"].validate(value);\n if (result.issues) {\n throw new SchemaError2(result.issues);\n }\n return result.value;\n}\nasync function validateFields(schemas, values) {\n const results = {};\n const errors = {};\n for (const [field, schema] of Object.entries(schemas)) {\n const result = await schema[\"~standard\"].validate(values[field]);\n if (result.issues) {\n errors[field] = result.issues.map((issue) => issue.message);\n } else {\n results[field] = result.value;\n }\n }\n if (Object.keys(errors).length > 0) {\n return { errors };\n }\n return results;\n}\nvar colorCodes, colors, ESC = \"\\x1B\", CSI, CLEAR_LINE, CURSOR_START, CURSOR_HIDE, CURSOR_SHOW, SPINNER_FRAMES, CLEAR_LINE2 = \"\\x1B[2K\", CURSOR_START2 = \"\\x1B[G\", SchemaError2, utils, prompt2;\nvar init_dist = __esm(() => {\n colorCodes = {\n black: 30,\n red: 31,\n green: 32,\n yellow: 33,\n blue: 34,\n magenta: 35,\n cyan: 36,\n white: 37,\n gray: 90,\n brightRed: 91,\n brightGreen: 92,\n brightYellow: 93,\n brightBlue: 94,\n brightMagenta: 95,\n brightCyan: 96,\n brightWhite: 97,\n bgRed: 41,\n bgGreen: 42,\n bgYellow: 43,\n bgBlue: 44,\n bgMagenta: 45,\n bgCyan: 46,\n bgWhite: 47,\n bold: 1,\n dim: 2,\n italic: 3,\n underline: 4,\n strikethrough: 9,\n reset: 0\n };\n colors = {\n black: createColorFunction(colorCodes.black),\n red: createColorFunction(colorCodes.red),\n green: createColorFunction(colorCodes.green),\n yellow: createColorFunction(colorCodes.yellow),\n blue: createColorFunction(colorCodes.blue),\n magenta: createColorFunction(colorCodes.magenta),\n cyan: createColorFunction(colorCodes.cyan),\n white: createColorFunction(colorCodes.white),\n gray: createColorFunction(colorCodes.gray),\n brightRed: createColorFunction(colorCodes.brightRed),\n brightGreen: createColorFunction(colorCodes.brightGreen),\n brightYellow: createColorFunction(colorCodes.brightYellow),\n brightBlue: createColorFunction(colorCodes.brightBlue),\n brightMagenta: createColorFunction(colorCodes.brightMagenta),\n brightCyan: createColorFunction(colorCodes.brightCyan),\n brightWhite: createColorFunction(colorCodes.brightWhite),\n bgRed: createColorFunction(colorCodes.bgRed),\n bgGreen: createColorFunction(colorCodes.bgGreen),\n bgYellow: createColorFunction(colorCodes.bgYellow),\n bgBlue: createColorFunction(colorCodes.bgBlue),\n bgMagenta: createColorFunction(colorCodes.bgMagenta),\n bgCyan: createColorFunction(colorCodes.bgCyan),\n bgWhite: createColorFunction(colorCodes.bgWhite),\n bold: createColorFunction(colorCodes.bold),\n dim: createColorFunction(colorCodes.dim),\n italic: createColorFunction(colorCodes.italic),\n underline: createColorFunction(colorCodes.underline),\n strikethrough: createColorFunction(colorCodes.strikethrough),\n reset: createColorFunction(colorCodes.reset),\n strip: stripAnsi\n };\n CSI = `${ESC}[`;\n CLEAR_LINE = `${CSI}2K`;\n CURSOR_START = `${CSI}G`;\n CURSOR_HIDE = `${CSI}?25l`;\n CURSOR_SHOW = `${CSI}?25h`;\n SPINNER_FRAMES = [\"\\u280B\", \"\\u2819\", \"\\u2839\", \"\\u2838\", \"\\u283C\", \"\\u2834\", \"\\u2826\", \"\\u2827\", \"\\u2807\", \"\\u280F\"];\n SchemaError2 = class extends Error {\n issues;\n constructor(issues) {\n super(issues[0].message);\n this.name = \"SchemaError\";\n this.issues = issues;\n }\n };\n utils = {\n prompt: Object.assign(prompt, {\n confirm,\n select,\n password\n }),\n spinner: createSpinner,\n colors\n };\n prompt2 = Object.assign(prompt, {\n confirm,\n select,\n password\n });\n});\n\n// ../../node_modules/@standard-schema/utils/dist/index.js\nfunction getDotPath(issue) {\n if (issue.path?.length) {\n let dotPath = \"\";\n for (const item of issue.path) {\n const key = typeof item === \"object\" ? item.key : item;\n if (typeof key === \"string\" || typeof key === \"number\") {\n if (dotPath) {\n dotPath += `.${key}`;\n } else {\n dotPath += key;\n }\n } else {\n return null;\n }\n }\n return dotPath;\n }\n return null;\n}\nvar SchemaError = class extends Error {\n issues;\n constructor(issues) {\n super(issues[0].message);\n this.name = \"SchemaError\";\n this.issues = issues;\n }\n};\n\n// src/parser.ts\nasync function parseArgs(args, options) {\n const flags = {};\n const positional = [];\n const shortToName = new Map;\n for (const [name, opt] of Object.entries(options)) {\n if (opt.short) {\n shortToName.set(opt.short, name);\n }\n }\n for (let i = 0;i < args.length; i++) {\n const arg = args[i];\n if (!arg)\n continue;\n if (arg.startsWith(\"--\")) {\n const eqIndex = arg.indexOf(\"=\");\n const name = eqIndex > 0 ? arg.slice(2, eqIndex) : arg.slice(2);\n const inlineValue = eqIndex > 0 ? arg.slice(eqIndex + 1) : undefined;\n if (!name || !options[name])\n continue;\n let value = inlineValue;\n if (value === undefined && i + 1 < args.length && !args[i + 1]?.startsWith(\"-\")) {\n value = args[++i];\n }\n flags[name] = await validateOption(name, value ?? \"true\", options[name].schema);\n } else if (arg.startsWith(\"-\") && arg.length > 1) {\n const short = arg.slice(1);\n const name = shortToName.get(short);\n if (name && options[name]) {\n let value;\n if (i + 1 < args.length && !args[i + 1]?.startsWith(\"-\")) {\n value = args[++i];\n }\n flags[name] = await validateOption(name, value ?? \"true\", options[name].schema);\n }\n } else {\n positional.push(arg);\n }\n }\n for (const [name, opt] of Object.entries(options)) {\n if (!(name in flags)) {\n flags[name] = await validateOption(name, undefined, opt.schema);\n }\n }\n return { flags, positional };\n}\nasync function validateOption(name, value, schema) {\n let processedValue = value;\n if (typeof value === \"string\" && (value === \"true\" || value === \"false\")) {\n const testResult = await schema[\"~standard\"].validate(true);\n if (!testResult.issues) {\n processedValue = value === \"true\";\n }\n }\n const result = await schema[\"~standard\"].validate(processedValue);\n if (result.issues) {\n const issuesWithPath = result.issues.map((issue) => ({\n ...issue,\n path: [name, ...issue.path || []]\n }));\n throw new SchemaError(issuesWithPath);\n }\n return result.value;\n}\n\n// src/cli.ts\nfunction createCLI(config) {\n const fullConfig = \"commands\" in config ? config : { ...config, commands: undefined };\n const commands = new Map;\n function registerCommand(cmd, path = []) {\n const fullName = [...path, cmd.name].join(\" \");\n commands.set(fullName, cmd);\n if (cmd.alias) {\n const aliases = Array.isArray(cmd.alias) ? cmd.alias : [cmd.alias];\n aliases.forEach((alias) => {\n const aliasPath = [...path, alias].join(\" \");\n commands.set(aliasPath, cmd);\n });\n }\n if (cmd.commands) {\n cmd.commands.forEach((subCmd) => {\n registerCommand(subCmd, [...path, cmd.name]);\n });\n }\n }\n function findCommand(args) {\n for (let i = args.length;i > 0; i--) {\n const cmdPath = args.slice(0, i).join(\" \");\n const command = commands.get(cmdPath);\n if (command) {\n return { command, remainingArgs: args.slice(i) };\n }\n }\n return { command: undefined, remainingArgs: args };\n }\n function showHelp(cmd, path = []) {\n if (!cmd) {\n console.log(`${fullConfig.name} v${fullConfig.version}`);\n if (fullConfig.description) {\n console.log(fullConfig.description);\n }\n console.log(`\nCommands:`);\n const topLevel = new Set;\n for (const [name, command] of commands) {\n if (!name.includes(\" \") && !command.alias?.includes(name)) {\n topLevel.add(command);\n }\n }\n for (const command of topLevel) {\n console.log(` ${command.name.padEnd(20)} ${command.description}`);\n }\n } else {\n const fullPath = [...path, cmd.name].join(\" \");\n console.log(`Usage: ${fullConfig.name} ${fullPath} [options]`);\n console.log(`\n${cmd.description}`);\n if (cmd.options && Object.keys(cmd.options).length > 0) {\n console.log(`\nOptions:`);\n for (const [name, opt] of Object.entries(cmd.options)) {\n const flag = `--${name}${opt.short ? `, -${opt.short}` : \"\"}`;\n const description = opt.description || \"\";\n console.log(` ${flag.padEnd(20)} ${description}`);\n }\n }\n if (cmd.commands && cmd.commands.length > 0) {\n console.log(`\nSubcommands:`);\n for (const subCmd of cmd.commands) {\n console.log(` ${subCmd.name.padEnd(20)} ${subCmd.description}`);\n }\n }\n }\n }\n async function loadFromConfig() {\n if (fullConfig.commands?.manifest) {\n try {\n const manifestPath = fullConfig.commands.manifest.startsWith(\".\") ? `${process.cwd()}/${fullConfig.commands.manifest}` : fullConfig.commands.manifest;\n const manifestModule = await import(manifestPath);\n const manifest = manifestModule.default || manifestModule;\n await loadCommandsFromManifest(manifest);\n } catch (error) {\n console.error(`Failed to load command manifest from ${fullConfig.commands.manifest}:`, error);\n }\n }\n }\n async function loadCommandsFromManifest(manifest) {\n async function loadFromManifest(obj, path = []) {\n const commands2 = [];\n if (typeof obj === \"function\") {\n const { default: command } = await obj();\n return [command];\n }\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === \"function\") {\n const { default: command } = await value();\n commands2.push(command);\n } else {\n const subCommands = await loadFromManifest(value, [...path, key]);\n if (subCommands.length > 0) {\n const parentCommand = {\n name: key,\n description: `${key} commands`,\n commands: subCommands\n };\n commands2.push(parentCommand);\n }\n }\n }\n return commands2;\n }\n const loadedCommands = await loadFromManifest(manifest);\n loadedCommands.forEach((cmd) => registerCommand(cmd));\n }\n return {\n command(cmd) {\n registerCommand(cmd);\n },\n async load(manifest) {\n await loadCommandsFromManifest(manifest);\n },\n async init() {\n await loadFromConfig();\n },\n async run(argv = process.argv.slice(2)) {\n if (argv.length === 0) {\n showHelp();\n return;\n }\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n const helpIndex = Math.max(argv.indexOf(\"--help\"), argv.indexOf(\"-h\"));\n const cmdArgs = argv.slice(0, helpIndex);\n if (cmdArgs.length === 0) {\n showHelp();\n } else {\n const { command: command2 } = findCommand(cmdArgs);\n if (command2) {\n showHelp(command2, cmdArgs.slice(0, -1));\n } else {\n console.error(`Unknown command: ${cmdArgs.join(\" \")}`);\n process.exit(1);\n }\n }\n return;\n }\n const { command, remainingArgs } = findCommand(argv);\n if (!command) {\n console.error(`Unknown command: ${argv[0]}`);\n process.exit(1);\n }\n if (!command.handler && command.commands) {\n showHelp(command, argv.slice(0, argv.length - remainingArgs.length - 1));\n return;\n }\n if (command.handler) {\n try {\n const parsed = await parseArgs(remainingArgs, command.options || {});\n const { prompt: prompt3, spinner, colors: colors2 } = await Promise.resolve().then(() => (init_dist(), exports_dist));\n await command.handler({\n flags: parsed.flags,\n positional: parsed.positional,\n shell: Bun.$,\n env: process.env,\n cwd: process.cwd(),\n prompt: prompt3,\n spinner,\n colors: colors2\n });\n } catch (error) {\n const { colors: colors2 } = await Promise.resolve().then(() => (init_dist(), exports_dist));\n if (error instanceof SchemaError) {\n console.error(colors2.red(\"Validation errors:\"));\n const fieldErrors = {};\n const generalErrors = [];\n for (const issue of error.issues) {\n const dotPath = getDotPath(issue);\n if (dotPath) {\n fieldErrors[dotPath] ??= [];\n fieldErrors[dotPath].push(issue.message);\n } else {\n generalErrors.push(issue.message);\n }\n }\n for (const [field, messages] of Object.entries(fieldErrors)) {\n console.error(colors2.yellow(` --${field}:`));\n for (const message of messages) {\n console.error(colors2.dim(` \\u2022 ${message}`));\n }\n }\n for (const message of generalErrors) {\n console.error(colors2.dim(` \\u2022 ${message}`));\n }\n process.exit(1);\n } else if (error instanceof Error) {\n console.error(colors2.red(`Error: ${error.message}`));\n process.exit(1);\n }\n throw error;\n }\n }\n }\n };\n}\n// src/types.ts\nfunction defineCommand(command) {\n return command;\n}\nfunction defineConfig(config) {\n return config;\n}\nfunction option(schema, metadata) {\n return {\n schema,\n ...metadata\n };\n}\nexport {\n option,\n defineConfig,\n defineCommand,\n createCLI,\n SchemaError\n};\n",
6
+ "import type { Command } from '@bunli/core'\nimport type { TestOptions, TestResult, MockHandlerArgs, ShellPromise } from './types.js'\nimport { createCLI } from '@bunli/core'\n\nexport async function testCommand(\n command: Command<any>,\n options: TestOptions = {}\n): Promise<TestResult> {\n const startTime = performance.now()\n \n // Capture output\n const stdout: string[] = []\n const stderr: string[] = []\n let exitCode = 0\n let error: Error | undefined\n \n // Setup stdin mock\n const stdinLines = Array.isArray(options.stdin) \n ? [...options.stdin]\n : options.stdin \n ? [options.stdin]\n : []\n \n // Setup mock prompts map\n const mockPromptsMap = options.mockPrompts || {}\n const promptResponsesUsed = new Map<string, number>()\n \n // Create mock prompt\n const mockPrompt = Object.assign(\n async (message: string, options?: any): Promise<any> => {\n stdout.push(message)\n \n // Check if we have a mock response for this prompt\n let response: string\n if (mockPromptsMap[message]) {\n const responses = mockPromptsMap[message]\n const usedCount = promptResponsesUsed.get(message) || 0\n \n if (Array.isArray(responses)) {\n response = responses[usedCount] ?? responses[responses.length - 1] ?? ''\n promptResponsesUsed.set(message, usedCount + 1)\n } else {\n response = responses ?? ''\n }\n } else {\n response = stdinLines.shift() || ''\n }\n \n stdout.push(response)\n \n // Handle schema validation if provided\n if (options?.schema) {\n const result = await options.schema['~standard'].validate(response)\n if (result.issues) {\n // Simulate validation error output\n stderr.push('[red]Invalid input:[/red]')\n for (const issue of result.issues) {\n stderr.push(`[dim] • ${issue.message}[/dim]`)\n }\n // Check if we have more responses to try\n const hasMoreMockResponses = mockPromptsMap[message] && Array.isArray(mockPromptsMap[message]) && \n (promptResponsesUsed.get(message) || 0) < mockPromptsMap[message].length\n const hasMoreStdin = stdinLines.length > 0\n \n if (hasMoreMockResponses || hasMoreStdin) {\n return mockPrompt(message, options) // Retry with next input\n }\n // If no more inputs, return undefined like real prompt would\n return undefined\n }\n return result.value\n }\n \n // Handle custom validation\n if (options?.validate) {\n const validationResult = options.validate(response)\n if (validationResult !== true) {\n const errorMsg = typeof validationResult === 'string' ? validationResult : 'Invalid input'\n stderr.push(`✗ ${errorMsg}`)\n // Retry if more input available\n if (stdinLines.length > 0) {\n return mockPrompt(message, options)\n }\n }\n }\n \n return response\n },\n {\n confirm: async (message: string, opts?: any) => {\n stdout.push(message)\n \n let response: string\n if (mockPromptsMap[message]) {\n const responses = mockPromptsMap[message]\n const usedCount = promptResponsesUsed.get(message) || 0\n \n if (Array.isArray(responses)) {\n response = responses[usedCount] ?? responses[responses.length - 1] ?? ''\n promptResponsesUsed.set(message, usedCount + 1)\n } else {\n response = responses ?? ''\n }\n } else {\n response = stdinLines.shift() || ''\n }\n \n stdout.push(response)\n const normalized = response.toLowerCase().trim()\n return normalized === 'y' || normalized === 'yes' || (opts?.default && normalized === '')\n },\n select: async <T = string>(message: string, selectOptions: { options: any[], default?: T, hint?: string }) => {\n stdout.push(message)\n selectOptions.options.forEach((choice, i) => {\n const label = typeof choice === 'object' ? choice.label : choice\n stdout.push(` ${i + 1}. ${label}`)\n })\n \n let response: string\n if (mockPromptsMap[message]) {\n const responses = mockPromptsMap[message]\n const usedCount = promptResponsesUsed.get(message) || 0\n \n if (Array.isArray(responses)) {\n response = responses[usedCount] ?? responses[responses.length - 1] ?? ''\n promptResponsesUsed.set(message, usedCount + 1)\n } else {\n response = responses ?? ''\n }\n } else {\n response = stdinLines.shift() || '1'\n }\n \n stdout.push(`> ${response}`)\n const index = parseInt(response) - 1\n const choice = selectOptions.options[index] || selectOptions.options[0]\n return (typeof choice === 'object' ? choice.value : choice) as T\n },\n password: async (message: string, options?: any): Promise<any> => {\n stdout.push(message)\n \n let response: string\n if (mockPromptsMap[message]) {\n const responses = mockPromptsMap[message]\n const usedCount = promptResponsesUsed.get(message) || 0\n \n if (Array.isArray(responses)) {\n response = responses[usedCount] ?? responses[responses.length - 1] ?? ''\n promptResponsesUsed.set(message, usedCount + 1)\n } else {\n response = responses ?? ''\n }\n } else {\n response = stdinLines.shift() || ''\n }\n \n stdout.push('*'.repeat(response.length))\n \n // Handle schema validation if provided\n if (options?.schema) {\n const result = await options.schema['~standard'].validate(response)\n if (result.issues) {\n stderr.push('[red]Invalid input:[/red]')\n for (const issue of result.issues) {\n stderr.push(`[dim] • ${issue.message}[/dim]`)\n }\n // Check if we have more responses to try\n const hasMoreMockResponses = mockPromptsMap[message] && Array.isArray(mockPromptsMap[message]) && \n (promptResponsesUsed.get(message) || 0) < mockPromptsMap[message].length\n const hasMoreStdin = stdinLines.length > 0\n \n if (hasMoreMockResponses || hasMoreStdin) {\n return mockPrompt.password(message, options) // Retry with next input\n }\n return undefined\n }\n return result.value\n }\n \n return response\n },\n multiselect: async <T = string>(message: string, selectOptions: { options: any[] }) => {\n stdout.push(message)\n selectOptions.options.forEach((choice, i) => {\n const label = typeof choice === 'object' ? choice.label : choice\n stdout.push(` [ ] ${i + 1}. ${label}`)\n })\n \n let response: string\n if (mockPromptsMap[message]) {\n const responses = mockPromptsMap[message]\n const usedCount = promptResponsesUsed.get(message) || 0\n \n if (Array.isArray(responses)) {\n response = responses[usedCount] ?? responses[responses.length - 1] ?? ''\n promptResponsesUsed.set(message, usedCount + 1)\n } else {\n response = responses ?? ''\n }\n } else {\n response = stdinLines.shift() || ''\n }\n \n stdout.push(`> ${response}`)\n const indices = response.split(',').map(s => parseInt(s.trim()) - 1)\n return indices\n .filter(i => i >= 0 && i < selectOptions.options.length)\n .map(i => {\n const choice = selectOptions.options[i]\n return (typeof choice === 'object' ? choice.value : choice) as T\n })\n }\n }\n )\n \n // Create mock spinner\n const mockSpinner = (text?: string) => {\n if (text) stdout.push(`⠋ ${text}`)\n return {\n start: (text?: string) => {\n if (text) stdout.push(`⠋ ${text}`)\n },\n stop: (text?: string) => {\n if (text) stdout.push(text)\n },\n succeed: (text?: string) => {\n stdout.push(`✅ ${text || 'Done'}`)\n },\n fail: (text?: string) => {\n stdout.push(`❌ ${text || 'Failed'}`)\n },\n warn: (text?: string) => {\n stdout.push(`⚠️ ${text || 'Warning'}`)\n },\n info: (text?: string) => {\n stdout.push(`ℹ️ ${text || 'Info'}`)\n },\n update: (text: string) => {\n stdout.push(`⠋ ${text}`)\n }\n }\n }\n \n // Create mock shell\n const mockShellCommands = options.mockShellCommands || {}\n \n const mockShell = (strings: TemplateStringsArray, ...values: any[]) => {\n const command = strings.reduce((acc, str, i) => {\n return acc + str + (values[i] || '')\n }, '').trim()\n \n stdout.push(`$ ${command}`)\n \n const promise = Promise.resolve() as ShellPromise\n \n promise.text = async () => {\n // Check mock commands first\n if (mockShellCommands[command]) {\n return mockShellCommands[command]\n }\n \n // Default mock responses\n if (command.includes('git branch --show-current')) {\n return 'main\\n'\n }\n if (command.includes('git status')) {\n return 'nothing to commit, working tree clean\\n'\n }\n return ''\n }\n \n promise.json = async () => {\n // Check if we have a mock response that looks like JSON\n if (mockShellCommands[command]) {\n try {\n return JSON.parse(mockShellCommands[command])\n } catch {\n // Not JSON, return empty object\n return {} as any\n }\n }\n return {} as any\n }\n \n promise.quiet = () => promise\n \n return promise\n }\n \n // Mock colors\n const mockColors = {\n red: (text: string) => `[red]${text}[/red]`,\n green: (text: string) => `[green]${text}[/green]`,\n blue: (text: string) => `[blue]${text}[/blue]`,\n yellow: (text: string) => `[yellow]${text}[/yellow]`,\n cyan: (text: string) => `[cyan]${text}[/cyan]`,\n magenta: (text: string) => `[magenta]${text}[/magenta]`,\n gray: (text: string) => `[gray]${text}[/gray]`,\n dim: (text: string) => `[dim]${text}[/dim]`,\n bold: (text: string) => `[bold]${text}[/bold]`,\n italic: (text: string) => `[italic]${text}[/italic]`,\n underline: (text: string) => `[underline]${text}[/underline]`,\n strikethrough: (text: string) => `[strikethrough]${text}[/strikethrough]`,\n bgRed: (text: string) => `[bgRed]${text}[/bgRed]`,\n bgGreen: (text: string) => `[bgGreen]${text}[/bgGreen]`,\n bgBlue: (text: string) => `[bgBlue]${text}[/bgBlue]`,\n bgYellow: (text: string) => `[bgYellow]${text}[/bgYellow]`,\n bgCyan: (text: string) => `[bgCyan]${text}[/bgCyan]`,\n bgMagenta: (text: string) => `[bgMagenta]${text}[/bgMagenta]`,\n bgGray: (text: string) => `[bgGray]${text}[/bgGray]`,\n black: (text: string) => `[black]${text}[/black]`,\n white: (text: string) => `[white]${text}[/white]`,\n bgBlack: (text: string) => `[bgBlack]${text}[/bgBlack]`,\n bgWhite: (text: string) => `[bgWhite]${text}[/bgWhite]`,\n // Add missing bright colors\n brightRed: (text: string) => `[brightRed]${text}[/brightRed]`,\n brightGreen: (text: string) => `[brightGreen]${text}[/brightGreen]`,\n brightYellow: (text: string) => `[brightYellow]${text}[/brightYellow]`,\n brightBlue: (text: string) => `[brightBlue]${text}[/brightBlue]`,\n brightCyan: (text: string) => `[brightCyan]${text}[/brightCyan]`,\n brightMagenta: (text: string) => `[brightMagenta]${text}[/brightMagenta]`,\n brightWhite: (text: string) => `[brightWhite]${text}[/brightWhite]`,\n reset: (text: string) => `[reset]${text}[/reset]`,\n strip: (text: string) => text.replace(/\\[[^\\]]+\\]/g, '')\n }\n \n // Override console methods\n const originalLog = console.log\n const originalError = console.error\n \n console.log = (...args: any[]) => {\n stdout.push(args.join(' '))\n }\n \n console.error = (...args: any[]) => {\n stderr.push(args.join(' '))\n }\n \n try {\n // Create handler args\n const handlerArgs: MockHandlerArgs = {\n flags: options.flags || {},\n positional: options.args || [],\n env: { ...process.env, ...(options.env || {}) },\n cwd: options.cwd || process.cwd(),\n prompt: mockPrompt,\n spinner: mockSpinner,\n shell: mockShell as any,\n colors: mockColors\n }\n \n // Execute command handler\n if (command.handler) {\n await command.handler(handlerArgs as any)\n }\n \n exitCode = options.exitCode || 0\n } catch (err) {\n error = err as Error\n exitCode = 1\n stderr.push(error.message)\n } finally {\n // Restore console methods\n console.log = originalLog\n console.error = originalError\n }\n \n const duration = performance.now() - startTime\n \n return {\n stdout: stdout.join('\\n'),\n stderr: stderr.join('\\n'),\n exitCode,\n duration,\n error\n }\n}\n\nexport async function testCLI(\n setupCLI: (cli: ReturnType<typeof createCLI>) => void,\n argv: string[],\n options: Omit<TestOptions, 'args'> = {}\n): Promise<TestResult> {\n const startTime = performance.now()\n \n // Capture output\n const stdout: string[] = []\n const stderr: string[] = []\n let exitCode = 0\n let error: Error | undefined\n \n // Override console methods\n const originalLog = console.log\n const originalError = console.error\n const originalExit = process.exit\n \n console.log = (...args: any[]) => {\n stdout.push(args.join(' '))\n }\n \n console.error = (...args: any[]) => {\n stderr.push(args.join(' '))\n }\n \n ;(process.exit as any) = (code?: number) => {\n exitCode = code || 0\n throw new Error(`Process exited with code ${exitCode}`)\n }\n \n try {\n // Create and setup CLI\n const cli = createCLI({\n name: 'test-cli',\n version: '1.0.0',\n description: 'Test CLI'\n })\n \n setupCLI(cli)\n \n // Run CLI with arguments\n await cli.run(argv)\n \n } catch (err: any) {\n if (!err.message.startsWith('Process exited with code')) {\n error = err\n exitCode = 1\n stderr.push(error?.message || 'Unknown error')\n }\n } finally {\n // Restore methods\n console.log = originalLog\n console.error = originalError\n process.exit = originalExit\n }\n \n const duration = performance.now() - startTime\n \n return {\n stdout: stdout.join('\\n'),\n stderr: stderr.join('\\n'),\n exitCode,\n duration,\n error\n }\n}",
7
+ "import type { TestResult } from './types.js'\n\nexport interface Matchers {\n toHaveExitCode(code: number): void\n toHaveSucceeded(): void\n toHaveFailed(): void\n toContainInStdout(text: string): void\n toContainInStderr(text: string): void\n toMatchStdout(pattern: RegExp): void\n toMatchStderr(pattern: RegExp): void\n}\n\nexport function createMatchers(result: TestResult): Matchers {\n return {\n toHaveExitCode(code: number) {\n if (result.exitCode !== code) {\n throw new Error(\n `Expected exit code ${code}, but got ${result.exitCode}\\n` +\n `stdout: ${result.stdout}\\n` +\n `stderr: ${result.stderr}`\n )\n }\n },\n \n toHaveSucceeded() {\n if (result.exitCode !== 0) {\n throw new Error(\n `Expected command to succeed (exit code 0), but got ${result.exitCode}\\n` +\n `stdout: ${result.stdout}\\n` +\n `stderr: ${result.stderr}\\n` +\n (result.error ? `error: ${result.error.message}` : '')\n )\n }\n },\n \n toHaveFailed() {\n if (result.exitCode === 0) {\n throw new Error(\n `Expected command to fail (non-zero exit code), but it succeeded\\n` +\n `stdout: ${result.stdout}`\n )\n }\n },\n \n toContainInStdout(text: string) {\n if (!result.stdout.includes(text)) {\n throw new Error(\n `Expected stdout to contain \"${text}\"\\n` +\n `stdout: ${result.stdout}`\n )\n }\n },\n \n toContainInStderr(text: string) {\n if (!result.stderr.includes(text)) {\n throw new Error(\n `Expected stderr to contain \"${text}\"\\n` +\n `stderr: ${result.stderr}`\n )\n }\n },\n \n toMatchStdout(pattern: RegExp) {\n if (!pattern.test(result.stdout)) {\n throw new Error(\n `Expected stdout to match ${pattern}\\n` +\n `stdout: ${result.stdout}`\n )\n }\n },\n \n toMatchStderr(pattern: RegExp) {\n if (!pattern.test(result.stderr)) {\n throw new Error(\n `Expected stderr to match ${pattern}\\n` +\n `stderr: ${result.stderr}`\n )\n }\n }\n }\n}\n\n// Extend expect for better integration\ndeclare global {\n namespace jest {\n interface Matchers<R> {\n toHaveExitCode(code: number): R\n toHaveSucceeded(): R\n toHaveFailed(): R\n toContainInStdout(text: string): R\n toContainInStderr(text: string): R\n toMatchStdout(pattern: RegExp): R\n toMatchStderr(pattern: RegExp): R\n }\n }\n}\n\n// Helper to add matchers to expect result\nexport function expectCommand(result: TestResult) {\n const matchers = createMatchers(result)\n \n return {\n ...result,\n ...matchers\n }\n}",
8
+ "import type { TestOptions } from './types.js'\n\n/**\n * Helper to create test options with mock prompt responses\n * @param responses - Map of prompt messages to responses\n * @example\n * mockPromptResponses({\n * 'Enter name:': 'Alice',\n * 'Enter age:': ['invalid', '25'], // Multiple attempts for validation\n * 'Continue?': 'y'\n * })\n */\nexport function mockPromptResponses(responses: Record<string, string | string[]>): Pick<TestOptions, 'mockPrompts'> {\n return { mockPrompts: responses }\n}\n\n/**\n * Helper to create test options with mock shell command outputs\n * @param commands - Map of shell commands to their outputs\n * @example\n * mockShellCommands({\n * 'git status': 'On branch main\\nnothing to commit',\n * 'npm --version': '10.2.0',\n * 'node --version': 'v20.10.0'\n * })\n */\nexport function mockShellCommands(commands: Record<string, string>): Pick<TestOptions, 'mockShellCommands'> {\n return { mockShellCommands: commands }\n}\n\n/**\n * Helper to create test options for interactive commands\n * @param prompts - Prompt responses\n * @param commands - Shell command outputs\n * @example\n * mockInteractive(\n * { 'Name:': 'Alice', 'Continue?': 'y' },\n * { 'git status': 'clean' }\n * )\n */\nexport function mockInteractive(\n prompts: Record<string, string | string[]>,\n commands?: Record<string, string>\n): TestOptions {\n return {\n ...mockPromptResponses(prompts),\n ...(commands ? mockShellCommands(commands) : {})\n }\n}\n\n/**\n * Helper to create stdin input for validation testing\n * Useful for testing retry behavior with invalid inputs\n * @param attempts - Array of input attempts\n * @example\n * mockValidationAttempts(['invalid-email', 'still-bad', 'valid@email.com'])\n */\nexport function mockValidationAttempts(attempts: string[]): Pick<TestOptions, 'stdin'> {\n return { stdin: attempts }\n}\n\n/**\n * Helper to combine multiple test option objects\n * @param options - Test option objects to merge\n * @example\n * mergeTestOptions(\n * { flags: { verbose: true } },\n * mockPromptResponses({ 'Name:': 'Alice' }),\n * { env: { NODE_ENV: 'test' } }\n * )\n */\nexport function mergeTestOptions(...options: Partial<TestOptions>[]): TestOptions {\n const merged: TestOptions = {}\n \n for (const opt of options) {\n // Handle stdin/mockPrompts specially to combine them\n if (opt.stdin || opt.mockPrompts) {\n const stdinArray: string[] = []\n \n // Add existing stdin\n if (merged.stdin) {\n if (Array.isArray(merged.stdin)) {\n stdinArray.push(...merged.stdin)\n } else {\n stdinArray.push(merged.stdin)\n }\n }\n \n // Add new stdin\n if (opt.stdin) {\n if (Array.isArray(opt.stdin)) {\n stdinArray.push(...opt.stdin)\n } else {\n stdinArray.push(opt.stdin)\n }\n }\n \n if (stdinArray.length > 0) {\n merged.stdin = stdinArray\n }\n }\n \n // Merge other properties\n Object.assign(merged, opt)\n }\n \n return merged\n}"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "CC322262A7E5B8FD64756E2164756E21",
12
+ "names": []
13
+ }
@@ -0,0 +1,38 @@
1
+ import type { TestResult } from './types.js';
2
+ export interface Matchers {
3
+ toHaveExitCode(code: number): void;
4
+ toHaveSucceeded(): void;
5
+ toHaveFailed(): void;
6
+ toContainInStdout(text: string): void;
7
+ toContainInStderr(text: string): void;
8
+ toMatchStdout(pattern: RegExp): void;
9
+ toMatchStderr(pattern: RegExp): void;
10
+ }
11
+ export declare function createMatchers(result: TestResult): Matchers;
12
+ declare global {
13
+ namespace jest {
14
+ interface Matchers<R> {
15
+ toHaveExitCode(code: number): R;
16
+ toHaveSucceeded(): R;
17
+ toHaveFailed(): R;
18
+ toContainInStdout(text: string): R;
19
+ toContainInStderr(text: string): R;
20
+ toMatchStdout(pattern: RegExp): R;
21
+ toMatchStderr(pattern: RegExp): R;
22
+ }
23
+ }
24
+ }
25
+ export declare function expectCommand(result: TestResult): {
26
+ toHaveExitCode(code: number): void;
27
+ toHaveSucceeded(): void;
28
+ toHaveFailed(): void;
29
+ toContainInStdout(text: string): void;
30
+ toContainInStderr(text: string): void;
31
+ toMatchStdout(pattern: RegExp): void;
32
+ toMatchStderr(pattern: RegExp): void;
33
+ stdout: string;
34
+ stderr: string;
35
+ exitCode: number;
36
+ duration: number;
37
+ error?: Error;
38
+ };
@@ -0,0 +1,5 @@
1
+ import type { Command } from '@bunli/core';
2
+ import type { TestOptions, TestResult } from './types.js';
3
+ import { createCLI } from '@bunli/core';
4
+ export declare function testCommand(command: Command<any>, options?: TestOptions): Promise<TestResult>;
5
+ export declare function testCLI(setupCLI: (cli: ReturnType<typeof createCLI>) => void, argv: string[], options?: Omit<TestOptions, 'args'>): Promise<TestResult>;
@@ -0,0 +1,67 @@
1
+ import type { HandlerArgs } from '@bunli/core';
2
+ export interface TestOptions {
3
+ /** Command flags to pass */
4
+ flags?: Record<string, unknown>;
5
+ /** Positional arguments */
6
+ args?: string[];
7
+ /** Environment variables */
8
+ env?: Record<string, string>;
9
+ /** Current working directory */
10
+ cwd?: string;
11
+ /** Input for prompts (line by line) */
12
+ stdin?: string | string[];
13
+ /** Mock prompt responses mapped by prompt message */
14
+ mockPrompts?: Record<string, string | string[]>;
15
+ /** Mock shell command outputs */
16
+ mockShellCommands?: Record<string, string>;
17
+ /** Exit code to expect */
18
+ exitCode?: number;
19
+ }
20
+ export interface TestResult {
21
+ /** Captured stdout */
22
+ stdout: string;
23
+ /** Captured stderr */
24
+ stderr: string;
25
+ /** Exit code */
26
+ exitCode: number;
27
+ /** Execution time in ms */
28
+ duration: number;
29
+ /** Any error thrown */
30
+ error?: Error;
31
+ }
32
+ export interface MockHandlerArgs extends Omit<HandlerArgs, 'prompt' | 'spinner' | 'shell'> {
33
+ prompt: {
34
+ (message: string, options?: any): Promise<string>;
35
+ confirm: (message: string, options?: any) => Promise<boolean>;
36
+ select: <T = string>(message: string, options: any) => Promise<T>;
37
+ password: (message: string, options?: any) => Promise<string>;
38
+ multiselect: <T = string>(message: string, options: any) => Promise<T[]>;
39
+ };
40
+ spinner: (text?: string) => {
41
+ start: (text?: string) => void;
42
+ stop: (text?: string) => void;
43
+ succeed: (text?: string) => void;
44
+ fail: (text?: string) => void;
45
+ warn: (text?: string) => void;
46
+ info: (text?: string) => void;
47
+ update: (text: string) => void;
48
+ };
49
+ shell: MockShell;
50
+ }
51
+ export interface Matchers {
52
+ toHaveExitCode(code: number): void;
53
+ toHaveSucceeded(): void;
54
+ toHaveFailed(): void;
55
+ toContainInStdout(text: string): void;
56
+ toContainInStderr(text: string): void;
57
+ toMatchStdout(pattern: RegExp): void;
58
+ toMatchStderr(pattern: RegExp): void;
59
+ }
60
+ export interface MockShell {
61
+ (strings: TemplateStringsArray, ...values: any[]): ShellPromise;
62
+ }
63
+ export interface ShellPromise extends Promise<void> {
64
+ text(): Promise<string>;
65
+ json<T = any>(): Promise<T>;
66
+ quiet(): ShellPromise;
67
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@bunli/test",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Testing utilities for Bunli CLI applications",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "author": "Arya Labs, Inc.",
18
+ "license": "MIT",
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/AryaLabsHQ/bunli.git",
25
+ "directory": "packages/test"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/AryaLabsHQ/bunli/issues"
29
+ },
30
+ "homepage": "https://github.com/AryaLabsHQ/bunli#readme",
31
+ "keywords": [
32
+ "bunli",
33
+ "test",
34
+ "testing",
35
+ "cli",
36
+ "bun",
37
+ "typescript",
38
+ "matchers",
39
+ "assertions"
40
+ ],
41
+ "scripts": {
42
+ "build": "bun scripts/build.ts && bun run tsc",
43
+ "test": "bun test",
44
+ "type-check": "tsc --noEmit"
45
+ },
46
+ "peerDependencies": {
47
+ "bun": ">=1.0.0"
48
+ },
49
+ "dependencies": {
50
+ "@bunli/core": "0.1.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/bun": "latest",
54
+ "bun-types": "latest",
55
+ "typescript": "^5.8.0"
56
+ }
57
+ }