#![cfg(unix)]
use std::process::{Command, Stdio};
use tempfile::TempDir;
const CLEAN_PATH: &str = "/usr/bin:/bin:/usr/sbin:/sbin";
const BLOCK_START_MARKER: &str = "# >>> git-prism shim >>>";
fn count_marker_blocks(rc: &str) -> usize {
rc.matches(BLOCK_START_MARKER).count()
}
#[test]
fn consent_writes_block_even_when_fragment_appears_in_unrelated_line() {
let bin = env!("CARGO_BIN_EXE_git-prism");
let home = TempDir::new().unwrap();
let zshenv = home.path().join(".zshenv");
std::fs::write(
&zshenv,
"# I once read about .local/share/git-prism/bin in the docs\n",
)
.unwrap();
let out = Command::new(bin)
.env("HOME", home.path())
.env("PATH", CLEAN_PATH)
.env("SHELL", "/bin/zsh")
.args(["shim", "install"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.and_then(|mut child| {
use std::io::Write;
child.stdin.take().unwrap().write_all(b"y\n").unwrap();
child.wait_with_output()
})
.unwrap();
let stdout = String::from_utf8_lossy(&out.stdout);
let zshenv_after = std::fs::read_to_string(&zshenv).unwrap();
assert!(
stdout.contains("Added to"),
"consent path must print the success message; got: {stdout}"
);
assert_eq!(
count_marker_blocks(&zshenv_after),
1,
"consent must write exactly one marker block to .zshenv even when the \
fragment appears as an unrelated substring; .zshenv was:\n{zshenv_after}"
);
}
#[test]
fn trailing_slash_path_entry_is_recognized_as_already_first() {
let bin = env!("CARGO_BIN_EXE_git-prism");
let home = TempDir::new().unwrap();
std::fs::write(home.path().join(".zshenv"), "# zshenv\n").unwrap();
std::fs::write(home.path().join(".zshrc"), "# rc\n").unwrap();
let shim_dir = home.path().join(".local/share/git-prism/bin");
let path_with_trailing_slash = format!("{}/:{}", shim_dir.display(), CLEAN_PATH);
let out = Command::new(bin)
.env("HOME", home.path())
.env("PATH", path_with_trailing_slash)
.env("SHELL", "/bin/zsh")
.args(["shim", "install"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.and_then(|mut child| {
use std::io::Write;
child.stdin.take().unwrap().write_all(b"n\n").unwrap();
child.wait_with_output()
})
.unwrap();
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(
!stdout.contains("not first"),
"shim dir first with a trailing slash should count as already-first-in-PATH; \
got prompt: {stdout}"
);
let zshenv_after = std::fs::read_to_string(home.path().join(".zshenv")).unwrap();
assert_eq!(
zshenv_after, "# zshenv\n",
"already-first detection must not append a block to .zshenv; got:\n{zshenv_after}"
);
let zshrc_after = std::fs::read_to_string(home.path().join(".zshrc")).unwrap();
assert_eq!(
zshrc_after, "# rc\n",
"already-first detection must not append a block to .zshrc; got:\n{zshrc_after}"
);
}