extern crate alloc;
use alloc::vec::Vec;
use super::super::support::{dot, vv};
use crate::metis::{Cut, Dot, DotSet, Stability};
#[test]
fn test_floor_is_gap_free_and_maximal() {
let mut have = DotSet::new();
assert!(have.insert(dot(1, 1)));
assert!(have.insert(dot(1, 2)));
assert!(have.insert(dot(1, 5)));
assert_eq!(have.floor(), vv(&[(1, 2)]));
assert_eq!(have.high_water(), vv(&[(1, 5)]));
let holes: Vec<_> = have.holes().collect();
assert_eq!(holes, [dot(1, 3), dot(1, 4)]);
}
#[test]
fn test_station_summaries_expose_compact_bounds_without_empty_rows() {
let mut have = DotSet::new();
for (station, counter) in [(7, 1), (7, 3), (11, 1), (11, 2)] {
assert!(have.insert(dot(station, counter)));
}
assert_eq!(have.station_count(), 2);
let summaries: Vec<_> = have.stations().collect();
assert_eq!(
summaries,
[
have.station(7).expect("station seven exists"),
have.station(11).expect("station eleven exists"),
]
);
assert_eq!(summaries[0].station(), 7);
assert_eq!(summaries[0].floor(), 1);
assert_eq!(summaries[0].high_water(), 3);
assert_eq!(summaries[0].forward_gap(), 2);
assert_eq!(summaries[1].forward_gap(), 0);
assert_eq!(have.station(9), None);
}
#[test]
fn test_out_of_order_arrival_converges() {
let mut have = DotSet::new();
assert!(have.insert(dot(1, 3)));
assert!(have.insert(dot(1, 1)));
assert!(have.insert(dot(1, 2)));
assert_eq!(have.floor(), vv(&[(1, 3)]));
assert_eq!(have.high_water(), vv(&[(1, 3)]));
assert_eq!(have.exceptions_len(), 0);
assert_eq!(have.holes().count(), 0);
}
#[test]
fn test_dot_zero_is_not_a_dot() {
assert!(Dot::from_parts(1, 0).is_err());
assert!(Dot::try_from((1, 0)).is_err());
let have = DotSet::new();
assert_eq!(have, DotSet::new());
}
#[test]
fn test_duplicate_insert_is_idempotent() {
let mut have = DotSet::new();
assert!(have.insert(dot(2, 4)));
let before = have.clone();
assert!(!have.insert(dot(2, 4)));
assert_eq!(have, before);
}
#[test]
fn test_hole_fill_absorbs_the_parked_run() {
let mut have = DotSet::new();
for counter in [1, 3, 4, 5] {
assert!(have.insert(dot(1, counter)));
}
assert_eq!(have.floor(), vv(&[(1, 1)]));
assert_eq!(have.exceptions_len(), 3);
assert!(have.insert(dot(1, 2)));
assert_eq!(have.floor(), vv(&[(1, 5)]));
assert_eq!(have.exceptions_len(), 0);
}
#[test]
fn test_from_witnessed_round_trips() {
let cut = vv(&[(1, 3), (4, 1)]);
let witness = Cut::floor_of(&DotSet::from_cut(&cut));
let have = DotSet::from_witnessed(&witness);
assert_eq!(have.floor(), cut);
assert_eq!(have.high_water(), cut);
assert_eq!(have.holes().count(), 0);
assert!(have.contains(dot(1, 3)));
assert!(!have.contains(dot(1, 4)));
}
#[test]
fn test_merge_fills_each_others_holes() {
let mut a = DotSet::new();
assert!(a.insert(dot(1, 1)));
assert!(a.insert(dot(1, 3)));
let mut b = DotSet::new();
assert!(b.insert(dot(1, 2)));
let union = a.merge(&b);
assert_eq!(a.floor().merge(&b.floor()), vv(&[(1, 1)]));
assert_eq!(union.floor(), vv(&[(1, 3)]));
}
#[test]
fn test_high_water_matches_the_horizon_shape() {
let mut have = DotSet::new();
assert!(have.insert(dot(1, 1)));
assert!(have.insert(dot(1, 6)));
assert_eq!(have.high_water(), vv(&[(1, 6)]));
assert_eq!(have.floor(), vv(&[(1, 1)]));
let holes: Vec<_> = have.holes().collect();
assert_eq!(holes, [dot(1, 2), dot(1, 3), dot(1, 4), dot(1, 5)]);
}
#[test]
fn test_difference_names_the_owed_dots() {
let mut mine = DotSet::new();
for counter in [1, 2, 3, 4, 5, 8] {
assert!(mine.insert(dot(1, counter)));
}
let mut yours = DotSet::new();
for counter in [1, 2, 4] {
assert!(yours.insert(dot(1, counter)));
}
let owed: Vec<_> = mine.difference(&yours).collect();
assert_eq!(owed, [dot(1, 3), dot(1, 5), dot(1, 8)]);
for owed_dot in owed {
assert!(yours.insert(owed_dot));
}
assert_eq!(yours, mine.merge(&yours));
assert_eq!(yours.difference(&mine).next(), None);
}
#[test]
fn test_cut_difference_is_the_residual_span() {
let mine = DotSet::from_cut(&vv(&[(1, 5)]));
let yours = DotSet::from_cut(&vv(&[(1, 3)]));
let owed: Vec<_> = mine.difference(&yours).collect();
assert_eq!(owed, [dot(1, 4), dot(1, 5)]);
}
#[test]
fn test_reports_honestly_for_stability() {
let mut have = DotSet::new();
for (station, counter) in [(1, 1), (1, 2), (2, 1), (2, 3)] {
assert!(have.insert(dot(station, counter)));
}
let mut tracker = Stability::new([1, 2]);
tracker.report(1, &vv(&[(1, 4), (2, 3)])).unwrap();
tracker.report(2, &have.floor()).unwrap();
let watermark = tracker.watermark();
assert_eq!(watermark, vv(&[(1, 2), (2, 1)]));
let holes: Vec<_> = have.holes().collect();
assert_eq!(holes, [dot(2, 2)]);
assert!(watermark.get(2) < 2);
}