extern crate alloc;
use alloc::vec::Vec;
use super::super::super::super::support::dot;
use crate::metis::{DotSet, HaveSetDecodeBudget, HaveSetDecodeError};
#[test]
fn test_have_set_from_bytes_rejects_zero_length_run() {
let mut frame = Vec::new();
frame.push(0x01u8);
frame.extend_from_slice(&1u32.to_be_bytes());
frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&2u64.to_be_bytes()); frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&5u64.to_be_bytes()); frame.extend_from_slice(&0u64.to_be_bytes()); assert_eq!(
DotSet::from_bytes(&frame),
Err(HaveSetDecodeError::ZeroLengthRun { station: 1 })
);
}
#[test]
fn test_have_set_from_bytes_rejects_run_adjacent_to_floor() {
let mut frame = Vec::new();
frame.push(0x01u8);
frame.extend_from_slice(&1u32.to_be_bytes());
frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&3u64.to_be_bytes()); frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&4u64.to_be_bytes()); frame.extend_from_slice(&1u64.to_be_bytes()); assert_eq!(
DotSet::from_bytes(&frame),
Err(HaveSetDecodeError::NonMaximalRun {
station: 1,
start: 4,
})
);
}
#[test]
fn test_have_set_from_bytes_rejects_adjacent_runs() {
let mut frame = Vec::new();
frame.push(0x01u8);
frame.extend_from_slice(&1u32.to_be_bytes());
frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&2u64.to_be_bytes()); frame.extend_from_slice(&2u32.to_be_bytes()); frame.extend_from_slice(&5u64.to_be_bytes()); frame.extend_from_slice(&1u64.to_be_bytes()); frame.extend_from_slice(&6u64.to_be_bytes()); frame.extend_from_slice(&1u64.to_be_bytes()); assert_eq!(
DotSet::from_bytes(&frame),
Err(HaveSetDecodeError::NonMaximalRun {
station: 1,
start: 6,
})
);
}
#[test]
fn test_have_set_from_bytes_rejects_run_too_long() {
let mut frame = Vec::new();
frame.push(0x01u8);
frame.extend_from_slice(&1u32.to_be_bytes());
frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&0u64.to_be_bytes()); frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&2u64.to_be_bytes()); frame.extend_from_slice(&1_000_000u64.to_be_bytes()); assert_eq!(
DotSet::from_bytes(&frame),
Err(HaveSetDecodeError::RunTooLong {
station: 1,
start: 2,
len: 1_000_000,
})
);
}
#[test]
fn test_have_set_from_bytes_accepts_dense_run_under_explicit_budget() {
let mut set = DotSet::new();
for counter in 2..=100 {
assert!(set.insert(dot(1, counter)));
}
let frame = set.to_bytes();
assert!(frame.len() < set.exceptions_len());
assert!(matches!(
DotSet::from_bytes(&frame),
Err(HaveSetDecodeError::RunTooLong { .. })
));
assert!(matches!(
DotSet::from_bytes_with_budget(&frame, HaveSetDecodeBudget::new(98)),
Err(HaveSetDecodeError::RunTooLong { .. })
));
assert_eq!(
DotSet::from_bytes_with_budget(&frame, HaveSetDecodeBudget::new(99)),
Ok(set)
);
}
#[test]
fn test_zero_budget_accepts_only_floor_covered_dots() {
let mut floor_only = DotSet::new();
assert!(floor_only.insert(dot(1, 1)));
assert!(floor_only.insert(dot(1, 2)));
let zero = HaveSetDecodeBudget::new(0);
assert_eq!(
DotSet::from_bytes_with_budget(&floor_only.to_bytes(), zero),
Ok(floor_only)
);
let mut one_exception = DotSet::new();
assert!(one_exception.insert(dot(1, 2)));
assert!(matches!(
DotSet::from_bytes_with_budget(&one_exception.to_bytes(), zero),
Err(HaveSetDecodeError::RunTooLong { .. })
));
}
#[test]
fn test_decode_budget_is_shared_across_stations() {
let mut set = DotSet::new();
for station in [1, 2] {
assert!(set.insert(dot(station, 2)));
assert!(set.insert(dot(station, 3)));
}
let frame = set.to_bytes();
assert!(matches!(
DotSet::from_bytes_with_budget(&frame, HaveSetDecodeBudget::new(3)),
Err(HaveSetDecodeError::RunTooLong {
station: 2,
start: 2,
len: 2,
})
));
assert_eq!(
DotSet::from_bytes_with_budget(&frame, HaveSetDecodeBudget::new(4)),
Ok(set)
);
}
#[test]
fn test_have_set_from_bytes_rejects_run_overflow() {
let mut frame = Vec::new();
frame.push(0x01u8);
frame.extend_from_slice(&1u32.to_be_bytes());
frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&2u64.to_be_bytes()); frame.extend_from_slice(&1u32.to_be_bytes()); frame.extend_from_slice(&u64::MAX.to_be_bytes()); frame.extend_from_slice(&2u64.to_be_bytes()); assert_eq!(
DotSet::from_bytes(&frame),
Err(HaveSetDecodeError::RunOverflow {
station: 1,
start: u64::MAX,
len: 2,
})
);
}