use automapper_validation::eval::{EvaluationContext, GroupScope, MapExternalProvider};
use mig_types::navigator::GroupNavigator;
use mig_types::segment::OwnedSegment;
#[test]
fn context_defaults_scope_to_none() {
let external = MapExternalProvider::new(Default::default());
let segments = vec![];
let ctx = EvaluationContext::new("55218", &external, &segments);
assert!(ctx.scope.is_none());
}
#[test]
fn with_scope_sets_scope() {
let external = MapExternalProvider::new(Default::default());
let segments = vec![];
let ctx = EvaluationContext::new("55218", &external, &segments);
let path = ["SG4", "SG8"];
let scope = GroupScope {
group_path: &path,
instance_index: 2,
};
let scoped = ctx.with_scope(scope);
let s = scoped.scope.expect("scope set");
assert_eq!(s.group_path, &["SG4", "SG8"]);
assert_eq!(s.instance_index, 2);
}
struct StubNavigator {
per_instance: Vec<Vec<OwnedSegment>>,
}
impl GroupNavigator for StubNavigator {
fn find_segments_in_group(&self, tag: &str, _: &[&str], idx: usize) -> Vec<OwnedSegment> {
self.per_instance
.get(idx)
.cloned()
.unwrap_or_default()
.into_iter()
.filter(|s| s.id == tag)
.collect()
}
fn find_segments_with_qualifier_in_group(
&self,
tag: &str,
elem: usize,
qual: &str,
_: &[&str],
idx: usize,
) -> Vec<OwnedSegment> {
self.per_instance
.get(idx)
.cloned()
.unwrap_or_default()
.into_iter()
.filter(|s| {
s.id == tag
&& s.elements
.get(elem)
.and_then(|e| e.first())
.is_some_and(|v| v == qual)
})
.collect()
}
fn group_instance_count(&self, _: &[&str]) -> usize {
self.per_instance.len()
}
}
fn pia(code: &str) -> OwnedSegment {
OwnedSegment {
id: "PIA".to_string(),
segment_number: 0,
elements: vec![vec!["Z02".to_string()], vec![code.to_string()]],
}
}
#[test]
fn scoped_find_segments_returns_segments_in_instance_only() {
let nav = StubNavigator {
per_instance: vec![
vec![pia("1-02-0-001")],
vec![pia("1-08-4-004")],
vec![pia("1-10-1")],
],
};
let external = MapExternalProvider::new(Default::default());
let segments = vec![];
let ctx = EvaluationContext::with_navigator("55218", &external, &segments, &nav);
let path = ["SG4", "SG8"];
let ctx1 = ctx.with_scope(GroupScope {
group_path: &path,
instance_index: 1,
});
let found = ctx1.scoped_find_segments("PIA");
assert_eq!(found.len(), 1);
assert_eq!(found[0].elements[1][0], "1-08-4-004");
}
#[test]
fn scoped_find_segments_falls_back_to_message_wide_when_scope_is_none() {
let external = MapExternalProvider::new(Default::default());
let segments = vec![pia("1-02-0-001"), pia("1-10-1")];
let ctx = EvaluationContext::new("55218", &external, &segments);
let found = ctx.scoped_find_segments("PIA");
assert_eq!(found.len(), 2);
}
#[test]
fn scoped_find_segments_with_qualifier_narrows_by_scope() {
let nav = StubNavigator {
per_instance: vec![
vec![pia("1-02-0-001"), pia("1-08-4-004")],
vec![pia("1-10-1")],
],
};
let external = MapExternalProvider::new(Default::default());
let segments = vec![];
let ctx = EvaluationContext::with_navigator("55218", &external, &segments, &nav);
let path = ["SG4", "SG8"];
let ctx0 = ctx.with_scope(GroupScope {
group_path: &path,
instance_index: 0,
});
let found = ctx0.scoped_find_segments_with_qualifier("PIA", 0, "Z02");
assert_eq!(found.len(), 2, "both PIAs in instance 0 are Z02");
}
#[test]
fn scoped_find_segments_with_qualifier_falls_back_to_message_wide() {
let external = MapExternalProvider::new(Default::default());
let segments = vec![pia("1-02-0-001"), pia("1-10-1")];
let ctx = EvaluationContext::new("55218", &external, &segments);
let found = ctx.scoped_find_segments_with_qualifier("PIA", 0, "Z02");
assert_eq!(found.len(), 2);
}