use super::commit::{git_text, remove_settled, wrapped_commit};
use super::support::{Fixture, Observed, fixture, git, observe, repository, run_direct, stderr_of};
use git_policy_cli::service_messages::{LINGER_COMMAND, NOTHING_CHANGED};
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::process::Output;
fn edited(name: &str) -> (Fixture, PathBuf) {
let fixture: Fixture = fixture(name);
let repo: PathBuf = repository(&fixture, OsStr::new("repo"));
std::fs::write(repo.join("a.txt"), "base\n").expect("a");
git(&fixture, &repo, &["add", "a.txt"]);
git(&fixture, &repo, &["commit", "--quiet", "--message=base"]);
std::fs::write(repo.join("a.txt"), "base\nmore\n").expect("edit");
return (fixture, repo);
}
fn newest_subject(fixture: &Fixture, repo: &Path) -> String {
return git_text(fixture, repo, &["log", "-1", "--format=%s"]).trim().to_string();
}
#[test]
fn a_commit_with_no_service_manager_stops_plainly_and_changes_nothing() {
let (fixture, repo) = edited("no-manager-plain");
let mut command = wrapped_commit(&fixture, &repo, &["commit", "--message=second", "--", "a.txt"]);
command.env_remove("XDG_RUNTIME_DIR").env_remove("DBUS_SESSION_BUS_ADDRESS");
let output: Output = command.output().expect("the wrapped commit runs");
let stderr: String = String::from_utf8_lossy(&output.stderr).into_owned();
assert_eq!(output.status.code(), Some(1), "{stderr}");
assert!(stderr.contains("this commit was not made"), "{stderr}");
assert!(stderr.contains(LINGER_COMMAND), "the remedy is named: {stderr}");
assert!(stderr.contains(NOTHING_CHANGED), "{stderr}");
for internal in ["XDG_RUNTIME_DIR", "socket", "D-Bus", "dbus"] {
assert!(!stderr.contains(internal), "no internal term ({internal}) reaches the person: {stderr}");
}
assert_eq!(newest_subject(&fixture, &repo), "base", "no commit was made");
assert_eq!(git_text(&fixture, &repo, &["diff", "--name-only"]).trim(), "a.txt", "the edit is still in the worktree");
assert!(!repo.join(".git/index.lock").exists(), "no lock is left behind");
let leftovers: Vec<String> = std::fs::read_dir(repo.join(".git"))
.expect("git directory")
.flatten()
.map(|entry| { return entry.file_name().to_string_lossy().into_owned(); })
.filter(|name| { return name.starts_with("cli-git"); })
.collect();
assert!(leftovers.is_empty(), "no scratch directory or record is left: {leftovers:?}");
remove_settled(&fixture);
}
#[test]
fn a_commit_outside_a_repository_says_what_native_git_says() {
let fixture: Fixture = fixture("no-manager-outside");
let plain: PathBuf = fixture.root.join("plain");
std::fs::create_dir_all(&plain).expect("a directory that belongs to no repository");
let wrapped: Observed = observe(&mut wrapped_commit(&fixture, &plain, &["commit", "--message=x"]), b"");
let native: Observed = run_direct(&fixture, &plain, &["commit", "--message=x"]);
assert_eq!(native.code, Some(128), "{}", stderr_of(&native));
assert_eq!(wrapped.code, native.code, "{}", stderr_of(&wrapped));
assert_eq!(stderr_of(&wrapped), stderr_of(&native), "the same words as native Git");
assert!(wrapped.stdout.is_empty());
remove_settled(&fixture);
}