use super::*;
use crate::error::BallError;
use std::path::Path;
use std::process::Command;
use tempfile::tempdir;
fn raw_git(path: &Path, args: &[&str]) -> std::process::Output {
let mut cmd = Command::new("git");
cmd.current_dir(path).args(args);
for var in crate::git::GIT_ENV_VARS {
cmd.env_remove(var);
}
cmd.output().expect("spawn git")
}
fn init_repo(path: &Path) {
let run = |args: &[&str]| {
assert!(raw_git(path, args).status.success());
};
run(&["init", "-q", "-b", "main"]);
run(&["config", "user.email", "test@example.com"]);
run(&["config", "user.name", "test"]);
run(&["config", "commit.gpgsign", "false"]);
run(&["commit", "--allow-empty", "-m", "init"]);
}
#[test]
fn is_bare_repo_false_on_regular_repo() {
let td = tempdir().unwrap();
init_repo(td.path());
assert!(!is_bare_repo(td.path()).unwrap());
}
#[test]
fn is_bare_repo_true_when_core_bare_flag_set() {
let td = tempdir().unwrap();
init_repo(td.path());
assert!(raw_git(td.path(), &["config", "core.bare", "true"])
.status
.success());
assert!(is_bare_repo(td.path()).unwrap());
}
#[test]
fn is_bare_repo_errors_on_non_git_path() {
let td = tempdir().unwrap();
let err = is_bare_repo(td.path()).unwrap_err();
assert!(matches!(err, BallError::Git(_)), "got {err:?}");
}
#[test]
fn worktree_add_detach_errors_on_bogus_ref() {
let td = tempdir().unwrap();
init_repo(td.path());
let target = td.path().join("wt");
let err = worktree_add_detach(td.path(), &target, "no-such-ref-anywhere").unwrap_err();
assert!(matches!(err, BallError::Git(_)), "got {err:?}");
assert!(!target.exists(), "no worktree should have been created");
}
#[test]
fn update_ref_errors_on_invalid_ref_name() {
let td = tempdir().unwrap();
init_repo(td.path());
let err =
update_ref(td.path(), "refs/heads/bad..name", "deadbeef").unwrap_err();
assert!(matches!(err, BallError::Git(_)), "got {err:?}");
}
#[test]
fn scrub_path_noop_when_path_missing() {
let td = tempdir().unwrap();
init_repo(td.path());
let absent = td.path().join("does-not-exist");
scrub_path(td.path(), &absent);
assert!(!absent.exists());
}
#[test]
fn scrub_path_removes_orphaned_directory() {
let td = tempdir().unwrap();
init_repo(td.path());
let leftover = td.path().join("stale");
std::fs::create_dir(&leftover).unwrap();
std::fs::write(leftover.join("trash"), "junk").unwrap();
scrub_path(td.path(), &leftover);
assert!(!leftover.exists(), "scrub_path should remove orphaned dir");
}
#[test]
fn scrub_path_removes_registered_worktree() {
let td = tempdir().unwrap();
init_repo(td.path());
let wt = td.path().join("live-wt");
let wt_str = wt.to_string_lossy().to_string();
assert!(raw_git(
td.path(),
&["worktree", "add", "--detach", &wt_str, "HEAD"]
)
.status
.success());
scrub_path(td.path(), &wt);
assert!(!wt.exists(), "scrub_path should remove registered worktree");
}
#[test]
fn squash_worktree_path_includes_pid() {
let td = tempdir().unwrap();
init_repo(td.path());
let store = Store::init(td.path(), false, None).unwrap();
let p = squash_worktree_path(&store);
assert!(p.starts_with(store.local_dir()));
let name = p.file_name().unwrap().to_string_lossy().to_string();
assert!(name.starts_with("squash-"));
assert!(name.ends_with(&std::process::id().to_string()));
}