use std::path::Path;
use std::process::Command;
use tempfile::TempDir;
fn create_temp_repo() -> TempDir {
let dir = TempDir::new().expect("Failed to create temp dir");
run_git(dir.path(), &["init"]);
run_git(dir.path(), &["config", "user.email", "test@example.com"]);
run_git(dir.path(), &["config", "user.name", "Test User"]);
std::fs::write(dir.path().join("README.md"), "# Test").expect("Failed to write file");
run_git(dir.path(), &["add", "."]);
run_git(dir.path(), &["commit", "-m", "Initial commit"]);
dir
}
fn run_git(dir: &Path, args: &[&str]) -> String {
let output = Command::new("git")
.args(args)
.current_dir(dir)
.output()
.expect("Failed to run git command");
String::from_utf8_lossy(&output.stdout).trim().to_string()
}
fn git_check(dir: &Path, args: &[&str]) -> bool {
Command::new("git")
.args(args)
.current_dir(dir)
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
#[test]
fn test_is_git_repo() {
let dir = create_temp_repo();
let result = git_check(dir.path(), &["rev-parse", "--git-dir"]);
assert!(result);
}
#[test]
fn test_is_not_git_repo() {
let dir = TempDir::new().expect("Failed to create temp dir");
let result = git_check(dir.path(), &["rev-parse", "--git-dir"]);
assert!(!result);
}
#[test]
fn test_current_branch() {
let dir = create_temp_repo();
let branch = run_git(dir.path(), &["rev-parse", "--abbrev-ref", "HEAD"]);
assert!(branch == "main" || branch == "master");
}
#[test]
fn test_branch_exists() {
let dir = create_temp_repo();
run_git(dir.path(), &["branch", "test-branch"]);
let exists = git_check(
dir.path(),
&["show-ref", "--verify", "--quiet", "refs/heads/test-branch"],
);
assert!(exists);
let not_exists = git_check(
dir.path(),
&[
"show-ref",
"--verify",
"--quiet",
"refs/heads/nonexistent-branch",
],
);
assert!(!not_exists);
}
#[test]
fn test_has_uncommitted_changes_clean() {
let dir = create_temp_repo();
let has_unstaged = !git_check(dir.path(), &["diff", "--quiet"]);
let has_staged = !git_check(dir.path(), &["diff", "--cached", "--quiet"]);
assert!(!has_unstaged);
assert!(!has_staged);
}
#[test]
fn test_has_uncommitted_changes_unstaged() {
let dir = create_temp_repo();
std::fs::write(dir.path().join("README.md"), "# Modified").expect("Failed to write file");
let has_unstaged = !git_check(dir.path(), &["diff", "--quiet"]);
let has_staged = !git_check(dir.path(), &["diff", "--cached", "--quiet"]);
assert!(has_unstaged);
assert!(!has_staged);
}
#[test]
fn test_has_uncommitted_changes_staged() {
let dir = create_temp_repo();
std::fs::write(dir.path().join("README.md"), "# Modified").expect("Failed to write file");
run_git(dir.path(), &["add", "README.md"]);
let has_unstaged = !git_check(dir.path(), &["diff", "--quiet"]);
let has_staged = !git_check(dir.path(), &["diff", "--cached", "--quiet"]);
assert!(!has_unstaged);
assert!(has_staged);
}
#[test]
fn test_is_worktree_main_repo() {
let dir = create_temp_repo();
let git_dir = run_git(dir.path(), &["rev-parse", "--git-dir"]);
let common_dir = run_git(dir.path(), &["rev-parse", "--git-common-dir"]);
assert_eq!(git_dir, common_dir);
}
#[test]
fn test_head_commit() {
let dir = create_temp_repo();
let commit = run_git(dir.path(), &["rev-parse", "HEAD"]);
assert!(!commit.is_empty());
assert_eq!(commit.len(), 40); }
#[test]
fn test_short_commit() {
let dir = create_temp_repo();
let commit = run_git(dir.path(), &["rev-parse", "--short", "HEAD"]);
assert!(!commit.is_empty());
assert!(commit.len() <= 10); }
#[test]
fn test_head_commit_message() {
let dir = create_temp_repo();
let msg = run_git(dir.path(), &["log", "-1", "--format=%s"]);
assert_eq!(msg, "Initial commit");
}
#[test]
fn test_stash_count_empty() {
let dir = create_temp_repo();
let output = run_git(dir.path(), &["stash", "list"]);
let count = if output.is_empty() {
0
} else {
output.lines().count()
};
assert_eq!(count, 0);
}
#[test]
fn test_checkout_new_branch() {
let dir = create_temp_repo();
let current = run_git(dir.path(), &["rev-parse", "--abbrev-ref", "HEAD"]);
run_git(
dir.path(),
&["checkout", "-b", "new-feature", ¤t, "--quiet"],
);
let branch = run_git(dir.path(), &["rev-parse", "--abbrev-ref", "HEAD"]);
assert_eq!(branch, "new-feature");
}
#[test]
fn test_delete_branch() {
let dir = create_temp_repo();
run_git(dir.path(), &["branch", "to-delete"]);
assert!(git_check(
dir.path(),
&["show-ref", "--verify", "--quiet", "refs/heads/to-delete"]
));
run_git(dir.path(), &["branch", "-d", "to-delete"]);
assert!(!git_check(
dir.path(),
&["show-ref", "--verify", "--quiet", "refs/heads/to-delete"]
));
}