use assert_cmd::Command;
use std::path::Path;
#[test]
fn pre_commit_hook_runs_stamp_and_lint() {
let tmp = tempfile::tempdir().expect("tempdir");
let repo = tmp.path();
let aristo_bin = assert_cmd::cargo::cargo_bin("aristo");
let aristo_dir = aristo_bin.parent().expect("cargo bin has a parent dir");
let new_path = match std::env::var_os("PATH") {
Some(existing) => {
let mut paths = vec![aristo_dir.to_path_buf()];
paths.extend(std::env::split_paths(&existing));
std::env::join_paths(paths).expect("join PATH entries")
}
None => aristo_dir.as_os_str().to_owned(),
};
let git = |dir: &Path| {
let mut cmd = Command::new("git");
cmd.current_dir(dir).env("PATH", &new_path);
cmd
};
git(repo).args(["init", "--quiet"]).assert().success();
git(repo)
.args(["config", "user.email", "test@aretta.dev"])
.assert()
.success();
git(repo)
.args(["config", "user.name", "Test"])
.assert()
.success();
git(repo)
.args(["config", "commit.gpgsign", "false"])
.assert()
.success();
std::fs::write(
repo.join("Cargo.toml"),
r#"[package]
name = "hook-test"
version = "0.0.0"
edition = "2021"
"#,
)
.unwrap();
std::fs::create_dir(repo.join("src")).unwrap();
std::fs::write(repo.join("src/lib.rs"), "").unwrap();
Command::cargo_bin("aristo")
.unwrap()
.arg("init")
.current_dir(repo)
.assert()
.success();
assert!(
repo.join(".git/hooks/pre-commit").exists(),
"expected aristo init to install .git/hooks/pre-commit"
);
std::fs::write(
repo.join("src/lib.rs"),
r#"use aristo::intent;
#[intent("the function returns a stable hash of its input")]
pub fn stable_hash(_x: &[u8]) -> u64 { 0 }
"#,
)
.unwrap();
git(repo).args(["add", "."]).assert().success();
let commit = git(repo)
.args(["commit", "-m", "feat: stable_hash"])
.assert()
.success();
let stderr = String::from_utf8_lossy(&commit.get_output().stderr).to_string();
assert!(
stderr.contains("aristo stamp") || stderr.contains("annotations stamped"),
"expected pre-commit hook to invoke `aristo stamp`; got stderr:\n{stderr}"
);
assert!(
repo.join(".aristo/index.toml").exists(),
"expected `aristo stamp` to populate .aristo/index.toml during commit"
);
std::fs::write(
repo.join("src/lib.rs"),
r#"use aristo::intent;
#[intent("the function returns a stable hash of its input")]
pub fn stable_hash(_x: &[u8]) -> u64 { 0 }
#[intent("")]
pub fn empty_text() {}
"#,
)
.unwrap();
git(repo).args(["add", "."]).assert().success();
let blocked = git(repo)
.args(["commit", "-m", "feat: empty_text"])
.assert()
.failure();
let stderr = String::from_utf8_lossy(&blocked.get_output().stderr).to_string();
assert!(
stderr.contains("empty_text") || stderr.contains("lint"),
"expected pre-commit hook's `aristo lint --check` to abort the commit; got stderr:\n{stderr}"
);
}