//! Tests for selection types: SelectionTransform, TransformHandle, CropState. use hcie_iced_gui::selection::clipboard::centered_transform; use hcie_iced_gui::selection::state::{combine_masks, mask_bounds, selected_spans}; use hcie_iced_gui::selection::{CropState, SelectionMode, SelectionTransform, TransformHandle}; #[test] fn test_selection_transform_is_empty() { let tr = SelectionTransform { pixels: vec![], width: 0, height: 0, pos: iced::Vector::ZERO, size: iced::Vector::ZERO, rotation: 0.0, }; assert!(tr.is_empty()); } #[test] fn test_selection_transform_with_data() { let tr = SelectionTransform { pixels: vec![255; 100], width: 5, height: 5, pos: iced::Vector::new(10.0, 20.0), size: iced::Vector::new(5.0, 5.0), rotation: 0.0, }; assert!(!tr.is_empty()); } #[test] fn test_crop_state_lifecycle() { let mut crop = CropState::default(); assert!(!crop.active); assert!(crop.rect.is_none()); crop.start_drag(10.0, 10.0); assert!(crop.active); assert!(crop.is_dragging); crop.update_drag(100.0, 100.0); assert!(crop.rect.is_some()); let (x, y, w, h) = crop.rect.unwrap(); assert_eq!(x, 10.0); assert_eq!(y, 10.0); assert_eq!(w, 90.0); assert_eq!(h, 90.0); crop.end_drag(); assert!(!crop.is_dragging); let result = crop.confirm(); assert!(result.is_some()); assert!(!crop.active); } #[test] fn test_crop_cancel() { let mut crop = CropState::default(); crop.start_drag(10.0, 10.0); crop.update_drag(100.0, 100.0); crop.cancel(); assert!(!crop.active); assert!(crop.rect.is_none()); } #[test] fn test_transform_handle_cursor_hints() { assert_eq!(TransformHandle::Move.cursor_hint(), "move"); assert_eq!(TransformHandle::TopLeft.cursor_hint(), "nwse-resize"); assert_eq!(TransformHandle::Rotate.cursor_hint(), "crosshair"); } #[test] fn selection_modes_combine_alpha_without_losing_soft_edges() { let old = [0, 64, 255, 255]; let new = [255, 128, 64, 0]; assert_eq!(combine_masks(Some(&old), &new, SelectionMode::Replace), new); assert_eq!( combine_masks(Some(&old), &new, SelectionMode::Add), [255, 128, 255, 255] ); assert_eq!( combine_masks(Some(&old), &new, SelectionMode::Subtract), [0, 0, 191, 255] ); assert_eq!( combine_masks(Some(&old), &new, SelectionMode::Intersect), [0, 64, 64, 0] ); } #[test] fn irregular_mask_bounds_and_fill_spans_are_exact() { let mask = [0, 255, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0]; assert_eq!(mask_bounds(&mask, 4, 3), Some((0, 0, 2, 3))); assert_eq!( selected_spans(&mask, 4, 3), vec![(1, 0, 2), (0, 1, 2), (1, 2, 2)] ); } #[test] fn crop_clamps_drag_and_cancel_restores_idle_state() { let mut crop = CropState::default(); crop.start_drag_clamped(-20.0, 5.0, 100, 80); crop.update_drag(140.0, 120.0); assert_eq!(crop.rect, Some((0.0, 5.0, 100.0, 75.0))); crop.cancel(); assert_eq!(crop.canvas_size, None); assert!(!crop.active); } #[test] fn clipboard_transform_is_centered_and_transform_geometry_is_safe() { let mut transform = centered_transform(vec![255; 8 * 4 * 4], 8, 4, 100, 50).unwrap(); assert_eq!(transform.pos, iced::Vector::new(46.0, 23.0)); transform.size = iced::Vector::new(-20.0, f32::NAN); transform.sanitize_geometry(true); assert!(transform.size.x > 0.0 && transform.size.y > 0.0); assert!((transform.size.x / transform.size.y - 2.0).abs() < 0.001); }