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) -> String { 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()); String::from_utf8_lossy(&output.stdout) .trim() .strip_prefix("✓ committed ") .unwrap() .to_string() } #[test] fn reset_all_restores_modified_file() { let dir = init_repo(); commit_file(&dir, "a.txt", "original\n", "first"); std::fs::write(dir.path().join("a.txt"), "modified\n").unwrap(); let output = arc_cmd() .args(["reset"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("reset")); let content = std::fs::read_to_string(dir.path().join("a.txt")).unwrap(); assert_eq!(content, "original\n"); } #[test] fn reset_all_removes_added_file() { let dir = init_repo(); commit_file(&dir, "a.txt", "a\n", "first"); std::fs::write(dir.path().join("new.txt"), "new\n").unwrap(); let output = arc_cmd() .args(["reset"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); assert!(!dir.path().join("new.txt").exists()); } #[test] fn reset_all_restores_deleted_file() { let dir = init_repo(); commit_file(&dir, "a.txt", "a\n", "first"); std::fs::remove_file(dir.path().join("a.txt")).unwrap(); let output = arc_cmd() .args(["reset"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let content = std::fs::read_to_string(dir.path().join("a.txt")).unwrap(); assert_eq!(content, "a\n"); } #[test] fn reset_specific_file_only() { let dir = init_repo(); commit_file(&dir, "a.txt", "a\n", "first"); commit_file(&dir, "b.txt", "b\n", "second"); std::fs::write(dir.path().join("a.txt"), "changed-a\n").unwrap(); std::fs::write(dir.path().join("b.txt"), "changed-b\n").unwrap(); let output = arc_cmd() .args(["reset", "a.txt"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let a_content = std::fs::read_to_string(dir.path().join("a.txt")).unwrap(); assert_eq!(a_content, "a\n"); let b_content = std::fs::read_to_string(dir.path().join("b.txt")).unwrap(); assert_eq!(b_content, "changed-b\n"); } #[test] fn reset_clean_worktree() { let dir = init_repo(); commit_file(&dir, "a.txt", "a\n", "first"); let output = arc_cmd() .args(["reset"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("nothing to reset")); } #[test] fn reset_multiple_changes() { let dir = init_repo(); commit_file(&dir, "a.txt", "a\n", "first"); commit_file(&dir, "b.txt", "b\n", "second"); std::fs::write(dir.path().join("a.txt"), "changed\n").unwrap(); std::fs::remove_file(dir.path().join("b.txt")).unwrap(); std::fs::write(dir.path().join("c.txt"), "new\n").unwrap(); let output = arc_cmd() .args(["reset"]) .current_dir(dir.path()) .output() .expect("failed"); assert!(output.status.success()); let a = std::fs::read_to_string(dir.path().join("a.txt")).unwrap(); assert_eq!(a, "a\n"); assert!(dir.path().join("b.txt").exists()); assert!(!dir.path().join("c.txt").exists()); }