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_id(dir: &TempDir, msg: &str) -> String { let output = arc_cmd() .args(["commit", msg]) .current_dir(dir.path()) .output() .expect("failed to commit"); assert!(output.status.success()); String::from_utf8_lossy(&output.stdout) .trim() .strip_prefix("✓ committed ") .unwrap() .to_string() } #[test] fn history_single_commit() { let dir = init_repo(); std::fs::write(dir.path().join("a.txt"), "line one\nline two\n").unwrap(); let id = commit_id(&dir, "initial"); let output = arc_cmd() .args(["history", "a.txt"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); let short = &id[..8]; assert!(stdout.contains(short)); assert!(stdout.contains("line one")); assert!(stdout.contains("line two")); } #[test] fn history_attributes_modified_lines() { let dir = init_repo(); std::fs::write(dir.path().join("a.txt"), "line one\nline two\n").unwrap(); let id1 = commit_id(&dir, "initial"); std::fs::write(dir.path().join("a.txt"), "line one\nline modified\n").unwrap(); let id2 = commit_id(&dir, "modify"); let output = arc_cmd() .args(["history", "a.txt"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); let lines: Vec<&str> = stdout.lines().collect(); assert_eq!(lines.len(), 2); assert!(lines[0].contains(&id1[..8])); assert!(lines[0].contains("line one")); assert!(lines[1].contains(&id2[..8])); assert!(lines[1].contains("line modified")); } #[test] fn history_attributes_added_lines() { let dir = init_repo(); std::fs::write(dir.path().join("a.txt"), "line one\n").unwrap(); let id1 = commit_id(&dir, "initial"); std::fs::write(dir.path().join("a.txt"), "line one\nline two\n").unwrap(); let id2 = commit_id(&dir, "add line"); let output = arc_cmd() .args(["history", "a.txt"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); let lines: Vec<&str> = stdout.lines().collect(); assert_eq!(lines.len(), 2); assert!(lines[0].contains(&id1[..8])); assert!(lines[1].contains(&id2[..8])); } #[test] fn history_file_not_found() { let dir = init_repo(); std::fs::write(dir.path().join("a.txt"), "content\n").unwrap(); commit_id(&dir, "initial"); let output = arc_cmd() .args(["history", "nonexistent.txt"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(!output.status.success()); } #[test] fn history_three_commits() { let dir = init_repo(); std::fs::write(dir.path().join("a.txt"), "alpha\nbeta\n").unwrap(); let id1 = commit_id(&dir, "c1"); std::fs::write(dir.path().join("a.txt"), "alpha\nbeta\ngamma\n").unwrap(); let id2 = commit_id(&dir, "c2"); std::fs::write(dir.path().join("a.txt"), "alpha\nBETA\ngamma\n").unwrap(); let id3 = commit_id(&dir, "c3"); let output = arc_cmd() .args(["history", "a.txt"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); let lines: Vec<&str> = stdout.lines().collect(); assert_eq!(lines.len(), 3); assert!(lines[0].contains(&id1[..8])); assert!(lines[0].contains("alpha")); assert!(lines[1].contains(&id3[..8])); assert!(lines[1].contains("BETA")); assert!(lines[2].contains(&id2[..8])); assert!(lines[2].contains("gamma")); }