use processkit::testing::{RecordingRunner, Reply, ScriptedRunner};
use processkit::{Command, ProcessRunner, ProcessRunnerExt, Result};
async fn describe_repo(runner: &impl ProcessRunner) -> Result<String> {
let clean = runner
.probe(&Command::new("git").args(["diff", "--quiet"]))
.await?;
if !clean {
return Ok("dirty working tree".to_string());
}
let branch = runner
.run(&Command::new("git").args(["branch", "--show-current"]))
.await?;
Ok(format!("clean on {branch}"))
}
#[tokio::main]
async fn main() -> Result<()> {
let runner = RecordingRunner::new(
ScriptedRunner::new()
.on(["git", "diff", "--quiet"], Reply::ok(""))
.on(["git", "branch", "--show-current"], Reply::ok("main\n"))
.fallback(Reply::fail(1, "unexpected command")),
);
let description = describe_repo(&runner).await?;
println!("{description}");
assert_eq!(description, "clean on main");
let calls = runner.calls();
assert_eq!(calls.len(), 2, "expected exactly two scripted calls");
assert_eq!(calls[0].args_str(), ["diff", "--quiet"]);
assert!(calls[1].has_flag("--show-current"));
let only = RecordingRunner::replying(Reply::ok("v1.2.3\n"));
let version = only.run(&Command::new("tool").arg("--version")).await?;
assert_eq!(version, "v1.2.3");
assert_eq!(only.only_call().args_str(), ["--version"]);
println!(
"recorded {} scripted call(s) across two runners — no subprocess spawned",
calls.len() + 1
);
Ok(())
}