use std::path::Path;
use crate::mr_scope::mr_base_in;
use crate::test_repo::{self, sha_of};
fn mr_base_in_dir(dir: &Path) -> Result<(String, String), String> {
let old = std::env::current_dir().unwrap();
std::env::set_current_dir(dir).unwrap();
let result = std::panic::catch_unwind(|| mr_base_in(None));
std::env::set_current_dir(old).unwrap();
result.unwrap()
}
fn commit_file_at(dir: &Path, name: &str, msg: &str, epoch: i64) {
std::fs::write(dir.join(name), format!("// {msg}\n")).unwrap();
test_repo::commit_all_at(dir, msg, epoch);
}
fn seed_stacked_branches(dir: &Path) -> String {
test_repo::seed_repo_with_base_commit(dir); test_repo::checkout_new_branch(dir, "feature/one");
commit_file_at(dir, "one.rb", "one", 1_735_689_660); let c1 = sha_of(dir, "refs/heads/feature/one");
test_repo::checkout_new_branch(dir, "feature/two");
commit_file_at(dir, "two.rb", "two", 1_735_689_720); test_repo::checkout_branch_named(dir, "main");
commit_file_at(dir, "main.rb", "advance main", 1_735_689_780); test_repo::checkout_branch_named(dir, "feature/two");
c1
}
#[test]
fn mr_base_uses_nearest_parent_branch_fork_point() {
let dir = test_repo::temp_dir("abcop_forkpoint");
let c1 = seed_stacked_branches(&dir);
let _guard = test_repo::cwd_lock();
let (base, label) = mr_base_in_dir(&dir).expect("base resolves");
assert_eq!(base, c1, "nearest fork point wins; label={label}");
}
#[test]
fn mr_base_on_default_branch_keeps_36h_window() {
let dir = test_repo::temp_dir("abcop_36h");
let _guard = test_repo::cwd_lock();
test_repo::seed_repo_with_base_commit(&dir);
let (_base, label) = mr_base_in_dir(&dir).expect("base resolves");
assert!(
label.contains("36 hours"),
"direct-main work keeps the 36h window; got {label}"
);
}
fn commit_at(dir: &Path, name: &str, msg: &str, epoch: Option<i64>) -> String {
std::fs::write(dir.join(name), format!("// {msg}\n")).unwrap();
match epoch {
Some(t) => test_repo::commit_all_at(dir, msg, t),
None => test_repo::commit_all(dir, msg),
}
sha_of(dir, "HEAD")
}
#[test]
fn mr_base_on_default_branch_rejects_empty_36h_window() {
let dir = test_repo::temp_dir("abcop_36h_empty");
let _guard = test_repo::cwd_lock();
test_repo::seed_repo_with_base_commit(&dir);
test_repo::amend_head_at(&dir, "ancient", 1_577_836_800);
let err = mr_base_in_dir(&dir).expect_err("empty window errors");
assert!(
err.contains("no commits in the last 36 hours"),
"got: {err}"
);
}
#[test]
fn mr_base_on_default_branch_anchors_at_window_edge() {
let dir = test_repo::temp_dir("abcop_36h_anchor");
let _guard = test_repo::cwd_lock();
test_repo::seed_repo_with_base_commit(&dir);
let old = commit_at(&dir, "old.rb", "old work", Some(1_577_836_800));
let _fresh = commit_at(&dir, "new.rb", "new work", None);
let (base, label) = mr_base_in_dir(&dir).expect("base resolves");
assert_eq!(base, old, "anchored at the window edge");
assert!(label.contains("36 hours"), "got {label}");
}