Skip to content

Provide an in-process Toolcraft command unit-test harness #501

Description

@kamilio

Summary

Toolcraft needs an in-process unit-test harness for command behavior, not a dry-run convention.

Downstream tools need to prove that validation, defaults, secrets, requirements, errors, service injection, and side-effect ordering behave identically across the CLI, MCP, and SDK surfaces. Today, tests either call createSDK(root) directly—which skips useful runner-level observability—or spawn the built CLI/MCP process and parse output. The latter is slow and makes it difficult to assert that invalid input failed before authentication, network calls, locks, or filesystem writes.

This is related to, but distinct from, closed issue #496. A deterministic command-tree snapshot proves surface shape; it does not execute a command through Toolcraft's runtime pipeline or provide controlled fakes and captured effects.

Requested API

Provide a supported testing utility along these lines:

const harness = createCommandTestHarness(root, {
  services: fakeServices,
  env: { HOMEY_PAT: "test" },
  secrets: { pat: "test" },
});

const result = await harness.run(["sync"], {
  root: fixtureRoot,
  id: "flow-1",
});

expect(result.value).toEqual(...);
expect(result.logs).toEqual(...);
expect(result.progress).toEqual(...);
expect(result.error).toBeInstanceOf(UserError);
expect(fakeServices.homey.calls).toEqual([]);

The goal is deterministic unit testing of real command execution. It should not add or standardize a product-level dryRun flag.

Required capabilities

  • Resolve a command by path from the same defineGroup tree used by CLI/MCP/SDK.
  • Run schema parsing/defaults, requirements, secrets, service injection, and the handler in-process.
  • Supply explicit environment/secrets without reading the developer's real process environment or credential stores.
  • Capture raw result, UserError/HTTP errors, logs, progress events, confirmation requests, and rendered output without writing to global stdout/stderr.
  • Make it easy to assert that validation or requirements prevented handler/service invocation.
  • Allow deterministic fake clock, fetch, filesystem, and injected services where Toolcraft exposes them.
  • Optionally run the same case through SDK/CLI/MCP adapters to assert parity without spawning child processes.

Acceptance criteria

  • Toolcraft documents a first-class unit-test helper with TypeScript types.
  • A fixture command can be tested for successful result, validation failure, secret injection, requirement failure, and captured rendering entirely in-process.
  • A test can prove that invalid parameters do not invoke the handler or injected services.
  • The harness does not require a dry-run mode in application commands.
  • The harness output is deterministic and suitable for normal assertions or snapshots.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions