use crate::{
cargo_affected, git, init_git_with_initial_commit, replace_in_file, write_two_module_project,
};
#[test]
fn function_body_edit_selects_only_that_test() {
let tmp = tempfile::tempdir().unwrap();
let dir = tmp.path();
write_two_module_project(dir, "sample_narrowing");
init_git_with_initial_commit(dir);
let collect = cargo_affected(dir, &["affected", "collect"]);
assert!(
collect.status.success(),
"collect failed: {}\nstdout: {}",
String::from_utf8_lossy(&collect.stderr),
String::from_utf8_lossy(&collect.stdout)
);
let db_path = dir.join("target/affected/coverage.db");
assert!(
db_path.exists(),
"target/affected/coverage.db should exist after collect"
);
let conn = rusqlite::Connection::open(&db_path).unwrap();
let test_count: i64 = conn
.query_row(
"SELECT COUNT(DISTINCT test_name) FROM test_regions",
[],
|r| r.get(0),
)
.unwrap();
assert_eq!(test_count, 3, "expected 3 tests in DB");
let stored_shas: Vec<String> = conn
.prepare("SELECT DISTINCT collect_sha FROM test_regions")
.unwrap()
.query_map([], |r| r.get::<_, String>(0))
.unwrap()
.map(|r| r.unwrap())
.collect();
assert_eq!(
stored_shas.len(),
1,
"fresh full collect should anchor every row at a single sha, got {stored_shas:?}",
);
assert_eq!(
stored_shas[0].len(),
40,
"stored sha should be a full hex sha",
);
replace_in_file(&dir.join("src/math.rs"), "a + b", "a + b /* edited */");
let status = cargo_affected(dir, &["affected", "status", "-v"]);
assert!(
status.status.success(),
"status failed: {}",
String::from_utf8_lossy(&status.stderr)
);
let stdout = String::from_utf8_lossy(&status.stdout);
assert!(
stdout.contains("test_add"),
"status should list test_add (its function body changed), got:\n{stdout}"
);
assert!(
!stdout.contains("test_multiply"),
"status should NOT list test_multiply (multiply unchanged) — \
function-level narrowing failed:\n{stdout}"
);
assert!(
!stdout.contains("test_greet"),
"status should NOT list test_greet (strings.rs unchanged):\n{stdout}"
);
git(dir, &["checkout", "--", "src/math.rs"]);
}