mod common;
use common::TestRepo;
use predicates::prelude::*;
#[test]
fn test_list_in_repo() {
let repo = TestRepo::new();
let output = repo.cw(&["list"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Worktrees for repository:"));
}
#[test]
fn test_status_in_repo() {
let repo = TestRepo::new();
let output = repo.cw(&["status"]);
assert!(output.status.success());
}
#[test]
fn test_tree_in_repo() {
let repo = TestRepo::new();
let output = repo.cw(&["tree"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("(base repository)"));
}
#[test]
fn test_stats_no_worktrees() {
let repo = TestRepo::new();
let output = repo.cw(&["stats"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("No feature worktrees found"));
}
#[test]
fn test_new_creates_worktree() {
let repo = TestRepo::new();
let output = repo.cw(&["new", "test-feature", "--no-ai"]);
assert!(
output.status.success(),
"cw new failed: {}",
String::from_utf8_lossy(&output.stdout)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Worktree created successfully"));
let list_output = repo.cw_stdout(&["list"]);
assert!(list_output.contains("test-feature"));
}
#[test]
fn test_new_invalid_branch_name() {
let repo = TestRepo::new();
let output = repo.cw(&["new", "bad..name", "--no-ai"]);
assert!(!output.status.success());
}
#[test]
fn test_new_then_delete() {
let repo = TestRepo::new();
let output = repo.cw(&["new", "to-delete", "--no-ai"]);
assert!(output.status.success());
let list = repo.cw_stdout(&["list"]);
assert!(list.contains("to-delete"));
let del_output = repo.cw(&["delete", "to-delete"]);
assert!(
del_output.status.success(),
"delete failed: {}",
String::from_utf8_lossy(&del_output.stdout)
);
let list_after = repo.cw_stdout(&["list"]);
assert!(!list_after.contains("to-delete"));
}
#[test]
fn test_new_then_sync() {
let repo = TestRepo::new();
let output = repo.cw(&["new", "sync-test", "--no-ai"]);
assert!(output.status.success());
let sync_output = repo.cw(&["sync", "sync-test"]);
let stdout = String::from_utf8_lossy(&sync_output.stdout);
assert!(stdout.contains("Fetching") || stdout.contains("Syncing") || stdout.contains("Sync"));
}
#[test]
fn test_doctor() {
let repo = TestRepo::new();
let output = repo.cw(&["doctor"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Health Check"));
assert!(stdout.contains("Checking Git version"));
}
#[test]
fn test_config_show() {
let repo = TestRepo::new();
let output = repo.cw(&["config", "show"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("AI Tool:"));
assert!(stdout.contains("Config file:"));
}
#[test]
fn test_backup_list_empty() {
let repo = TestRepo::new();
let output = repo.cw(&["backup", "list"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("No backups found"));
}
#[test]
fn test_stash_list_empty() {
let repo = TestRepo::new();
let output = repo.cw(&["stash", "list"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("No stashes found"));
}
#[test]
fn test_hook_list_empty() {
let repo = TestRepo::new();
let output = repo.cw(&["hook", "list"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("No hooks configured"));
}
#[test]
fn test_path_list_branches() {
let repo = TestRepo::new();
let output = repo.cw(&["_path", "--list-branches"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("main") || stdout.contains("master"));
}
#[test]
fn test_clean_no_criteria() {
let repo = TestRepo::new();
let output = repo.cw(&["clean"]);
assert!(output.status.success()); let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
let combined = format!("{}{}", stdout, stderr);
assert!(combined.contains("criterion") || combined.contains("specify"));
}
#[test]
fn test_clean_dry_run() {
let repo = TestRepo::new();
let output = repo.cw(&["clean", "--merged", "--dry-run"]);
assert!(output.status.success());
}
#[test]
fn test_diff_nonexistent_branch() {
let repo = TestRepo::new();
let output = repo.cw(&["diff", "main", "nonexistent"]);
assert!(!output.status.success());
}
#[test]
fn test_prune_empty() {
let repo = TestRepo::new();
let output = repo.cw(&["prune"]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("stale") || stdout.contains("No stale"));
}
#[test]
fn test_export_creates_file() {
let repo = TestRepo::new();
let export_path = repo.path().join("test-export.json");
let output = repo.cw(&["export", "--output", export_path.to_str().unwrap()]);
assert!(output.status.success());
assert!(export_path.exists());
let content = std::fs::read_to_string(&export_path).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&content).unwrap();
assert_eq!(
parsed.get("export_version").unwrap().as_str().unwrap(),
"1.0"
);
}
#[test]
fn test_import_preview() {
let repo = TestRepo::new();
let export_path = repo.path().join("import-test.json");
repo.cw(&["export", "--output", export_path.to_str().unwrap()]);
let output = repo.cw(&["import", export_path.to_str().unwrap()]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Preview"));
}