#![allow(clippy::unwrap_used)] #![allow(clippy::explicit_iter_loop)] use super::*;
#[test]
fn test_new_defaults() {
let adaptive = AdaptiveChunking::new();
assert_eq!(adaptive.current_size(), 256);
assert_eq!(adaptive.min_size, 16);
assert_eq!(adaptive.max_size, 1024);
assert_eq!(adaptive.adjustment_window, 50);
assert!(adaptive.last_adjustment_time.is_none());
assert!(adaptive.measurements.is_empty());
}
#[test]
fn test_no_adjustment_in_hysteresis_band() {
let mut adaptive = AdaptiveChunking::new();
for _ in 0..50 {
assert_eq!(adaptive.observe(128, 256), None);
}
assert_eq!(adaptive.current_size(), 256);
}
#[test]
fn test_decrease_on_high_occupancy() {
let mut adaptive = AdaptiveChunking::new();
let original_size = 256;
for _ in 0..49 {
assert_eq!(adaptive.observe(230, 256), None);
}
let result = adaptive.observe(230, 256);
assert!(result.is_some());
let new_size = result.unwrap();
assert!(
new_size < original_size,
"Should decrease on high occupancy"
);
assert!(new_size >= 16, "Should respect min bound");
}
#[test]
fn test_increase_on_low_occupancy() {
let mut adaptive = AdaptiveChunking::new();
let original_size = 256;
for _ in 0..49 {
assert_eq!(adaptive.observe(26, 256), None);
}
let result = adaptive.observe(26, 256);
assert!(result.is_some());
let new_size = result.unwrap();
assert!(new_size > original_size, "Should increase on low occupancy");
assert!(new_size <= 1024, "Should respect max bound");
}
#[test]
fn test_respects_min_bound() {
let mut adaptive = AdaptiveChunking::new();
for iteration in 0..20 {
for _ in 0..50 {
adaptive.observe(250, 256);
}
adaptive.observe(250, 256);
assert!(
adaptive.current_size() >= 16,
"Iteration {}: size {} < min",
iteration,
adaptive.current_size()
);
}
}
#[test]
fn test_respects_max_bound() {
let mut adaptive = AdaptiveChunking::new();
for iteration in 0..20 {
for _ in 0..50 {
adaptive.observe(10, 256);
}
adaptive.observe(10, 256);
assert!(
adaptive.current_size() <= 1024,
"Iteration {}: size {} > max",
iteration,
adaptive.current_size()
);
}
}
#[test]
fn test_respects_min_adjustment_interval() {
let mut adaptive = AdaptiveChunking::new();
for _ in 0..49 {
let result = adaptive.observe(230, 256);
assert_eq!(result, None, "Should not adjust yet, window not full");
}
let first_adjustment = adaptive.observe(230, 256);
assert!(
first_adjustment.is_some(),
"Should adjust on 50th observation when window is full"
);
let first_size = adaptive.current_size();
assert!(
first_size < 256,
"High occupancy should decrease chunk size"
);
for _ in 0..50 {
let result = adaptive.observe(230, 256);
assert_eq!(
result, None,
"Should not adjust again so soon (within min interval)"
);
}
assert_eq!(
adaptive.current_size(),
first_size,
"Size should remain unchanged due to rate limiting"
);
}
#[test]
fn test_window_resets_after_adjustment() {
let mut adaptive = AdaptiveChunking::new();
for _ in 0..49 {
let result = adaptive.observe(230, 256);
assert_eq!(result, None, "Should not adjust yet, window not full");
}
let first = adaptive.observe(230, 256);
assert!(
first.is_some(),
"Should adjust when window reaches 50 observations"
);
assert!(
adaptive.measurements.is_empty(),
"Measurements should be cleared after adjustment"
);
}
#[test]
fn test_zero_capacity_handling() {
let mut adaptive = AdaptiveChunking::new();
for _ in 0..49 {
let result = adaptive.observe(0, 0);
assert_eq!(result, None, "Should not adjust until window is full");
}
let result = adaptive.observe(0, 0);
assert!(
result.is_some(),
"Should increase chunk size when occupancy < 20% and window is full"
);
assert!(
adaptive.current_size() > 256,
"Should increase from 256 due to low occupancy"
);
}
#[test]
fn test_average_occupancy_calculation() {
let mut adaptive = AdaptiveChunking::new();
for pct in [10, 20, 30, 40, 50].iter() {
let items = (pct * 256) / 100;
adaptive.observe(items, 256);
}
let avg = adaptive.average_occupancy();
assert_eq!(
avg, 29,
"Average should account for integer division in percentages"
);
}