use std::io::Write;
use std::process::Command;
const MKTOOL: &str = env!("CARGO_BIN_EXE_mktool");
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[test]
fn digest_valid_file() -> Result<()> {
let dir = tempfile::tempdir()?;
let file = dir.path().join("test.txt");
std::fs::write(&file, b"hello\n")?;
let cmd =
Command::new(MKTOOL).args(["digest", "SHA256"]).arg(&file).output()?;
let stdout = String::from_utf8_lossy(&cmd.stdout);
let stderr = String::from_utf8_lossy(&cmd.stderr);
assert!(cmd.status.success(), "expected success: {stderr}");
assert!(
stdout.contains("SHA256") && stdout.contains("="),
"expected hash output: {stdout}"
);
assert!(stderr.is_empty(), "expected no stderr: {stderr}");
Ok(())
}
#[test]
fn digest_missing_file() -> Result<()> {
let cmd = Command::new(MKTOOL)
.args(["digest", "SHA256", "/nonexistent/file.txt"])
.output()?;
let stderr = String::from_utf8_lossy(&cmd.stderr);
assert!(!cmd.status.success(), "expected failure: {stderr}");
assert_eq!(cmd.status.code(), Some(1));
assert!(
stderr.contains("/nonexistent/file.txt"),
"expected filename in error: {stderr}"
);
assert!(
stderr.contains("No such file") || stderr.contains("not found"),
"expected error reason in output: {stderr}"
);
Ok(())
}
#[test]
fn digest_mixed_files() -> Result<()> {
let dir = tempfile::tempdir()?;
let good = dir.path().join("good.txt");
std::fs::write(&good, b"hello\n")?;
let cmd = Command::new(MKTOOL)
.args(["digest", "SHA256"])
.arg(&good)
.arg("/nonexistent/bad.txt")
.output()?;
let stdout = String::from_utf8_lossy(&cmd.stdout);
let stderr = String::from_utf8_lossy(&cmd.stderr);
assert!(!cmd.status.success(), "expected failure due to bad file");
assert!(
stdout.contains("good.txt"),
"expected hash for good file: {stdout}"
);
assert!(
stderr.contains("/nonexistent/bad.txt"),
"expected error for bad file: {stderr}"
);
assert!(
stderr.contains("No such file") || stderr.contains("not found"),
"expected error reason: {stderr}"
);
Ok(())
}
#[test]
fn digest_stdin() -> Result<()> {
let mut child = Command::new(MKTOOL)
.args(["digest", "SHA256"])
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()?;
child.stdin.take().ok_or("failed to open stdin")?.write_all(b"hello\n")?;
let output = child.wait_with_output()?;
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success(), "expected success");
assert!(stdout.trim().len() == 64, "expected SHA256 hex string: {stdout}");
Ok(())
}