use guiduck_scene::geom::Size; use super::*; use crate::clipboard::NoClipboard; use crate::event::{Modifiers, PointerButton}; fn text() -> TextContext { TextContext::hermetic([]) } fn laid_out(width: f64) -> Slider { let mut slider = Slider::new(); slider.finalize_layout(&mut text(), Size::new(width, 20.0), Size::ZERO); slider } fn press(slider: &mut Slider, x: f64) { slider.on_pointer( EventKind::PointerDown, &PointerEvent { window: Point::new(x, 10.0), local: Point::new(x, 10.0), button: Some(PointerButton::Left), click_count: 1, }, &mut text(), &mut NoClipboard, ); } fn arrow(slider: &mut Slider, key: Key) -> bool { slider.on_key( &KeyInput { key, modifiers: Modifiers::default(), pressed: true, }, &mut text(), &mut NoClipboard, ) } #[test] fn a_programmatic_set_is_silent() { let mut slider = Slider::new(); slider.set_value(0.5); assert_eq!(slider.get_value(), 0.5); assert!( slider.take_emitted().is_empty(), "the controlled contract: a binding writing the value must not report it" ); } #[test] fn dragging_reports_the_new_value() { let mut slider = laid_out(100.0); press(&mut slider, 50.0); assert!( (slider.get_value() - 0.5).abs() < 0.05, "{}", slider.get_value() ); assert!(matches!( slider.take_emitted().as_slice(), [EventData::ValueChanged(_)] )); } /// The thumb has width, so the travel is shorter than the track. Without /// accounting for it the value could never reach either end. #[test] fn the_ends_are_reachable() { let mut slider = laid_out(100.0); press(&mut slider, 0.0); assert_eq!(slider.get_value(), 0.0); press(&mut slider, 100.0); assert_eq!(slider.get_value(), 1.0); } #[test] fn arrows_step_and_stop_at_the_ends() { let mut slider = laid_out(100.0); slider.set_value(0.5); let _ = slider.take_emitted(); assert!(arrow(&mut slider, Key::Right), "a move consumes the key"); assert!((slider.get_value() - 0.55).abs() < 1e-9); assert!(matches!( slider.take_emitted().as_slice(), [EventData::ValueChanged(_)] )); assert!(arrow(&mut slider, Key::End)); assert_eq!(slider.get_value(), 1.0); let _ = slider.take_emitted(); // At the end there is nowhere to go, so the key is *not* consumed and can // still reach Tab or a shortcut. assert!( !arrow(&mut slider, Key::Right), "a key that moves nothing is not consumed" ); assert!(slider.take_emitted().is_empty()); } #[test] fn a_slider_announces_a_percentage() { let mut slider = Slider::new(); slider.set_value(0.25); let mut node = accesskit::Node::new(accesskit::Role::Slider); slider.accessibility(&mut node); assert_eq!(node.numeric_value(), Some(25.0)); assert_eq!(slider.role(), accesskit::Role::Slider); }