#![allow(deprecated)]
use assert_cmd::prelude::*;
use assert_fs::prelude::*;
use predicates::prelude::*;
use std::process::Command;
#[test]
fn test_rm_multiple_branches() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-a")
.current_dir(repo_dir.path())
.assert()
.success();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-b")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_a_path = temp.path().join("test-repo-worktrees/feature-a");
let worktree_b_path = temp.path().join("test-repo-worktrees/feature-b");
assert!(worktree_a_path.exists());
assert!(worktree_b_path.exists());
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("rm")
.arg("feature-a")
.arg("feature-b")
.current_dir(repo_dir.path())
.assert()
.success()
.stderr(predicate::str::contains("Removed feature-").count(2));
assert!(!worktree_a_path.exists());
assert!(!worktree_b_path.exists());
let output = Command::new("git")
.args(["branch", "--list", "feature-a"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
let output = Command::new("git")
.args(["branch", "--list", "feature-b"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}
#[test]
fn test_rm_multiple_branches_from_worktree() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-a")
.current_dir(repo_dir.path())
.assert()
.success();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-b")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_a_path = temp.path().join("test-repo-worktrees/feature-a");
let worktree_b_path = temp.path().join("test-repo-worktrees/feature-b");
assert!(worktree_a_path.exists());
assert!(worktree_b_path.exists());
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("rm")
.arg("feature-a")
.arg("feature-b")
.current_dir(&worktree_a_path)
.assert()
.success()
.stderr(predicate::str::contains("Removed feature-").count(2));
assert!(!worktree_a_path.exists());
assert!(!worktree_b_path.exists());
let output = Command::new("git")
.args(["branch", "--list", "feature-a"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
let output = Command::new("git")
.args(["branch", "--list", "feature-b"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}
#[test]
fn test_rm_duplicate_targets() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-a")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_a_path = temp.path().join("test-repo-worktrees/feature-a");
assert!(worktree_a_path.exists());
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("--color=never")
.arg("rm")
.arg("feature-a")
.arg("feature-a")
.current_dir(repo_dir.path())
.assert()
.success()
.stderr(predicate::str::contains("Removed feature-a").count(1))
.stderr(predicate::str::contains("Duplicate").or(predicate::str::contains("already")));
assert!(!worktree_a_path.exists());
let output = Command::new("git")
.args(["branch", "--list", "feature-a"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}
#[test]
fn test_rm_current_with_others() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-a")
.current_dir(repo_dir.path())
.assert()
.success();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-b")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_a_path = temp.path().join("test-repo-worktrees/feature-a");
let worktree_b_path = temp.path().join("test-repo-worktrees/feature-b");
assert!(worktree_a_path.exists());
assert!(worktree_b_path.exists());
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("rm")
.arg("feature-b")
.arg(".")
.current_dir(&worktree_a_path)
.assert()
.success()
.stdout(predicate::str::contains(repo_dir.path().to_str().unwrap()))
.stderr(predicate::str::contains("Removed feature-").count(2));
assert!(!worktree_a_path.exists());
assert!(!worktree_b_path.exists());
let output = Command::new("git")
.args(["branch", "--list", "feature-a"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
let output = Command::new("git")
.args(["branch", "--list", "feature-b"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}
#[test]
fn test_rm_alias_and_dot() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-a")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_a_path = temp.path().join("test-repo-worktrees/feature-a");
assert!(worktree_a_path.exists());
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("--color=never")
.arg("rm")
.arg("feature-a")
.arg(".")
.current_dir(&worktree_a_path)
.assert()
.success()
.stdout(predicate::str::contains(repo_dir.path().to_str().unwrap()))
.stderr(predicate::str::contains("Duplicate"))
.stderr(predicate::str::contains("Removed feature-a").count(1));
assert!(!worktree_a_path.exists());
let output = Command::new("git")
.args(["branch", "--list", "feature-a"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}
#[test]
fn test_rm_with_invalid_target() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("feature-a")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_a_path = temp.path().join("test-repo-worktrees/feature-a");
assert!(worktree_a_path.exists());
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("rm")
.arg("feature-a")
.arg("nonexistent-branch")
.current_dir(repo_dir.path())
.assert()
.failure()
.stderr(predicate::str::contains(
"Worktree not found: nonexistent-branch",
));
assert!(worktree_a_path.exists());
let output = Command::new("git")
.args(["show-ref", "--verify", "refs/heads/feature-a"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert!(
output.status.success(),
"Branch feature-a should still exist after failed rm command. stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
temp.close().unwrap();
}
#[test]
fn test_rm_prunable_worktree_by_branch_name() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("test-prunable")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_path = temp.path().join("test-repo-worktrees/test-prunable");
assert!(worktree_path.exists());
std::fs::remove_dir_all(&worktree_path).unwrap();
assert!(!worktree_path.exists());
let git_output = Command::new("git")
.args(["worktree", "list", "--porcelain"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert!(git_output.status.success());
let list_output = String::from_utf8_lossy(&git_output.stdout);
assert!(list_output.contains("prunable"));
assert!(list_output.contains("test-prunable"));
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("rm")
.arg("test-prunable")
.current_dir(repo_dir.path())
.assert()
.success()
.stderr(predicate::str::contains("Removed test-prunable"));
let git_output = Command::new("git")
.args(["worktree", "list", "--porcelain"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert!(git_output.status.success());
let list_output = String::from_utf8_lossy(&git_output.stdout);
assert!(!list_output.contains("test-prunable"));
let output = Command::new("git")
.args(["branch", "--list", "test-prunable"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}
#[test]
fn test_rm_prunable_worktree_by_absolute_path() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("test-prunable-path")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_path = temp.path().join("test-repo-worktrees/test-prunable-path");
assert!(worktree_path.exists());
std::fs::remove_dir_all(&worktree_path).unwrap();
assert!(!worktree_path.exists());
let git_output = Command::new("git")
.args(["worktree", "list", "--porcelain"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert!(git_output.status.success());
let list_output = String::from_utf8_lossy(&git_output.stdout);
assert!(list_output.contains("prunable"));
assert!(list_output.contains("test-prunable-path"));
let worktree_path_str = worktree_path.to_str().unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("rm")
.arg(worktree_path_str)
.current_dir(repo_dir.path())
.assert()
.success()
.stderr(predicate::str::contains("Removed test-prunable-path"));
let git_output = Command::new("git")
.args(["worktree", "list", "--porcelain"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert!(git_output.status.success());
let list_output = String::from_utf8_lossy(&git_output.stdout);
assert!(!list_output.contains("test-prunable-path"));
let output = Command::new("git")
.args(["branch", "--list", "test-prunable-path"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}
#[test]
fn test_rm_prunable_worktree_by_relative_path() {
let temp = assert_fs::TempDir::new().unwrap();
let repo_dir = temp.child("test-repo");
repo_dir.create_dir_all().unwrap();
Command::new("git")
.args(["init"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test User"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@example.com"])
.current_dir(repo_dir.path())
.output()
.unwrap();
Command::new("git")
.args(["commit", "--allow-empty", "-m", "Initial commit"])
.current_dir(repo_dir.path())
.output()
.unwrap();
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("add")
.arg("test-prunable-rel")
.current_dir(repo_dir.path())
.assert()
.success();
let worktree_path = temp.path().join("test-repo-worktrees/test-prunable-rel");
assert!(worktree_path.exists());
std::fs::remove_dir_all(&worktree_path).unwrap();
assert!(!worktree_path.exists());
let git_output = Command::new("git")
.args(["worktree", "list", "--porcelain"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert!(git_output.status.success());
let list_output = String::from_utf8_lossy(&git_output.stdout);
assert!(list_output.contains("prunable"));
assert!(list_output.contains("test-prunable-rel"));
let mut cmd = Command::cargo_bin("ofsht").unwrap();
cmd.arg("rm")
.arg("../test-repo-worktrees/test-prunable-rel")
.current_dir(repo_dir.path())
.assert()
.success()
.stderr(predicate::str::contains("Removed test-prunable-rel"));
let git_output = Command::new("git")
.args(["worktree", "list", "--porcelain"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert!(git_output.status.success());
let list_output = String::from_utf8_lossy(&git_output.stdout);
assert!(!list_output.contains("test-prunable-rel"));
let output = Command::new("git")
.args(["branch", "--list", "test-prunable-rel"])
.current_dir(repo_dir.path())
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "");
temp.close().unwrap();
}