use std::time::Duration;
use rustix::event::{PollFd, PollFlags, poll};
use crate::InputError;
use crate::event::KeyEvent;
use crate::repeat::RepeatConfig;
use crate::repeater::KeyRepeater;
const KEY_A: u32 = 30;
fn quick() -> RepeatConfig {
RepeatConfig {
delay: Duration::from_millis(5),
interval: Duration::from_millis(5),
}
}
fn press(key: u32) -> KeyEvent {
KeyEvent {
key,
pressed: true,
..KeyEvent::default()
}
}
fn release(key: u32) -> KeyEvent {
KeyEvent {
key,
pressed: false,
..KeyEvent::default()
}
}
fn fired(repeater: &KeyRepeater, timeout: Duration) -> bool {
let fd = repeater.fd();
let mut fds = [PollFd::new(&fd, PollFlags::IN)];
let ready = poll(&mut fds, Some(&timeout.try_into().expect("timeout"))).expect("poll");
ready > 0
}
#[test]
fn an_interval_of_zero_is_refused() {
let result = KeyRepeater::new(RepeatConfig {
delay: Duration::from_millis(100),
interval: Duration::ZERO,
});
assert!(matches!(result, Err(InputError::Config(_))), "{result:?}");
}
#[test]
fn an_idle_repeater_never_fires() {
let repeater = KeyRepeater::new(quick()).expect("timer");
assert!(!fired(&repeater, Duration::from_millis(50)));
}
#[test]
fn a_held_key_reaches_the_consumer() {
let mut repeater = KeyRepeater::new(quick()).expect("timer");
repeater.on_key(&press(KEY_A), true);
assert!(fired(&repeater, Duration::from_secs(5)), "the timer fired");
let mut out = Vec::new();
repeater.dispatch(7, &mut out).expect("dispatch");
assert!(!out.is_empty());
assert!(out.iter().all(|event| event.key == KEY_A && event.repeat));
}
#[test]
fn a_delay_of_zero_still_repeats() {
let mut repeater = KeyRepeater::new(RepeatConfig {
delay: Duration::ZERO,
interval: Duration::from_millis(5),
})
.expect("timer");
repeater.on_key(&press(KEY_A), true);
assert!(fired(&repeater, Duration::from_secs(5)));
let mut out = Vec::new();
repeater.dispatch(0, &mut out).expect("dispatch");
assert!(!out.is_empty());
}
#[test]
fn a_released_key_stops_the_timer() {
let mut repeater = KeyRepeater::new(quick()).expect("timer");
repeater.on_key(&press(KEY_A), true);
repeater.on_key(&release(KEY_A), true);
assert!(!fired(&repeater, Duration::from_millis(50)));
assert_eq!(repeater.held_key(), None);
}
#[test]
fn cancelling_stops_the_timer() {
let mut repeater = KeyRepeater::new(quick()).expect("timer");
repeater.on_key(&press(KEY_A), true);
repeater.cancel();
assert!(!fired(&repeater, Duration::from_millis(50)));
}
#[test]
fn dispatching_an_unfired_timer_is_quiet() {
let mut repeater = KeyRepeater::new(quick()).expect("timer");
repeater.on_key(&press(KEY_A), true);
let mut out = Vec::new();
repeater.dispatch(0, &mut out).expect("dispatch");
assert!(out.is_empty());
}
#[test]
fn a_cancel_after_the_timer_fired_emits_nothing() {
let mut repeater = KeyRepeater::new(quick()).expect("timer");
repeater.on_key(&press(KEY_A), true);
assert!(fired(&repeater, Duration::from_secs(5)));
repeater.cancel();
let mut out = Vec::new();
repeater.dispatch(0, &mut out).expect("dispatch");
assert!(out.is_empty());
}