use super::super::{config_branches, governing_config};
use crate::git_tree::tests::fixture::Fixture;
use crate::git_tree::{GitTree, GitTreeError};
fn tip(fx: &Fixture, id: &str) -> String {
GitTree::from_repo(&fx.path)
.unwrap()
.agents
.into_iter()
.find(|a| a.agent_id == id)
.unwrap()
.tip_oid
}
fn branch_tip(fx: &Fixture, name: &str) -> String {
config_branches(&fx.path)
.unwrap()
.into_iter()
.find(|b| b.name == name)
.unwrap()
.tip_oid
}
#[test]
fn governing_config_is_the_fork_point_for_a_fresh_agent() {
let fx = Fixture::new();
fx.agent_off("r1", "config/default");
let gov = governing_config(&fx.path, &tip(&fx, "r1")).unwrap();
assert_eq!(gov.oid, branch_tip(&fx, "default"));
assert_eq!(gov.branch_name_if_tip_of_one.as_deref(), Some("default"));
assert!(gov.files.contains(&"version".to_string()));
}
#[test]
fn governing_config_freezes_at_the_fork_point_after_the_branch_advances() {
let fx = Fixture::new();
fx.agent_off("r1", "config/default");
fx.commit_other("workflow.yaml", "events: {}\n");
let gov = governing_config(&fx.path, &tip(&fx, "r1")).unwrap();
assert_ne!(gov.oid, branch_tip(&fx, "default"));
assert_eq!(gov.branch_name_if_tip_of_one, None);
assert!(gov.files.contains(&"version".to_string()));
assert!(!gov.files.contains(&"workflow.yaml".to_string()));
assert_eq!(
gov.frozen_label(),
format!("policy frozen at {}", gov.short_oid)
);
}
#[test]
fn governing_config_picks_the_nearer_ancestor_arriving_later() {
let fx = Fixture::new();
fx.config_off("strict", "config/default");
fx.agent_off("r1", "config/strict");
let gov = governing_config(&fx.path, &tip(&fx, "r1")).unwrap();
assert_eq!(gov.oid, branch_tip(&fx, "strict"));
assert_eq!(gov.branch_name_if_tip_of_one.as_deref(), Some("strict"));
}
#[test]
fn governing_config_keeps_the_nearer_ancestor_arriving_first() {
let fx = Fixture::new();
fx.config_off("aaa", "config/default");
fx.agent_off("r1", "config/aaa");
let gov = governing_config(&fx.path, &tip(&fx, "r1")).unwrap();
assert_eq!(gov.oid, branch_tip(&fx, "aaa"));
}
#[test]
fn governing_config_folds_two_equal_candidates() {
let fx = Fixture::new();
fx.config_alias("twin", "config/default");
fx.agent_off("r1", "config/default");
let gov = governing_config(&fx.path, &tip(&fx, "r1")).unwrap();
assert_eq!(gov.oid, branch_tip(&fx, "default"));
assert_eq!(gov.branch_name_if_tip_of_one.as_deref(), Some("default"));
}
#[test]
fn governing_config_skips_an_unrelated_orphan_config() {
let fx = Fixture::new();
fx.agent_off("r1", "config/default");
fx.orphan_config("island");
let gov = governing_config(&fx.path, &tip(&fx, "r1")).unwrap();
assert_eq!(gov.branch_name_if_tip_of_one.as_deref(), Some("default"));
}
#[test]
fn governing_config_declines_an_agent_with_no_config_ancestor() {
let fx = Fixture::new();
fx.orphan_agent("x1");
let err = governing_config(&fx.path, &tip(&fx, "x1")).unwrap_err();
assert!(matches!(err, GitTreeError::Governing(_)), "{err}");
assert!(err.to_string().contains("no config/* ancestor"), "{err}");
}
#[test]
fn governing_config_declines_incomparable_candidates() {
let fx = Fixture::new();
fx.agent_off("r1", "config/default");
fx.orphan_config("island");
fx.cross_merge("r1", "island");
let err = governing_config(&fx.path, &tip(&fx, "r1")).unwrap_err();
assert!(matches!(err, GitTreeError::Governing(_)), "{err}");
assert!(err.to_string().contains("incomparable"), "{err}");
}