use iso_code::git::{detect_capabilities, parse_git_version};
use iso_code::types::GitVersion;
#[test]
fn qa_v_001_list_nul_falls_back_below_236() {
let v = parse_git_version("git version 2.35.1\n").unwrap();
let caps = detect_capabilities(&v);
assert!(!caps.has_list_nul, "2.35 must not advertise -z support");
}
#[test]
fn qa_v_002_repair_skipped_below_230() {
let v229 = parse_git_version("git version 2.29.0\n").unwrap();
assert!(!detect_capabilities(&v229).has_repair);
let v230 = parse_git_version("git version 2.30.0\n").unwrap();
assert!(detect_capabilities(&v230).has_repair);
}
#[test]
fn qa_v_003_orphan_branch_requires_242() {
let v241 = parse_git_version("git version 2.41.0\n").unwrap();
assert!(!detect_capabilities(&v241).has_orphan);
let v242 = parse_git_version("git version 2.42.0\n").unwrap();
assert!(detect_capabilities(&v242).has_orphan);
}
#[test]
fn qa_v_004_relative_paths_requires_248() {
let v247 = parse_git_version("git version 2.47.2\n").unwrap();
assert!(!detect_capabilities(&v247).has_relative_paths);
let v248 = parse_git_version("git version 2.48.0\n").unwrap();
assert!(detect_capabilities(&v248).has_relative_paths);
}
#[test]
fn qa_v_005_merge_tree_write_requires_238() {
let v237 = parse_git_version("git version 2.37.4\n").unwrap();
assert!(!detect_capabilities(&v237).has_merge_tree_write);
let v238 = parse_git_version("git version 2.38.0\n").unwrap();
assert!(detect_capabilities(&v238).has_merge_tree_write);
}
#[test]
fn qa_v_006_locked_prunable_absent_below_231() {
let output = b"worktree /tmp/wt\nHEAD aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nbranch refs/heads/main\n\n";
let handles = iso_code::git::parse_worktree_list_porcelain(output, false).unwrap();
assert_eq!(handles.len(), 1);
assert_eq!(handles[0].state, iso_code::WorktreeState::Active);
}
#[test]
fn qa_v_007_lock_flag_is_always_present_on_supported_versions() {
let minimum = GitVersion::MINIMUM;
let flag_introduced = GitVersion { major: 2, minor: 17, patch: 0 };
assert!(minimum >= flag_introduced, "--lock flag must be present at our hard minimum");
}
#[test]
fn qa_v_008_hard_minimum_rejects_219() {
let v = parse_git_version("git version 2.19.0\n").unwrap();
assert!(v < GitVersion::MINIMUM);
}
#[test]
fn qa_v_009_git_not_found_error_variant_exists() {
let e = iso_code::WorktreeError::GitNotFound;
let s = format!("{e}");
assert!(s.contains("git"), "Display: {s}");
}
#[cfg(unix)]
#[test]
fn mock_git_fixtures_report_their_tagged_versions() {
use std::process::Command;
for (tag, expected) in [
("2.19", GitVersion { major: 2, minor: 19, patch: 0 }),
("2.20", GitVersion { major: 2, minor: 20, patch: 0 }),
("2.30", GitVersion { major: 2, minor: 30, patch: 0 }),
("2.35", GitVersion { major: 2, minor: 35, patch: 1 }),
("2.37", GitVersion { major: 2, minor: 37, patch: 4 }),
("2.41", GitVersion { major: 2, minor: 41, patch: 0 }),
("2.47", GitVersion { major: 2, minor: 47, patch: 2 }),
] {
let script = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/mock-git")
.join(format!("git-{tag}"));
let real_path = std::env::var("PATH").unwrap_or_default();
let out = Command::new(&script)
.arg("--version")
.env("MOCK_REAL_PATH", &real_path)
.output()
.unwrap_or_else(|e| panic!("spawn mock git-{tag}: {e}"));
assert!(out.status.success(), "mock git-{tag} --version failed");
let stdout = String::from_utf8_lossy(&out.stdout);
let parsed = parse_git_version(&stdout).unwrap();
assert_eq!(
parsed, expected,
"mock git-{tag} reports {parsed:?}, expected {expected:?}"
);
}
}