2.5 KiB
run-plugin
Purpose
End-to-end test harness for plugins. runPlugin(plugin, options) wires up
an in-memory filesystem, a scripted CLI, a no-op logger, and a basic
template engine, then drives the plugin through the full
detect → prompts → plan → apply → postInstall pipeline. Returns the
filesystem and the recorded CLI interaction so tests can assert on what
was written and what was prompted. Zero real disk I/O.
Features
- Sensible defaults: in-memory
MemoryFs, scriptedScriptCli, no-op logger,{{var}}-style template engine — all overridable. - Returns
{ ops, summary, handle, dryRun, fs, cli }so tests can inspect the plan, the resulting fs, and the prompt history. - Same
RunOptionssurface asHost.run:dryRun,force,noInteractive,only,exclude,signal. - Defaults
noInteractivetotrueso test runs never block on a prompt that wasn't scripted.
Basic Example
import { runPlugin } from "@suaveplan/installer";
const result = await runPlugin(myPlugin, {
answers: { targetDir: "/.suaveplan/skills" },
});
expect(result.summary.written).toBe(5);
Advanced Example
import { runPlugin, ScriptCli } from "@suaveplan/installer";
const cli = new ScriptCli({ confirm: [true, false] });
const ac = new AbortController();
const result = await runPlugin(myPlugin, {
cli,
signal: ac.signal,
answers: { skills: ["echo", "crypto"] },
only: ["crypto"],
force: false,
});
expect(cli.record.confirms).toEqual([
{ message: "Overwrite existing file?", answer: true },
]);
expect(result.ops.every((op) => op.path.includes("crypto"))).toBe(true);
API Reference
runPlugin<TAnswers, THandle>(plugin, options): Promise<RunPluginResult<THandle>>interface RunPluginOptions<TAnswers>—{ answers?, fs?, cli?, cwd?, logger?, templates?, signal?, dryRun?, force?, noInteractive?, only?, exclude? }.interface RunPluginResult<THandle> extends HostRunResult<THandle>— addsfs: MemoryFsandcli: InstallerCli.
Implementation Notes
The default template engine handles only {{varName}} substitution and
returns empty string for unknown vars — that's enough for plugin tests
that don't care about templates and avoids adding a dependency on
@suaveplan/templates to the test surface. The default cwd is /
(POSIX root in MemoryFs's namespace) so paths in plans can be written
literally. Tests that need a different cwd should pass it explicitly;
both DiskFs and MemoryFs honour the value identically.