use crate::u64::tests::{
set::test_support::build,
test_support::{build_from_vec, interval_pair, iv},
};
#[test]
fn search_interval_returns_empty_on_empty_set() {
let set = build([]);
assert_eq!(
set.intervals_intersecting(iv(0, 1)).collect::<Vec<_>>(),
vec![]
);
assert_eq!(set.intersections(iv(0, 1)).collect::<Vec<_>>(), vec![]);
}
#[test]
fn search_interval_intervals_intersecting_respects_half_open_bounds() {
let set = build([(10, 20), (30, 40)]);
assert_eq!(
set.intervals_intersecting(iv(0, 10)).collect::<Vec<_>>(),
vec![]
);
assert_eq!(
set.intervals_intersecting(iv(20, 30)).collect::<Vec<_>>(),
vec![]
);
assert_eq!(
set.intervals_intersecting(iv(40, 50)).collect::<Vec<_>>(),
vec![]
);
assert_eq!(
set.intervals_intersecting(iv(9, 11)).collect::<Vec<_>>(),
vec![iv(10, 20)]
);
assert_eq!(
set.intervals_intersecting(iv(19, 21)).collect::<Vec<_>>(),
vec![iv(10, 20)]
);
}
#[test]
fn search_interval_intervals_intersecting_returns_original_canonical_intervals() {
let set = build([(10, 20), (30, 40), (50, 60)]);
assert_eq!(
set.intervals_intersecting(iv(15, 55)).collect::<Vec<_>>(),
vec![iv(10, 20), iv(30, 40), iv(50, 60)]
);
}
#[test]
fn search_interval_intersections_returns_clipped_segments() {
let set = build([(10, 20), (30, 40), (50, 60)]);
assert_eq!(
set.intersections(iv(15, 55)).collect::<Vec<_>>(),
vec![iv(15, 20), iv(30, 40), iv(50, 55)]
);
}
#[test]
fn search_interval_intersections_can_return_full_interval_when_query_contains_it() {
let set = build([(10, 20), (30, 40)]);
assert_eq!(
set.intersections(iv(9, 41)).collect::<Vec<_>>(),
vec![iv(10, 20), iv(30, 40)]
);
}
#[test]
fn search_interval_intersections_can_return_inner_query_when_fully_contained() {
let set = build([(10, 40)]);
assert_eq!(
set.intersections(iv(15, 25)).collect::<Vec<_>>(),
vec![iv(15, 25)]
);
}
#[test]
fn search_interval_works_after_canonical_merge() {
let set = build([(0, 5), (5, 10), (12, 20), (18, 30)]);
assert_eq!(set.as_slice(), &[iv(0, 10), iv(12, 30)]);
assert_eq!(
set.intervals_intersecting(iv(9, 13)).collect::<Vec<_>>(),
vec![iv(0, 10), iv(12, 30)]
);
assert_eq!(
set.intersections(iv(9, 13)).collect::<Vec<_>>(),
vec![iv(9, 10), iv(12, 13)]
);
}
#[test]
fn search_interval_returns_empty_for_gap_only_query() {
let set = build([(10, 20), (30, 40)]);
assert_eq!(
set.intervals_intersecting(iv(20, 30)).collect::<Vec<_>>(),
vec![]
);
assert_eq!(set.intersections(iv(20, 30)).collect::<Vec<_>>(), vec![]);
}
#[test]
fn search_interval_handles_domain_edges() {
let set = build([(u64::MIN, u64::MIN + 1), (u64::MAX - 1, u64::MAX)]);
assert_eq!(
set.intervals_intersecting(iv(u64::MIN, u64::MIN + 1))
.collect::<Vec<_>>(),
vec![iv(u64::MIN, u64::MIN + 1)]
);
assert_eq!(
set.intersections(iv(u64::MAX - 1, u64::MAX))
.collect::<Vec<_>>(),
vec![iv(u64::MAX - 1, u64::MAX)]
);
}
#[test]
fn search_interval_intervals_intersecting_matches_predicate() {
let set = build([(10, 20), (30, 40), (50, 60)]);
for query in [
iv(0, 10),
iv(9, 11),
iv(15, 35),
iv(20, 30),
iv(39, 41),
iv(40, 50),
iv(55, 61),
iv(u64::MAX - 1, u64::MAX),
] {
assert_eq!(
set.intervals_intersecting(query).next().is_some(),
set.intersects_interval(query),
"query = {query:?}"
);
}
}
use proptest::prelude::*;
proptest! {
#[test]
fn prop_intervals_intersecting_matches_slice_filter(
xs in prop::collection::vec(interval_pair(), 0..64),
query in interval_pair(),
) {
let set = build_from_vec(xs);
let query = iv(query.0, query.1);
let got = set.intervals_intersecting(query).collect::<Vec<_>>();
let expected = set
.as_slice()
.iter()
.copied()
.filter(|iv| iv.intersects(query))
.collect::<Vec<_>>();
prop_assert_eq!(got, expected);
}
#[test]
fn prop_intersections_matches_slice_filter_map(
xs in prop::collection::vec(interval_pair(), 0..64),
query in interval_pair(),
) {
let set = build_from_vec(xs);
let query = iv(query.0, query.1);
let got = set.intersections(query).collect::<Vec<_>>();
let expected = set
.as_slice()
.iter()
.copied()
.filter_map(|iv| iv.intersection(query))
.collect::<Vec<_>>();
prop_assert_eq!(got, expected);
}
}