use std::{
io::Write,
path::PathBuf,
process::{Command, Output},
};
use tempfile::{NamedTempFile, TempDir};
pub struct CliTest {
pub temp_dir: TempDir,
pub binary_path: PathBuf,
}
impl CliTest {
pub fn new() -> Self {
let bin_path = std::env::current_dir().unwrap();
let temp_dir = TempDir::new().expect("Failed to create temp directory");
Self { temp_dir, binary_path: bin_path }
}
pub fn run(&self, args: &[&str]) -> Output {
let mut cmd = Command::new("cargo");
cmd.arg("run").arg("--").args(args).current_dir(&self.binary_path);
cmd.env("HOME", self.temp_dir.path());
if cfg!(target_os = "windows") {
cmd.env("USERPROFILE", self.temp_dir.path());
}
cmd.output().expect("Failed to execute command")
}
pub fn run_command(&self, args: &[&str]) -> Output {
self.run(args)
}
pub fn create_temp_file(&self, content: &str) -> PathBuf {
let mut file = NamedTempFile::new_in(&self.temp_dir).unwrap();
file.write_all(content.as_bytes()).unwrap();
let path = file.into_temp_path();
let path_buf = path.to_path_buf();
path.keep().unwrap();
path_buf
}
}
pub fn assert_success(output: &Output) {
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(output.status.success(), "Command failed: {stderr}");
}
pub fn assert_output_contains(output: &Output, expected: &str) {
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains(expected),
"Expected output to contain '{expected}', but got:\n{stdout}"
);
}