mod common;
use common::TestRepo;
fn worktree_row(branch: &str) -> String {
format!("\u{25cb} {branch} ")
}
#[test]
fn test_delete_multiple_positional_all_succeed() {
let repo = TestRepo::new();
assert!(repo.cw_ok(&["new", "a", "--no-term"]));
assert!(repo.cw_ok(&["new", "b", "--no-term"]));
assert!(repo.cw_ok(&["new", "c", "--no-term"]));
let out = repo.cw(&["delete", "a", "b", "c"]);
assert!(
out.status.success(),
"stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let list = repo.cw_stdout(&["list"]);
assert!(
!list.contains(&worktree_row("a")),
"list still mentions a: {list}"
);
assert!(
!list.contains(&worktree_row("b")),
"list still mentions b: {list}"
);
assert!(
!list.contains(&worktree_row("c")),
"list still mentions c: {list}"
);
}
#[test]
fn test_delete_multiple_mixed_valid_and_missing() {
let repo = TestRepo::new();
assert!(repo.cw_ok(&["new", "real", "--no-term"]));
let out = repo.cw(&["delete", "real", "does-not-exist"]);
assert_eq!(
out.status.code(),
Some(2),
"stdout: {} stderr: {}",
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
);
let list = repo.cw_stdout(&["list"]);
assert!(
!list.contains(&worktree_row("real")),
"list still mentions real: {list}"
);
}
#[test]
fn test_delete_dry_run_does_not_delete() {
let repo = TestRepo::new();
assert!(repo.cw_ok(&["new", "p", "--no-term"]));
assert!(repo.cw_ok(&["new", "q", "--no-term"]));
let out = repo.cw(&["delete", "p", "q", "--dry-run"]);
assert!(out.status.success());
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(
stdout.contains("dry-run; nothing deleted"),
"stdout: {stdout}"
);
let list = repo.cw_stdout(&["list"]);
assert!(
list.contains(&worktree_row("p")),
"p should still be listed: {list}"
);
assert!(
list.contains(&worktree_row("q")),
"q should still be listed: {list}"
);
}
#[test]
fn test_delete_keep_branch_applies_to_all_targets() {
let repo = TestRepo::new();
assert!(repo.cw_ok(&["new", "k1", "--no-term"]));
assert!(repo.cw_ok(&["new", "k2", "--no-term"]));
let out = repo.cw(&["delete", "k1", "k2", "--keep-branch"]);
assert!(
out.status.success(),
"stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let branches = repo.git_stdout(&["branch", "--list"]);
assert!(branches.contains("k1"), "branches: {branches}");
assert!(branches.contains("k2"), "branches: {branches}");
let list = repo.cw_stdout(&["list"]);
assert!(
!list.contains(&worktree_row("k1")),
"list still mentions k1: {list}"
);
assert!(
!list.contains(&worktree_row("k2")),
"list still mentions k2: {list}"
);
}
#[test]
fn test_delete_interactive_conflicts_with_positional_at_runtime() {
let repo = TestRepo::new();
let out = repo.cw(&["delete", "-i", "some-target"]);
assert!(
!out.status.success(),
"stdout: {} stderr: {}",
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
);
let err = String::from_utf8_lossy(&out.stderr);
assert!(
err.contains("cannot") || err.contains("conflict"),
"expected conflict error, got: {err}"
);
}
#[test]
fn test_delete_no_args_still_uses_legacy_path() {
let repo = TestRepo::new();
let wt_path = repo.create_worktree("inside-me");
let out = TestRepo::cw_at(&wt_path, &["delete"]);
assert!(
out.status.success(),
"stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let list = repo.cw_stdout(&["list"]);
assert!(
!list.contains(&worktree_row("inside-me")),
"list still mentions inside-me: {list}"
);
}