use super::*;
#[kani::proof]
#[kani::unwind(5)]
fn pending_routes_initialization_is_empty_and_bounded() {
let pending = PendingRoutes::<u8, 3>::new();
assert_eq!(pending.len(), 0);
assert!(pending.slots.iter().all(Option::is_none));
}
#[kani::proof]
#[kani::unwind(6)]
fn pending_routes_preserves_dense_ownership_and_refuses_whole_fanout() {
let length: usize = kani::any();
kani::assume(length <= 3);
let mut pending = PendingRoutes::<u8, 3>::new();
for slot in pending.slots.iter_mut().take(length) {
*slot = Some(kani::any());
}
pending.length = length;
let before = pending.slots;
let operation: u8 = kani::any();
kani::assume(operation <= 5);
match operation {
0 => {
let popped = pending.pop();
assert_eq!(popped.is_some(), length > 0);
assert_eq!(
pending.len().checked_add(usize::from(popped.is_some())),
Some(length)
);
}
1..=5 => {
let route = match operation {
1 => Route::None,
2 => Route::One(kani::any()),
3 => Route::Two(kani::any()),
4 => Route::Three(kani::any()),
_ => Route::Four(kani::any()),
};
let count = route.len();
let expected_refusal = length
.checked_add(count.saturating_sub(1))
.is_none_or(|n| n > 3);
match pending.admit(route) {
Ok(first) => {
assert!(!expected_refusal);
assert_eq!(first.is_some(), count > 0);
assert_eq!(
pending.len(),
length.saturating_add(count.saturating_sub(1))
);
}
Err(rejected) => {
assert!(expected_refusal);
assert_eq!(rejected.len(), count);
assert_eq!(pending.slots, before);
assert_eq!(pending.len(), length);
}
}
}
_ => {}
}
assert!(pending.len() <= pending.capacity());
for (index, slot) in pending.slots.iter().enumerate() {
assert_eq!(slot.is_some(), index < pending.len());
}
}