extern crate alloc;
use alloc::collections::BTreeSet;
use alloc::vec::Vec;
use super::super::super::support::{arb_vv, dot};
use super::{arb_dots, have};
use crate::metis::{Cut, Dot, DotSet};
use proptest::prelude::*;
proptest! {
#[test]
fn prop_floor_is_the_greatest_contained_cut(dots in arb_dots()) {
let set = have(&dots);
let floor = set.floor();
for station in 0u32..4 {
let prefix = floor.get(station);
for counter in 1..=prefix {
prop_assert!(set.contains(dot(station, counter)));
}
prop_assert!(!set.contains(dot(station, prefix.saturating_add(1))));
}
}
#[test]
fn prop_high_water_is_a_join_homomorphism_and_floor_is_lax(
a in arb_dots(), b in arb_dots(),
) {
let (sa, sb) = (have(&a), have(&b));
let union = sa.merge(&sb);
prop_assert_eq!(
union.high_water(),
sa.high_water().merge(&sb.high_water())
);
let joined_floors = sa.floor().merge(&sb.floor());
prop_assert!(joined_floors <= union.floor());
}
#[test]
fn prop_holes_are_exactly_the_missing_dots(dots in arb_dots()) {
let set = have(&dots);
let high_water = set.high_water();
let holes: BTreeSet<Dot> = set.holes().collect();
let mut expected = BTreeSet::new();
for station in 0u32..4 {
for counter in 1..=high_water.get(station) {
if !set.contains(dot(station, counter)) {
let _ = expected.insert(dot(station, counter));
}
}
}
prop_assert_eq!(holes, expected);
}
#[test]
fn prop_holes_for_is_the_whole_set_filtered(dots in arb_dots()) {
let set = have(&dots);
for station in 0u32..6 {
let per_station: Vec<u64> = set.holes_for(station).collect();
let filtered: Vec<u64> = set
.holes()
.filter(|hole| hole.station() == station)
.map(Dot::counter)
.collect();
prop_assert_eq!(per_station, filtered);
}
}
#[test]
fn prop_hole_count_equals_holes_counted(dots in arb_dots()) {
let set = have(&dots);
let counted = u64::try_from(set.holes().count()).unwrap();
prop_assert_eq!(set.hole_count(), counted);
}
#[test]
fn prop_floor_and_high_water_bracket_and_never_regress(dots in arb_dots()) {
let mut set = DotSet::new();
let mut last_floor = set.floor();
let mut last_high = set.high_water();
for pair in dots {
if let Ok(dot) = Dot::try_from(pair) {
let _ = set.insert(dot);
}
let floor = set.floor();
let high = set.high_water();
prop_assert!(last_floor <= floor);
prop_assert!(last_high <= high);
prop_assert!(floor <= high);
last_floor = floor;
last_high = high;
}
}
#[test]
fn prop_from_witnessed_embeds_the_cut(cut in arb_vv()) {
let witness = Cut::floor_of(&DotSet::from_cut(&cut));
prop_assert_eq!(witness.as_vector(), &cut);
let set = DotSet::from_witnessed(&witness);
prop_assert_eq!(set.floor(), cut);
prop_assert_eq!(set.high_water(), set.floor());
prop_assert_eq!(set.holes().count(), 0);
prop_assert_eq!(set.exceptions_len(), 0);
}
}