use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
process::Command,
};
use tempfile::{tempdir, TempDir};
pub struct TestWorkspace {
_tempdir: TempDir,
root: PathBuf,
}
pub struct CommandOutput {
pub status_code: i32,
pub stdout: String,
pub stderr: String,
}
impl TestWorkspace {
pub fn new() -> Self {
let tempdir = tempdir().expect("tempdir should exist");
let root = tempdir.path().to_path_buf();
Self {
_tempdir: tempdir,
root,
}
}
pub fn root(&self) -> &Path {
&self.root
}
#[allow(dead_code)]
pub fn write_file(&self, relative_path: impl AsRef<Path>, contents: &str) {
let path = self.root.join(relative_path);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).expect("parent directories should exist");
}
fs::write(path, contents).expect("file should be written");
}
#[allow(dead_code)]
pub fn copy_fixture(&self, fixture_name: impl AsRef<Path>, destination: impl AsRef<Path>) {
let source = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("fixtures")
.join(fixture_name);
let destination = self.root.join(destination);
if let Some(parent) = destination.parent() {
fs::create_dir_all(parent).expect("parent directories should exist");
}
fs::copy(source, destination).expect("fixture should be copied");
}
pub fn run_hen<I, S>(&self, args: I) -> CommandOutput
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let output = Command::new(env!("CARGO_BIN_EXE_hen"))
.args(args)
.current_dir(self.root())
.env("NO_COLOR", "1")
.env("TERM", "dumb")
.output()
.expect("hen command should execute");
CommandOutput {
status_code: output.status.code().expect("process should exit normally"),
stdout: String::from_utf8(output.stdout).expect("stdout should be utf-8"),
stderr: String::from_utf8(output.stderr).expect("stderr should be utf-8"),
}
}
}