use super::*;
use std::process::Command;
fn git_available() -> bool {
Command::new("git")
.arg("--version")
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}
fn init_repo_with_commit(dir: &Path) -> PathBuf {
let file = dir.join("tracked.rs");
fs::write(&file, "pub fn f() -> i32 { 1 }\n").expect("write fixture");
let run = |args: &[&str]| {
Command::new("git")
.arg("-C")
.arg(dir)
.args(args)
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.expect("git must run");
};
run(&["init", "-q"]);
run(&["config", "user.email", "t@example.com"]);
run(&["config", "user.name", "t"]);
run(&["add", "-A"]);
run(&["commit", "-qm", "init", "--no-verify"]);
file
}
#[test]
fn test_git_tracked_does_not_depend_on_process_cwd() {
if !git_available() {
return;
}
let temp = tempfile::tempdir().expect("tempdir");
let file = init_repo_with_commit(temp.path());
assert!(
is_file_git_tracked(&file),
"a committed file must read as tracked no matter which directory pmat was invoked from"
);
}
#[test]
fn test_untracked_file_still_reads_as_untracked() {
if !git_available() {
return;
}
let temp = tempfile::tempdir().expect("tempdir");
init_repo_with_commit(temp.path());
let fresh = temp.path().join("fresh.rs");
fs::write(&fresh, "pub fn g() -> i32 { 2 }\n").expect("write fixture");
assert!(
!is_file_git_tracked(&fresh),
"an uncommitted file must still read as untracked (issue #279)"
);
}
#[test]
fn test_critical_defect_grade_is_cwd_independent() {
if !git_available() {
return;
}
let temp = tempfile::tempdir().expect("tempdir");
let dir = temp.path();
let file = dir.join("bad.rs");
fs::write(
&file,
"pub fn boom(v: Vec<i32>) -> i32 {\n let x: Option<i32> = v.first().copied();\n x.unwrap()\n}\n",
)
.expect("write fixture");
let run = |args: &[&str]| {
Command::new("git")
.arg("-C")
.arg(dir)
.args(args)
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.expect("git must run");
};
run(&["init", "-q"]);
run(&["config", "user.email", "t@example.com"]);
run(&["config", "user.name", "t"]);
run(&["add", "-A"]);
run(&["commit", "-qm", "init", "--no-verify"]);
let analyzer = TdgAnalyzerAst::new().expect("analyzer");
let source = fs::read_to_string(&file).expect("read fixture");
let score = analyzer
.analyze_source(&source, Language::Rust, Some(file.clone()))
.expect("analysis");
assert_eq!(score.critical_defects_count, 1);
assert!(
score.has_critical_defects,
"committed file with a critical defect must auto-fail from any CWD"
);
assert_eq!(score.total, 0.0);
assert_eq!(score.grade, Grade::F);
}