use client_domain::ScrollState; use std::time::Duration; #[test] fn no_overflow_means_zero_offset() { let scroll = ScrollState::new(100, 80); assert_eq!(scroll.offset(), 0); assert!(!scroll.is_active()); } #[test] fn overflow_starts_at_zero_offset() { let scroll = ScrollState::new(100, 200); assert_eq!(scroll.offset(), 0); assert!(scroll.is_active()); } #[test] fn tick_advances_offset_after_initial_pause() { let mut scroll = ScrollState::new(100, 200); // Overflow = 100px. Initial pause = 2s. // Tick past the pause assert!(scroll.tick(Duration::from_secs(3))); assert!(scroll.offset() > 0); } #[test] fn tick_returns_false_when_no_movement() { let mut scroll = ScrollState::new(100, 80); assert!(!scroll.tick(Duration::from_millis(100))); } #[test] fn offset_never_exceeds_overflow() { let mut scroll = ScrollState::new(100, 200); // Tick many times — offset should cap at overflow (100) for _ in 0..1000 { scroll.tick(Duration::from_millis(100)); } assert!(scroll.offset() <= 100); } #[test] fn bounces_back_after_reaching_end() { let mut scroll = ScrollState::new(100, 150); // Overflow = 50px. Tick until we reach the end and bounce back. // After enough ticks, offset should return to 0. let mut seen_nonzero = false; let mut returned_to_zero = false; for _ in 0..2000 { scroll.tick(Duration::from_millis(50)); if scroll.offset() > 0 { seen_nonzero = true; } if seen_nonzero && scroll.offset() == 0 { returned_to_zero = true; break; } } assert!(seen_nonzero, "should have scrolled"); assert!(returned_to_zero, "should have bounced back to 0"); } #[test] fn reset_restarts_scroll() { let mut scroll = ScrollState::new(100, 200); for _ in 0..100 { scroll.tick(Duration::from_millis(100)); } scroll.reset(100, 200); assert_eq!(scroll.offset(), 0); }