Files
ahab/tests/output_io.rs

100 lines
2.9 KiB
Rust

// what a command reports and how it exits, including when the write fails.
mod support;
use std::fs;
use support::Case;
#[test]
fn findings_are_reported_through_the_exit_code() {
let case = Case::new("findings");
case.write("loose.txt", b"x\n");
case.ahab(&["link", "check"]).ok();
case.ahab(&["link", "check", "--exit-code"]).code_is(4);
}
#[test]
fn an_argument_error_exits_two() {
let case = Case::new("usage");
case.ahab(&["link", "restore"]).code_is(2);
case.ahab(&["link", "restore", "--all", "some/path"])
.code_is(2);
case.ahab(&["postgres", "dump", "-F", "directory", "-z", "d"])
.code_is(2);
case.ahab(&["nonsense"]).code_is(2);
}
#[test]
fn a_write_that_cannot_be_delivered_is_a_failure_rather_than_a_success() {
let case = Case::new("devfull");
for n in 0..200 {
case.write(&format!("file-{n}.txt"), b"x\n");
}
// /dev/full accepts the open and fails the write. exiting 0 there would
// report a listing that was never delivered
let Ok(full) = fs::File::create("/dev/full") else {
eprintln!("skipped: this system has no /dev/full to fail a write against");
return;
};
let out = std::process::Command::new(env!("CARGO_BIN_EXE_ahab"))
.current_dir(&case.repo)
.env("XDG_DATA_HOME", case.repo.join("../xdg"))
.args(["link", "check", "--exit-code", "--porcelain"])
.stdout(full)
.output()
.expect("running ahab");
assert_eq!(out.status.code(), Some(1), "{:?}", out.status);
assert!(
String::from_utf8_lossy(&out.stderr).contains("writing to stdout failed"),
"{}",
String::from_utf8_lossy(&out.stderr)
);
}
#[test]
fn every_named_path_is_moved_even_when_the_reader_leaves() {
let case = Case::new("partial");
for name in ["a.env", "b.env", "c.env"] {
case.write(name, b"x\n");
}
case.gitignore("a.env\nb.env\nc.env\n");
// a closed stdout must stop the writing, not the moving: the command had
// planned to move all three and reported success for doing so
let run = case.ahab(&["link", "add", "a.env", "b.env", "c.env"]);
run.ok();
for name in ["a.env", "b.env", "c.env"] {
assert!(case.is_symlink(name), "{name} was left behind");
}
}
#[test]
fn quiet_keeps_the_reason_a_path_failed() {
let case = Case::new("quiet");
case.write("ok.env", b"x\n");
case.gitignore("ok.env\n");
let run = case.ahab(&["-q", "link", "add", "ok.env", "missing.env"]);
run.failed()
.says("1 of 2 paths failed")
// the line saying *which* and *why* is a result, not progress
.says("missing.env");
}
#[test]
fn a_dry_run_changes_nothing_on_disk() {
let case = Case::new("dryrun");
case.write(".env", b"SECRET=1\n");
case.gitignore(".env\n");
case.ahab(&["--dry-run", "link", "add", ".env"]).ok();
assert!(!case.is_symlink(".env"));
assert!(!case.store.join(".env").exists());
}