use super::*;
use crate::geometry::Point;
const FONT_BYTES: &[u8] = include_bytes!("../../../../demo/assets/CascadiaCode.ttf");
fn test_font() -> Arc<Font> {
Arc::new(Font::from_slice(FONT_BYTES).expect("font"))
}
fn mouse_down(x: f64, y: f64) -> Event {
Event::MouseDown {
pos: Point::new(x, y),
button: MouseButton::Left,
modifiers: Default::default(),
}
}
fn mouse_move(x: f64, y: f64) -> Event {
Event::MouseMove {
pos: Point::new(x, y),
}
}
#[test]
fn infinite_range_drag_stays_finite() {
let cell = Rc::new(Cell::new(10000.0));
let mut s = Slider::new(10000.0, -f64::INFINITY, f64::INFINITY, test_font())
.with_logarithmic(true)
.with_value_cell(Rc::clone(&cell));
let _ = s.layout(Size::new(300.0, WIDGET_H));
s.set_bounds(Rect::new(0.0, 0.0, 300.0, WIDGET_H));
assert!(s.value().is_finite(), "initial value {}", s.value());
assert!(!s.format_value().contains("NaN"), "label {}", s.format_value());
s.on_event(&mouse_down(150.0, WIDGET_H * 0.5));
assert!(
s.value().is_finite(),
"value after drag = {} (cell {})",
s.value(),
cell.get()
);
assert!(cell.get().is_finite(), "cell poisoned to {}", cell.get());
}
#[test]
fn demo_slider_initial_is_finite() {
let mut s = Slider::new(10.0, 0.0, 10000.0, test_font())
.with_logarithmic(true)
.with_step(0.0);
let _ = s.layout(Size::new(300.0, WIDGET_H));
assert!(s.normalized().is_finite(), "normalized {}", s.normalized());
assert!(s.thumb_pos().is_finite(), "thumb {}", s.thumb_pos());
assert!(!s.format_value().contains("NaN"));
}
#[test]
fn vertical_drag_is_monotonic_and_finite() {
let mut s = Slider::new(10.0, 0.0, 10000.0, test_font())
.with_logarithmic(true)
.with_step(0.0)
.with_orientation(SliderOrientation::Vertical);
let _ = s.layout(Size::new(120.0, VERT_LEN));
s.set_bounds(Rect::new(0.0, 0.0, 120.0, VERT_LEN));
assert!(s.thumb_pos().is_finite(), "thumb {}", s.thumb_pos());
s.on_event(&mouse_down(THUMB_R, VERT_LEN - THUMB_R - 1.0));
let low = s.value();
assert!(low.is_finite(), "low {low}");
s.on_event(&mouse_move(THUMB_R, VERT_LEN * 0.5));
let mid = s.value();
assert!(mid.is_finite(), "mid {mid}");
s.on_event(&mouse_move(THUMB_R, THUMB_R + 1.0));
let high = s.value();
assert!(high.is_finite(), "high {high}");
assert!(low <= mid && mid <= high, "not monotonic: {low} {mid} {high}");
}
#[test]
fn nan_in_value_cell_is_ignored() {
let cell = Rc::new(Cell::new(10.0));
let mut s = Slider::new(10.0, 0.0, 10000.0, test_font())
.with_logarithmic(true)
.with_value_cell(Rc::clone(&cell));
let _ = s.layout(Size::new(300.0, WIDGET_H));
assert_eq!(s.value(), 10.0);
cell.set(f64::NAN);
let _ = s.layout(Size::new(300.0, WIDGET_H));
assert_eq!(s.value(), 10.0, "NaN frame should be ignored, kept previous");
}
#[test]
fn set_value_rejects_nan() {
let mut s = Slider::new(10.0, 0.0, 10000.0, test_font());
s.set_value(f64::NAN);
assert_eq!(s.value(), 10.0, "value {}", s.value());
}
#[test]
fn new_with_reversed_range_does_not_panic() {
let s = Slider::new(5.0, 10.0, 0.0, test_font());
assert_eq!(s.value(), 5.0);
let s = Slider::new(-1.0, 10.0, 0.0, test_font());
assert_eq!(s.value(), 0.0);
}
#[test]
fn value_cell_with_reversed_range_does_not_panic() {
let cell = Rc::new(Cell::new(42.0));
let mut s = Slider::new(5.0, 10.0, 0.0, test_font()).with_value_cell(Rc::clone(&cell));
assert_eq!(s.value(), 10.0);
cell.set(-3.0);
let _ = s.layout(Size::new(200.0, 22.0));
assert_eq!(s.value(), 0.0);
}