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 remote_add_creates_entry() { let dir = init_repo(); let output = arc_cmd() .args(["remote", "add", "origin", "https://example.com/repo.git"]) .current_dir(dir.path()) .output() .unwrap(); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("remote 'origin' added")); let remotes_path = dir.path().join(".arc").join("remotes.yml"); assert!(remotes_path.exists()); let contents = std::fs::read_to_string(&remotes_path).unwrap(); assert!(contents.contains("origin")); assert!(contents.contains("https://example.com/repo.git")); } #[test] fn remote_add_fails_if_exists() { let dir = init_repo(); arc_cmd() .args(["remote", "add", "origin", "https://example.com/repo.git"]) .current_dir(dir.path()) .output() .unwrap(); let output = arc_cmd() .args(["remote", "add", "origin", "https://other.com/repo.git"]) .current_dir(dir.path()) .output() .unwrap(); assert!(!output.status.success()); let stderr = String::from_utf8_lossy(&output.stderr); assert!(stderr.contains("remote already exists")); } #[test] fn remote_rm_removes_entry() { let dir = init_repo(); arc_cmd() .args(["remote", "add", "origin", "https://example.com/repo.git"]) .current_dir(dir.path()) .output() .unwrap(); let output = arc_cmd() .args(["remote", "rm", "origin"]) .current_dir(dir.path()) .output() .unwrap(); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("remote 'origin' removed")); } #[test] fn remote_rm_fails_if_not_found() { let dir = init_repo(); let output = arc_cmd() .args(["remote", "rm", "nonexistent"]) .current_dir(dir.path()) .output() .unwrap(); assert!(!output.status.success()); let stderr = String::from_utf8_lossy(&output.stderr); assert!(stderr.contains("remote not configured")); } #[test] fn remote_list_shows_remotes() { let dir = init_repo(); arc_cmd() .args(["remote", "add", "origin", "https://example.com/repo.git"]) .current_dir(dir.path()) .output() .unwrap(); arc_cmd() .args(["remote", "add", "upstream", "https://upstream.com/repo.git"]) .current_dir(dir.path()) .output() .unwrap(); let output = arc_cmd() .args(["remote", "list"]) .current_dir(dir.path()) .output() .unwrap(); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("origin")); assert!(stdout.contains("https://example.com/repo.git")); assert!(stdout.contains("upstream")); assert!(stdout.contains("https://upstream.com/repo.git")); } #[test] fn remote_list_empty() { let dir = init_repo(); let output = arc_cmd() .args(["remote", "list"]) .current_dir(dir.path()) .output() .unwrap(); assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout); assert!(stdout.contains("no remotes configured")); } #[test] fn remote_list_sorted_alphabetically() { let dir = init_repo(); arc_cmd() .args(["remote", "add", "zebra", "https://z.com"]) .current_dir(dir.path()) .output() .unwrap(); arc_cmd() .args(["remote", "add", "alpha", "https://a.com"]) .current_dir(dir.path()) .output() .unwrap(); let output = arc_cmd() .args(["remote", "list"]) .current_dir(dir.path()) .output() .unwrap(); let stdout = String::from_utf8_lossy(&output.stdout); let alpha_pos = stdout.find("alpha").unwrap(); let zebra_pos = stdout.find("zebra").unwrap(); assert!(alpha_pos < zebra_pos); }