#![cfg(feature = "animations")]
use embedded_charts::prelude::*;
#[test]
fn test_chart_animator_basic() -> ChartResult<()> {
let animator = ChartAnimator::new(0.0f32, 100.0f32, EasingFunction::Linear);
assert_eq!(animator.value_at(0), Some(0.0));
assert_eq!(animator.value_at(50), Some(50.0));
assert_eq!(animator.value_at(100), Some(100.0));
let ease_in_animator = ChartAnimator::new(0.0f32, 100.0f32, EasingFunction::EaseIn);
let value_at_50 = ease_in_animator.value_at(50).unwrap();
assert!(value_at_50 < 50.0);
Ok(())
}
#[test]
fn test_chart_animator_point2d() -> ChartResult<()> {
let from_point = Point2D::new(0.0, 0.0);
let to_point = Point2D::new(100.0, 200.0);
let animator = ChartAnimator::new(from_point, to_point, EasingFunction::Linear);
let mid_point = animator.value_at(50).unwrap();
assert_eq!(mid_point.x(), 50.0);
assert_eq!(mid_point.y(), 100.0);
Ok(())
}
#[test]
fn test_multi_state_animator() -> ChartResult<()> {
let mut animator: MultiStateAnimator<f32, 4> = MultiStateAnimator::new();
animator.add_keyframe(0, 0.0, EasingFunction::Linear)?;
animator.add_keyframe(25, 50.0, EasingFunction::EaseIn)?;
animator.add_keyframe(75, 25.0, EasingFunction::EaseOut)?;
animator.add_keyframe(100, 100.0, EasingFunction::Linear)?;
assert_eq!(animator.value_at(0), Some(0.0));
assert_eq!(animator.value_at(100), Some(100.0));
let value_at_50 = animator.value_at(50).unwrap();
assert!(value_at_50 > 25.0 && value_at_50 < 50.0);
Ok(())
}
#[test]
fn test_streaming_animator() -> ChartResult<()> {
let mut animator = StreamingAnimator::new();
assert!(animator.is_empty());
assert_eq!(animator.len(), 0);
animator.push_data(Point2D::new(1.0, 10.0));
animator.push_data(Point2D::new(2.0, 20.0));
animator.push_data(Point2D::new(3.0, 30.0));
assert_eq!(animator.len(), 3);
assert!(!animator.is_empty());
let data: heapless::Vec<Point2D, 100> = animator.current_data().collect();
assert_eq!(data.len(), 3);
assert_eq!(data[0], Point2D::new(1.0, 10.0));
assert_eq!(data[2], Point2D::new(3.0, 30.0));
animator.set_interpolation_progress(75);
assert_eq!(animator.interpolation_progress(), 75);
Ok(())
}
#[test]
fn test_time_based_progress() -> ChartResult<()> {
let mut progress_calc = TimeBasedProgress::new(1000); let mut time_provider = ManualTimeProvider::new();
assert_eq!(progress_calc.progress_from_time(&time_provider), 0);
time_provider.advance_ms(250);
assert_eq!(progress_calc.progress_from_time(&time_provider), 25);
time_provider.advance_ms(250);
assert_eq!(progress_calc.progress_from_time(&time_provider), 50);
time_provider.advance_ms(500);
assert_eq!(progress_calc.progress_from_time(&time_provider), 100);
time_provider.advance_ms(500);
assert_eq!(progress_calc.progress_from_time(&time_provider), 100);
Ok(())
}
#[test]
fn test_time_based_progress_looping() -> ChartResult<()> {
let mut progress_calc = TimeBasedProgress::new_looping(1000); let mut time_provider = ManualTimeProvider::new();
assert_eq!(progress_calc.progress_from_time(&time_provider), 0);
time_provider.advance_ms(1000);
assert_eq!(progress_calc.progress_from_time(&time_provider), 0);
time_provider.advance_ms(500);
assert_eq!(progress_calc.progress_from_time(&time_provider), 50);
time_provider.advance_ms(500);
assert_eq!(progress_calc.progress_from_time(&time_provider), 0);
Ok(())
}
#[test]
fn test_progress_from_elapsed() -> ChartResult<()> {
let progress_calc = TimeBasedProgress::new(2000);
assert_eq!(progress_calc.progress_from_elapsed(0), 0);
assert_eq!(progress_calc.progress_from_elapsed(500), 25);
assert_eq!(progress_calc.progress_from_elapsed(1000), 50);
assert_eq!(progress_calc.progress_from_elapsed(2000), 100);
assert_eq!(progress_calc.progress_from_elapsed(3000), 100);
Ok(())
}
#[test]
fn test_easing_functions() -> ChartResult<()> {
assert_eq!(EasingFunction::Linear.apply(0.0), 0.0);
assert_eq!(EasingFunction::Linear.apply(0.5), 0.5);
assert_eq!(EasingFunction::Linear.apply(1.0), 1.0);
let ease_in_half = EasingFunction::EaseIn.apply(0.5);
assert!(ease_in_half < 0.5);
let ease_out_half = EasingFunction::EaseOut.apply(0.5);
assert!(ease_out_half > 0.5);
let ease_in_out_half = EasingFunction::EaseInOut.apply(0.5);
assert!((ease_in_out_half - 0.5).abs() < 0.01);
Ok(())
}
#[test]
fn test_data_series_interpolation() -> ChartResult<()> {
let mut from_series = StaticDataSeries::new();
from_series.push(Point2D::new(0.0, 0.0))?;
from_series.push(Point2D::new(1.0, 10.0))?;
from_series.push(Point2D::new(2.0, 20.0))?;
let mut to_series = StaticDataSeries::new();
to_series.push(Point2D::new(0.0, 100.0))?;
to_series.push(Point2D::new(1.0, 110.0))?;
to_series.push(Point2D::new(2.0, 120.0))?;
let interpolated = from_series.clone().interpolate(to_series, 0.5).unwrap();
assert_eq!(interpolated.len(), 3);
assert_eq!(interpolated.get(0).unwrap(), Point2D::new(0.0, 50.0));
assert_eq!(interpolated.get(1).unwrap(), Point2D::new(1.0, 60.0));
assert_eq!(interpolated.get(2).unwrap(), Point2D::new(2.0, 70.0));
Ok(())
}
#[test]
#[cfg(feature = "line")]
fn test_animated_chart_integration() -> ChartResult<()> {
let chart = AnimatedLineChart::<Rgb565>::new();
let mut from_data = StaticDataSeries::new();
from_data.push(Point2D::new(0.0, 0.0))?;
from_data.push(Point2D::new(1.0, 10.0))?;
let mut to_data = StaticDataSeries::new();
to_data.push(Point2D::new(0.0, 100.0))?;
to_data.push(Point2D::new(1.0, 110.0))?;
let animator = chart.create_transition_animator(
from_data.clone(),
to_data.clone(),
EasingFunction::Linear,
);
let mid_data = animator.value_at(50).unwrap();
assert_eq!(mid_data.len(), 2);
assert_eq!(mid_data.get(0).unwrap(), Point2D::new(0.0, 50.0));
assert_eq!(mid_data.get(1).unwrap(), Point2D::new(1.0, 60.0));
Ok(())
}
#[test]
fn test_streaming_memory_management() -> ChartResult<()> {
let mut animator = StreamingAnimator::new();
for i in 0..150 {
animator.push_data(Point2D::new(i as f32, (i * 2) as f32));
}
assert_eq!(animator.len(), animator.capacity());
let data: heapless::Vec<Point2D, 100> = animator.current_data().collect();
let last_point = data.last().unwrap();
assert_eq!(last_point.x(), 149.0);
assert_eq!(last_point.y(), 298.0);
Ok(())
}
#[test]
fn test_animation_error_handling() -> ChartResult<()> {
let mut animator: MultiStateAnimator<f32, 2> = MultiStateAnimator::new();
animator.add_keyframe(0, 0.0, EasingFunction::Linear)?;
animator.add_keyframe(100, 100.0, EasingFunction::Linear)?;
let result = animator.add_keyframe(50, 50.0, EasingFunction::Linear);
assert!(result.is_err());
Ok(())
}
#[test]
fn test_complex_animation_scenario() -> ChartResult<()> {
let position_animator = ChartAnimator::new(
Point2D::new(0.0, 0.0),
Point2D::new(100.0, 100.0),
EasingFunction::EaseInOut,
);
let scale_animator = ChartAnimator::new(1.0f32, 2.0f32, EasingFunction::EaseOut);
let mut color_animator: MultiStateAnimator<i32, 4> = MultiStateAnimator::new();
color_animator.add_keyframe(0, 0, EasingFunction::Linear)?;
color_animator.add_keyframe(33, 128, EasingFunction::EaseIn)?;
color_animator.add_keyframe(66, 255, EasingFunction::EaseOut)?;
color_animator.add_keyframe(100, 128, EasingFunction::Linear)?;
let progress = 75;
let position = position_animator.value_at(progress).unwrap();
let scale = scale_animator.value_at(progress).unwrap();
let color = color_animator.value_at(progress).unwrap();
assert!(position.x() > 0.0 && position.x() < 100.0);
assert!(position.y() > 0.0 && position.y() < 100.0);
assert!(scale > 1.0 && scale < 2.0);
assert!(color > 128 && color <= 255);
Ok(())
}