use super::*;
#[test]
fn sorted_unique_uses_fast_path_and_looks_up() {
let ids = [1u32, 5, 9, 100];
let starts = [10u32, 20, 30, 40];
let lengths = [3u32, 4, 5, 6];
let idx = ColumnarEntityIndex::from_columns(&ids, &starts, &lengths);
assert_eq!(idx.len(), 4);
assert_eq!(idx.lookup(1), Some((10, 13)));
assert_eq!(idx.lookup(5), Some((20, 24)));
assert_eq!(idx.lookup(100), Some((40, 46)));
assert_eq!(idx.lookup(2), None);
assert_eq!(idx.lookup(101), None);
}
#[test]
fn unsorted_input_is_sorted_then_searched() {
let ids = [100u32, 1, 9, 5];
let starts = [40u32, 10, 30, 20];
let lengths = [6u32, 3, 5, 4];
let idx = ColumnarEntityIndex::from_columns(&ids, &starts, &lengths);
assert_eq!(idx.ids(), &[1, 5, 9, 100]);
assert_eq!(idx.lookup(1), Some((10, 13)));
assert_eq!(idx.lookup(5), Some((20, 24)));
assert_eq!(idx.lookup(9), Some((30, 35)));
assert_eq!(idx.lookup(100), Some((40, 46)));
}
#[test]
fn duplicate_id_last_wins() {
let ids = [7u32, 3, 7];
let starts = [10u32, 20, 30];
let lengths = [1u32, 2, 3];
let idx = ColumnarEntityIndex::from_columns(&ids, &starts, &lengths);
assert_eq!(idx.len(), 2);
assert_eq!(idx.lookup(7), Some((30, 33)));
assert_eq!(idx.lookup(3), Some((20, 22)));
}
#[test]
fn adjacent_duplicate_ids_do_not_take_the_sorted_fast_path() {
let ids = [1u32, 1, 5];
let starts = [10u32, 20, 30];
let lengths = [1u32, 2, 3];
let idx = ColumnarEntityIndex::from_columns(&ids, &starts, &lengths);
assert_eq!(idx.len(), 2, "adjacent duplicate id must be deduped, not adopted as-is");
assert_eq!(idx.lookup(1), Some((20, 22)));
assert_eq!(idx.lookup(5), Some((30, 33)));
assert_eq!(idx.ids(), &[1, 5]);
}
#[test]
fn empty_and_mismatched_columns_are_empty() {
assert!(ColumnarEntityIndex::from_columns(&[], &[], &[]).is_empty());
assert!(ColumnarEntityIndex::from_columns(&[1, 2], &[0], &[0, 0]).is_empty());
}
#[test]
fn from_hashmap_matches_lookup() {
let content = "ISO-10303-21;\nHEADER;\nENDSEC;\nDATA;\n\
#1=IFCCARTESIANPOINT((0.,0.,0.));\n\
#7=IFCCARTESIANPOINT((1.,2.,3.));\n\
#1=IFCCARTESIANPOINT((9.,9.,9.));\n\
ENDSEC;\nEND-ISO-10303-21;\n";
let map = crate::build_entity_index(content);
let col = ColumnarEntityIndex::from_hashmap(&map);
assert_eq!(col.len(), 2, "duplicate #1 must collapse to one entry");
assert_eq!(col.len(), map.len());
for (&id, &(s, e)) in map.iter() {
assert_eq!(col.lookup(id), Some((s, e)));
}
let (start_1, end_1) = col.lookup(1).unwrap();
assert_eq!(&content.as_bytes()[start_1..end_1], b"#1=IFCCARTESIANPOINT((9.,9.,9.));");
let scanned = ColumnarEntityIndex::from_scan(content);
assert_eq!(scanned.ids(), col.ids());
assert_eq!(scanned.starts(), col.starts());
assert_eq!(scanned.lengths(), col.lengths());
for &id in col.ids() {
assert_eq!(scanned.lookup(id), col.lookup(id));
}
}
#[test]
fn consuming_and_borrowing_hashmap_builds_agree() {
let mut map: crate::EntityIndex = Default::default();
for (id, start, end) in [(7u32, 100usize, 150usize), (3, 0, 40), (9, 200, 260), (1, 41, 99)] {
map.insert(id, (start, end));
}
let borrowed = ColumnarEntityIndex::from_hashmap(&map);
let consumed = ColumnarEntityIndex::from_hashmap_consuming(map);
for id in [0u32, 1, 3, 7, 9, 10, u32::MAX] {
assert_eq!(borrowed.lookup(id), consumed.lookup(id), "id {id}");
}
assert_eq!(consumed.len(), 4);
}