use alpha_id::fusion::{rrf_merge, cross_segment_dedupe}; use alpha_id::model::Candidate; fn cand(code: &str, seg: usize, rerank: Option) -> Candidate { Candidate { icd_code: code.into(), alpha_text: code.into(), segment_idx: seg, lexical: None, semantic: None, rerank } } #[test] fn rrf_merges_two_rankings_by_reciprocal_rank() { let lex = vec![0usize, 1, 2]; // entry indices ranked let sem = vec![2usize, 0, 3]; let merged = rrf_merge(&lex, &sem, 60); // entry 0 appears rank0 in lex and rank1 in sem -> highest assert_eq!(merged[0], 0); assert!(merged.contains(&3)); } #[test] fn cross_segment_keeps_max_score_and_all_sources() { let cands = vec![ cand("E11.9", 0, Some(0.4)), cand("E11.9", 2, Some(0.9)), cand("I10.90", 1, Some(0.5)), ]; let mut merged = cross_segment_dedupe(cands); merged.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap()); assert_eq!(merged[0].0.icd_code, "E11.9"); assert_eq!(merged[0].1, 0.9); // max assert_eq!(merged[0].0.source_segments, vec![0, 2]); // all sources }