Skip to content

Test Utilities

Rune provides runCommand() for testing commands in-process without spawning a child process. Import it from @rune-cli/rune/test.

import { runCommand } from "@rune-cli/rune/test";
import { expect, test } from "vitest";
import greeting from "../src/commands/index.ts";
test("greets by name", async () => {
const result = await runCommand(greeting, ["world"]);
expect(result.exitCode).toBe(0);
expect(result.stdout).toBe("Hello, world!\n");
});

Exercises a command through Rune’s parse-and-execute pipeline. Input is passed as a string[] of CLI tokens, so argv parsing, type coercion, schema validation, and default handling all run exactly as they do at real invocation.

function runCommand(
command: DefinedCommand,
argv?: string[],
context?: RunCommandContext,
): Promise<CommandExecutionResult>
  • Type: DefinedCommand
  • Required

A command created by defineCommand().

  • Type: string[]
  • Default: []

CLI tokens forwarded to the command.

  • Type: RunCommandContext
  • Default: {}

Optional execution context.

  • Type: string
  • Optional

Working directory value injected into ctx.cwd. Does not change process.cwd().

  • Type: number

Process exit code (0 for success).

  • Type: string

Captured stdout output.

  • Type: string

Captured stderr output.

  • Type: CommandFailure | undefined

Structured error information, if the command failed.

  • Type: unknown

Return value from run() when the command uses json: true. This is populated regardless of whether --json is passed; the --json flag controls whether output.info() is suppressed, not whether data is captured.

test("requires an id argument", async () => {
const result = await runCommand(command, []);
expect(result.exitCode).toBe(1);
expect(result.stderr).not.toBe("");
});
const command = defineCommand({
options: [{ name: "count", type: "number", default: 1 }],
run({ options, output }) {
output.info(`count=${options.count}`);
},
});
test("uses default count", async () => {
const result = await runCommand(command, []);
expect(result.stdout).toBe("count=1\n");
});
const command = defineCommand({
json: true,
run() {
return { items: [1, 2, 3] };
},
});
test("returns structured data", async () => {
const result = await runCommand(command, ["--json"]);
expect(result.data).toEqual({ items: [1, 2, 3] });
expect(result.stdout).toBe("");
});