use std::collections::BTreeSet;
use relmath::temporal::{Interval, IntervalError};
#[test]
fn rejects_empty_or_inverted_intervals() {
assert_eq!(
Interval::new(2, 2),
Err(IntervalError::InvalidBounds { start: 2, end: 2 })
);
assert_eq!(
Interval::new(5, 3),
Err(IntervalError::InvalidBounds { start: 5, end: 3 })
);
}
#[test]
fn contains_uses_half_open_boundary_semantics() {
let window = Interval::new(10, 13).expect("expected valid interval");
assert!(window.contains(&10));
assert!(window.contains(&12));
assert!(!window.contains(&9));
assert!(!window.contains(&13));
}
#[test]
fn overlaps_distinguishes_adjacent_from_intersecting_intervals() {
let left = Interval::new(1, 3).expect("expected valid interval");
let overlap = Interval::new(2, 4).expect("expected valid interval");
let adjacent = Interval::new(3, 5).expect("expected valid interval");
let disjoint = Interval::new(6, 8).expect("expected valid interval");
assert!(left.overlaps(&overlap));
assert!(!left.overlaps(&adjacent));
assert!(!left.overlaps(&disjoint));
assert!(left.is_adjacent_to(&adjacent));
assert!(left.can_coalesce_with(&adjacent));
assert!(!left.can_coalesce_with(&disjoint));
}
#[test]
fn intersection_and_restriction_return_none_for_boundary_only_contact() {
let base = Interval::new(4, 9).expect("expected valid interval");
let overlap = Interval::new(6, 11).expect("expected valid interval");
let adjacent = Interval::new(9, 12).expect("expected valid interval");
assert_eq!(
base.intersection(&overlap),
Some(Interval::new(6, 9).expect("expected valid interval"))
);
assert_eq!(
base.restrict_to(&overlap),
Some(Interval::new(6, 9).expect("expected valid interval"))
);
assert_eq!(base.intersection(&adjacent), None);
assert_eq!(base.restrict_to(&adjacent), None);
}
#[test]
fn coalesce_merges_overlapping_or_adjacent_intervals() {
let overlap_left = Interval::new(1, 4).expect("expected valid interval");
let overlap_right = Interval::new(3, 6).expect("expected valid interval");
let adjacent = Interval::new(6, 8).expect("expected valid interval");
let disjoint = Interval::new(10, 12).expect("expected valid interval");
assert_eq!(
overlap_left.coalesce(&overlap_right),
Some(Interval::new(1, 6).expect("expected valid interval"))
);
assert_eq!(
overlap_right.coalesce(&adjacent),
Some(Interval::new(3, 8).expect("expected valid interval"))
);
assert_eq!(overlap_left.coalesce(&disjoint), None);
}
#[test]
fn intervals_iterate_in_deterministic_lexicographic_order() {
let ordered = BTreeSet::from([
Interval::new(3, 5).expect("expected valid interval"),
Interval::new(1, 4).expect("expected valid interval"),
Interval::new(1, 3).expect("expected valid interval"),
Interval::new(2, 7).expect("expected valid interval"),
])
.into_iter()
.collect::<Vec<_>>();
assert_eq!(
ordered,
vec![
Interval::new(1, 3).expect("expected valid interval"),
Interval::new(1, 4).expect("expected valid interval"),
Interval::new(2, 7).expect("expected valid interval"),
Interval::new(3, 5).expect("expected valid interval"),
]
);
}