int-interval-set 0.2.0

Integer half-open interval set structures built on top of int-interval.
Documentation
// -----------------------------------------------------------------------------
// This file is generated by `cargo run -p codegen -- --signed`.
// Do not edit manually.
// -----------------------------------------------------------------------------

use crate::i16::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([(i16::MIN, i16::MIN + 1), (i16::MAX - 1, i16::MAX)]);

    assert_eq!(
        set.intervals_intersecting(iv(i16::MIN, i16::MIN + 1))
            .collect::<Vec<_>>(),
        vec![iv(i16::MIN, i16::MIN + 1)]
    );

    assert_eq!(
        set.intersections(iv(i16::MAX - 1, i16::MAX))
            .collect::<Vec<_>>(),
        vec![iv(i16::MAX - 1, i16::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(i16::MAX - 1, i16::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);
    }
}