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 } #[test] fn status_clean_after_init() { let dir = init_repo(); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed to run arc"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("working tree clean")); } #[test] fn status_shows_added_files() { let dir = init_repo(); std::fs::write(dir.path().join("new.txt"), "new content\n").unwrap(); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed to run arc"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("added:")); assert!(stdout.contains("new.txt")); } #[test] fn status_shows_modified_files() { let dir = init_repo(); std::fs::write(dir.path().join("file.txt"), "original\n").unwrap(); arc_cmd() .args(["commit", "add file"]) .current_dir(dir.path()) .output() .expect("failed"); std::fs::write(dir.path().join("file.txt"), "modified\n").unwrap(); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("modified:")); assert!(stdout.contains("file.txt")); } #[test] fn status_shows_deleted_files() { let dir = init_repo(); std::fs::write(dir.path().join("gone.txt"), "will be deleted\n").unwrap(); arc_cmd() .args(["commit", "add file"]) .current_dir(dir.path()) .output() .expect("failed"); std::fs::remove_file(dir.path().join("gone.txt")).unwrap(); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("deleted:")); assert!(stdout.contains("gone.txt")); } #[test] fn status_clean_after_commit() { let dir = init_repo(); std::fs::write(dir.path().join("file.txt"), "content\n").unwrap(); arc_cmd() .args(["commit", "add file"]) .current_dir(dir.path()) .output() .expect("failed"); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("working tree clean")); } #[test] fn status_outside_repo_fails() { let dir = TempDir::new().unwrap(); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed"); assert!(!output.status.success()); } #[test] fn status_ignores_arcignore_patterns() { let dir = init_repo(); std::fs::write(dir.path().join(".arcignore"), "*.log\n").unwrap(); std::fs::write(dir.path().join("debug.log"), "log data\n").unwrap(); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(!stdout.contains("debug.log")); } #[test] fn status_shows_multiple_changes() { let dir = init_repo(); std::fs::write(dir.path().join("keep.txt"), "keep\n").unwrap(); std::fs::write(dir.path().join("modify.txt"), "old\n").unwrap(); std::fs::write(dir.path().join("delete.txt"), "gone\n").unwrap(); arc_cmd() .args(["commit", "initial"]) .current_dir(dir.path()) .output() .expect("failed"); std::fs::write(dir.path().join("modify.txt"), "new\n").unwrap(); std::fs::remove_file(dir.path().join("delete.txt")).unwrap(); std::fs::write(dir.path().join("added.txt"), "new file\n").unwrap(); let output = arc_cmd() .arg("status") .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("added:")); assert!(stdout.contains("added.txt")); assert!(stdout.contains("modified:")); assert!(stdout.contains("modify.txt")); assert!(stdout.contains("deleted:")); assert!(stdout.contains("delete.txt")); }