x11-overlay 0.1.0

A library for creating overlay interfaces on X11 systems using Cairo for rendering
Documentation
#[cfg(test)]
pub mod color_property_tests {
    use crate::graphics::{Color, ColorProperty, DynamicColor};
    use std::time::Duration;

    // Mock struct to test ColorProperty trait
    #[derive(Debug)]
    struct MockColorComponent {
        color: DynamicColor,
    }

    impl MockColorComponent {
        fn new(color: Color) -> Self {
            Self {
                color: DynamicColor::new(color),
            }
        }
    }

    impl ColorProperty for MockColorComponent {
        fn color_mut(&mut self) -> &mut DynamicColor {
            &mut self.color
        }

        fn color(&self) -> &DynamicColor {
            &self.color
        }
    }

    #[test]
    fn test_color_property_set_color() {
        let mut component = MockColorComponent::new(Color::rgb(1.0, 0.0, 0.0));
        let new_color = Color::rgb(0.0, 1.0, 0.0);

        component.set_color(new_color);

        assert_eq!(component.color().current(), new_color);
        assert_eq!(component.color().target(), new_color);
        assert!(!component.color().is_animating());
    }

    #[test]
    fn test_color_property_animate_color_to() {
        let mut component = MockColorComponent::new(Color::rgb(1.0, 0.0, 0.0));
        let target_color = Color::rgb(0.0, 1.0, 0.0);

        component.animate_color_to(target_color, Duration::from_millis(100));

        assert!(component.color().is_animating());
        assert_eq!(component.color().target(), target_color);
    }

    #[test]
    fn test_color_property_update_color() {
        let mut component = MockColorComponent::new(Color::rgb(1.0, 0.0, 0.0));

        // No animation running - should return false
        let needs_redraw = component.update_color(0.016);
        assert!(!needs_redraw);

        // Start animation - should return true while animating
        component.animate_color_to(Color::rgb(0.0, 1.0, 0.0), Duration::from_millis(10));
        let needs_redraw = component.update_color(0.016);
        assert!(needs_redraw);

        // Wait for completion and update until animation finishes
        std::thread::sleep(Duration::from_millis(15));
        let mut needs_redraw = true;
        while needs_redraw {
            needs_redraw = component.update_color(0.016);
        }
        // Final check - should be false when animation completes
        assert!(!component.update_color(0.016));
    }

    #[test]
    fn test_color_property_trait_methods_consistency() {
        let mut component = MockColorComponent::new(Color::rgb(0.5, 0.5, 0.5));

        // Test that trait methods and direct access are consistent
        let color_via_trait = component.color().current();
        let color_direct = component.color.current();
        assert_eq!(color_via_trait, color_direct);

        // Test mutation
        component
            .color_mut()
            .set_immediate(Color::rgb(1.0, 0.0, 0.0));
        assert_eq!(component.color().current(), Color::rgb(1.0, 0.0, 0.0));
    }

    #[test]
    fn test_multiple_components_independence() {
        let mut comp1 = MockColorComponent::new(Color::rgb(1.0, 0.0, 0.0));
        let mut comp2 = MockColorComponent::new(Color::rgb(0.0, 1.0, 0.0));

        // Animate each to different targets
        comp1.animate_color_to(Color::rgb(0.0, 0.0, 1.0), Duration::from_millis(100));
        comp2.animate_color_to(Color::rgb(1.0, 1.0, 0.0), Duration::from_millis(200));

        // Both should be animating independently
        assert!(comp1.color().is_animating());
        assert!(comp2.color().is_animating());
        assert_ne!(comp1.color().target(), comp2.color().target());

        // Update both
        comp1.update_color(0.016);
        comp2.update_color(0.016);

        // Should still be independent
        assert_ne!(comp1.color().current(), comp2.color().current());
    }
}