use embedded_charts::{
data::point::Point2D,
error::DataError,
memory::{
ChartMemoryManager, FixedCapacityCollections, LabelStorage, ManagedSlidingWindow,
MemoryStats,
},
};
use embedded_graphics::pixelcolor::{Rgb565, RgbColor};
use heapless::Vec;
#[test]
fn test_fixed_capacity_collections() {
let mut data_vec: Vec<Point2D, 10> = FixedCapacityCollections::data_vec();
assert_eq!(data_vec.capacity(), 10);
assert_eq!(data_vec.len(), 0);
data_vec.push(Point2D::new(1.0, 2.0)).unwrap();
assert_eq!(data_vec.len(), 1);
let mut string_vec: Vec<heapless::String<32>, 5> = FixedCapacityCollections::string_vec();
assert_eq!(string_vec.capacity(), 5);
assert_eq!(string_vec.len(), 0);
let mut test_string = heapless::String::new();
test_string.push_str("test").unwrap();
string_vec.push(test_string).unwrap();
assert_eq!(string_vec.len(), 1);
let mut color_vec: Vec<Rgb565, 8> = FixedCapacityCollections::color_vec();
assert_eq!(color_vec.capacity(), 8);
assert_eq!(color_vec.len(), 0);
color_vec.push(Rgb565::RED).unwrap();
assert_eq!(color_vec.len(), 1);
}
#[test]
fn test_memory_stats_edge_cases() {
let stats = MemoryStats::new(0);
assert_eq!(stats.total_allocated, 0);
assert_eq!(stats.utilization_percent(), 0.0);
assert!(!stats.is_above_threshold(50.0));
let mut stats = MemoryStats::new(1000);
assert_eq!(stats.peak_usage, 0);
stats.update_usage(500);
assert_eq!(stats.used, 500);
assert_eq!(stats.available, 500);
assert_eq!(stats.peak_usage, 500);
stats.update_usage(300);
assert_eq!(stats.used, 300);
assert_eq!(stats.available, 700);
assert_eq!(stats.peak_usage, 500);
stats.update_usage(800);
assert_eq!(stats.used, 800);
assert_eq!(stats.available, 200);
assert_eq!(stats.peak_usage, 800);
stats.update_usage(1200);
assert_eq!(stats.used, 1200);
assert_eq!(stats.available, 0); assert_eq!(stats.peak_usage, 1200);
}
#[test]
fn test_memory_stats_threshold_checks() {
let mut stats = MemoryStats::new(1000);
stats.update_usage(0);
assert!(!stats.is_above_threshold(0.0));
stats.update_usage(250);
assert!(!stats.is_above_threshold(25.0));
assert!(stats.is_above_threshold(24.9));
stats.update_usage(750);
assert!(!stats.is_above_threshold(75.0));
assert!(stats.is_above_threshold(74.9));
stats.update_usage(1000);
assert!(!stats.is_above_threshold(100.0));
assert!(stats.is_above_threshold(99.9));
}
#[test]
fn test_chart_memory_manager_comprehensive() {
let mut manager: ChartMemoryManager<2000> = ChartMemoryManager::new();
assert_eq!(manager.stats().total_allocated, 2000);
assert_eq!(manager.stats().used, 0);
assert_eq!(manager.high_water_mark(), 0);
manager.update_usage(500);
assert_eq!(manager.stats().used, 500);
assert_eq!(manager.high_water_mark(), 500);
manager.update_usage(300);
assert_eq!(manager.stats().used, 300);
assert_eq!(manager.high_water_mark(), 500);
manager.update_usage(1500);
assert_eq!(manager.stats().used, 1500);
assert_eq!(manager.high_water_mark(), 1500);
assert!(!manager.is_memory_critical(80.0));
assert!(manager.is_memory_critical(70.0));
manager.reset_stats();
assert_eq!(manager.stats().used, 0);
assert_eq!(manager.high_water_mark(), 0);
assert_eq!(manager.stats().total_allocated, 2000);
}
#[test]
fn test_chart_memory_manager_default() {
let manager: ChartMemoryManager<1024> = ChartMemoryManager::default();
assert_eq!(manager.stats().total_allocated, 1024);
assert_eq!(manager.stats().used, 0);
assert_eq!(manager.high_water_mark(), 0);
}
#[test]
fn test_managed_sliding_window_comprehensive() {
let mut window: ManagedSlidingWindow<u32, 5> = ManagedSlidingWindow::new();
assert_eq!(window.len(), 0);
assert!(window.is_empty());
assert!(!window.is_full());
window.push(10);
assert_eq!(window.len(), 1);
assert!(!window.is_empty());
assert!(!window.is_full());
window.push(20);
window.push(30);
window.push(40);
assert_eq!(window.len(), 4);
assert!(!window.is_full());
window.push(50);
assert_eq!(window.len(), 5);
assert!(window.is_full());
let stats_before = window.memory_stats().used;
window.push(60);
assert_eq!(window.len(), 5);
assert!(window.is_full());
assert_eq!(window.memory_stats().used, stats_before);
let items: Vec<u32, 5> = window.iter().collect();
assert_eq!(items.as_slice(), &[20, 30, 40, 50, 60]);
window.clear();
assert_eq!(window.len(), 0);
assert!(window.is_empty());
assert!(!window.is_full());
assert_eq!(window.memory_stats().used, 0);
}
#[test]
fn test_managed_sliding_window_iterator_edge_cases() {
let mut window: ManagedSlidingWindow<i32, 4> = ManagedSlidingWindow::new();
let empty_items: Vec<i32, 4> = window.iter().collect();
assert_eq!(empty_items.len(), 0);
window.push(1);
window.push(2);
let partial_items: Vec<i32, 4> = window.iter().collect();
assert_eq!(partial_items.as_slice(), &[1, 2]);
window.push(3);
window.push(4);
window.push(5); window.push(6); let wrapped_items: Vec<i32, 4> = window.iter().collect();
assert_eq!(wrapped_items.as_slice(), &[3, 4, 5, 6]);
}
#[test]
fn test_managed_sliding_window_memory_tracking() {
let mut window: ManagedSlidingWindow<u64, 10> = ManagedSlidingWindow::new();
let item_size = core::mem::size_of::<u64>();
let total_capacity = 10 * item_size;
assert_eq!(window.memory_stats().total_allocated, total_capacity);
assert_eq!(window.memory_stats().used, 0);
for i in 0..5 {
window.push(i);
assert_eq!(window.memory_stats().used, (i + 1) as usize * item_size);
}
for i in 5..10 {
window.push(i);
}
assert_eq!(window.memory_stats().used, 10 * item_size);
window.push(100);
assert_eq!(window.memory_stats().used, 10 * item_size);
}
#[test]
fn test_managed_sliding_window_default() {
let window: ManagedSlidingWindow<f32, 8> = ManagedSlidingWindow::default();
assert_eq!(window.len(), 0);
assert!(window.is_empty());
assert!(!window.is_full());
}
#[test]
fn test_label_storage_comprehensive() {
let mut storage: LabelStorage<10, 50> = LabelStorage::new();
assert_eq!(storage.len(), 0);
assert!(storage.is_empty());
let idx1 = storage.add_label("First Label").unwrap();
let idx2 = storage.add_label("Second Label").unwrap();
let idx3 = storage.add_label("Third Label").unwrap();
assert_eq!(storage.len(), 3);
assert!(!storage.is_empty());
assert_eq!(storage.get_label(idx1), Some("First Label"));
assert_eq!(storage.get_label(idx2), Some("Second Label"));
assert_eq!(storage.get_label(idx3), Some("Third Label"));
assert_eq!(storage.get_label(100), None);
let total_chars = "First Label".len() + "Second Label".len() + "Third Label".len();
assert_eq!(storage.memory_stats().used, total_chars);
storage.clear();
assert_eq!(storage.len(), 0);
assert!(storage.is_empty());
assert_eq!(storage.memory_stats().used, 0);
}
#[test]
fn test_label_storage_error_cases() {
let mut storage: LabelStorage<5, 10> = LabelStorage::new();
let long_label = "This is a very long label that exceeds the maximum length";
let result = storage.add_label(long_label);
assert!(matches!(result, Err(DataError::INVALID_DATA_POINT)));
for i in 0..5 {
storage.add_label(&format!("L{i}")).unwrap();
}
let result = storage.add_label("Overflow");
assert!(matches!(result, Err(DataError::BUFFER_FULL)));
}
#[test]
fn test_label_storage_memory_tracking() {
let mut storage: LabelStorage<5, 30> = LabelStorage::new();
assert_eq!(storage.memory_stats().total_allocated, 5 * 30);
assert_eq!(storage.memory_stats().used, 0);
storage.add_label("Short").unwrap();
assert_eq!(storage.memory_stats().used, 5);
storage.add_label("Medium Label").unwrap();
assert_eq!(storage.memory_stats().used, 5 + 12);
storage.add_label("Longer Label Here").unwrap();
assert_eq!(storage.memory_stats().used, 5 + 12 + 17);
storage.clear();
assert_eq!(storage.memory_stats().used, 0);
}
#[test]
fn test_label_storage_default() {
let storage: LabelStorage<20, 100> = LabelStorage::default();
assert_eq!(storage.len(), 0);
assert!(storage.is_empty());
assert_eq!(storage.memory_stats().total_allocated, 20 * 100);
}
#[test]
fn test_memory_stats_utilization_calculations() {
let mut stats = MemoryStats::new(1000);
stats.update_usage(0);
assert_eq!(stats.utilization_percent(), 0.0);
stats.update_usage(250);
assert!((stats.utilization_percent() - 25.0).abs() < 0.001);
stats.update_usage(500);
assert!((stats.utilization_percent() - 50.0).abs() < 0.001);
stats.update_usage(750);
assert!((stats.utilization_percent() - 75.0).abs() < 0.001);
stats.update_usage(1000);
assert!((stats.utilization_percent() - 100.0).abs() < 0.001);
stats.update_usage(1500);
assert!((stats.utilization_percent() - 150.0).abs() < 0.001);
}
#[test]
fn test_integration_scenario() {
let mut manager: ChartMemoryManager<10000> = ChartMemoryManager::new();
let mut data_window: ManagedSlidingWindow<f32, 100> = ManagedSlidingWindow::new();
let mut labels: LabelStorage<10, 20> = LabelStorage::new();
for i in 0..50 {
data_window.push(i as f32 * 1.5);
if i % 10 == 0 {
labels.add_label(&format!("Checkpoint {}", i / 10)).unwrap();
}
}
let total_usage = data_window.memory_stats().used + labels.memory_stats().used;
manager.update_usage(total_usage);
assert!(manager.high_water_mark() > 0);
assert!(!manager.is_memory_critical(90.0));
for i in 50..150 {
data_window.push(i as f32 * 1.5);
}
let new_total_usage = data_window.memory_stats().used + labels.memory_stats().used;
manager.update_usage(new_total_usage);
assert_eq!(manager.high_water_mark(), new_total_usage);
let latest_values: Vec<f32, 100> = data_window.iter().collect();
assert_eq!(latest_values.len(), 100);
assert!((latest_values[0] - 75.0).abs() < 0.001); assert!((latest_values[99] - 223.5).abs() < 0.001); }