use std::process::Command; use tempfile::TempDir; fn arc_cmd() -> Command { let mut cmd = Command::new(env!("CARGO_BIN_EXE_arc")); cmd.env("NO_COLOR", "1"); cmd } fn init_repo() -> TempDir { let dir = TempDir::new().unwrap(); arc_cmd() .arg("init") .current_dir(dir.path()) .output() .expect("failed to init"); dir } fn commit_file(dir: &TempDir, name: &str, content: &str, msg: &str) { std::fs::write(dir.path().join(name), content).unwrap(); let output = arc_cmd() .args(["commit", msg]) .current_dir(dir.path()) .output() .expect("failed to commit"); assert!(output.status.success()); } #[test] fn check_clean_repo_succeeds() { let dir = init_repo(); commit_file(&dir, "a.txt", "hello\n", "initial"); let output = arc_cmd() .arg("check") .current_dir(dir.path()) .output() .expect("failed to run check"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("repository ok")); } #[test] fn check_multi_commit_repo() { let dir = init_repo(); commit_file(&dir, "a.txt", "hello\n", "first"); commit_file(&dir, "b.txt", "world\n", "second"); commit_file(&dir, "a.txt", "updated\n", "third"); let output = arc_cmd() .arg("check") .current_dir(dir.path()) .output() .expect("failed to run check"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("3 commit(s)")); } #[test] fn check_detects_corrupt_commit_file() { let dir = init_repo(); commit_file(&dir, "a.txt", "hello\n", "initial"); let commits_dir = dir.path().join(".arc").join("commits"); let entries: Vec<_> = std::fs::read_dir(&commits_dir).unwrap().flatten().collect(); assert_eq!(entries.len(), 1); let commit_path = entries[0].path(); std::fs::write(&commit_path, b"corrupted data").unwrap(); let output = arc_cmd() .arg("check") .current_dir(dir.path()) .output() .expect("failed to run check"); assert!(!output.status.success()); } #[test] fn check_detects_missing_commit_from_ref() { let dir = init_repo(); commit_file(&dir, "a.txt", "hello\n", "initial"); let commits_dir = dir.path().join(".arc").join("commits"); let entries: Vec<_> = std::fs::read_dir(&commits_dir).unwrap().flatten().collect(); for entry in entries { std::fs::remove_file(entry.path()).unwrap(); } let output = arc_cmd() .arg("check") .current_dir(dir.path()) .output() .expect("failed to run check"); assert!(!output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("missing commit") || stdout.contains("error")); } #[test] fn check_with_bookmarks_and_tags() { let dir = init_repo(); commit_file(&dir, "a.txt", "hello\n", "initial"); arc_cmd() .args(["mark", "add", "feature"]) .current_dir(dir.path()) .output() .expect("failed"); arc_cmd() .args(["tag", "add", "v1"]) .current_dir(dir.path()) .output() .expect("failed"); let output = arc_cmd() .arg("check") .current_dir(dir.path()) .output() .expect("failed to run check"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("repository ok")); } #[test] fn check_empty_repo() { let dir = init_repo(); let output = arc_cmd() .arg("check") .current_dir(dir.path()) .output() .expect("failed to run check"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("repository ok")); }