use crate::isize::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([(-50, -40), (-20, -10), (10, 20)]);
assert_eq!(
set.intervals_intersecting(iv(-45, 15)).collect::<Vec<_>>(),
vec![iv(-50, -40), iv(-20, -10), iv(10, 20)]
);
}
#[test]
fn search_interval_intersections_returns_clipped_segments() {
let set = build([(-50, -40), (-20, -10), (10, 20)]);
assert_eq!(
set.intersections(iv(-45, 15)).collect::<Vec<_>>(),
vec![iv(-45, -40), iv(-20, -10), iv(10, 15)]
);
}
#[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([(-20, -10), (-10, 0), (5, 15), (10, 20)]);
assert_eq!(set.as_slice(), &[iv(-20, 0), iv(5, 20)]);
assert_eq!(
set.intervals_intersecting(iv(-1, 6)).collect::<Vec<_>>(),
vec![iv(-20, 0), iv(5, 20)]
);
assert_eq!(
set.intersections(iv(-1, 6)).collect::<Vec<_>>(),
vec![iv(-1, 0), iv(5, 6)]
);
}
#[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([(isize::MIN, isize::MIN + 1), (isize::MAX - 1, isize::MAX)]);
assert_eq!(
set.intervals_intersecting(iv(isize::MIN, isize::MIN + 1))
.collect::<Vec<_>>(),
vec![iv(isize::MIN, isize::MIN + 1)]
);
assert_eq!(
set.intersections(iv(isize::MAX - 1, isize::MAX))
.collect::<Vec<_>>(),
vec![iv(isize::MAX - 1, isize::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(isize::MAX - 1, isize::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);
}
}