82 lines
2.4 KiB
Rust
82 lines
2.4 KiB
Rust
|
|
//! Quick-toggle routing coverage for client input aggregation.
|
||
|
|
//!
|
||
|
|
//! Scope: include the input aggregator source and exercise swap-key edge
|
||
|
|
//! detection without creating real input devices.
|
||
|
|
//! Targets: `client/src/input/inputs.rs`.
|
||
|
|
//! Why: the swap key must not flap routing when held or bounced.
|
||
|
|
|
||
|
|
mod layout {
|
||
|
|
pub use lesavka_client::layout::*;
|
||
|
|
}
|
||
|
|
|
||
|
|
mod keyboard {
|
||
|
|
pub use lesavka_client::input::keyboard::*;
|
||
|
|
}
|
||
|
|
|
||
|
|
mod mouse {
|
||
|
|
pub use lesavka_client::input::mouse::*;
|
||
|
|
}
|
||
|
|
|
||
|
|
#[allow(warnings)]
|
||
|
|
mod inputs_toggle_contract {
|
||
|
|
include!(env!("LESAVKA_CLIENT_INPUTS_SRC"));
|
||
|
|
|
||
|
|
fn new_aggregator() -> InputAggregator {
|
||
|
|
let (kbd_tx, _) = tokio::sync::broadcast::channel(32);
|
||
|
|
let (mou_tx, _) = tokio::sync::broadcast::channel(32);
|
||
|
|
InputAggregator::new(false, kbd_tx, mou_tx, None)
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn observe_quick_toggle_uses_rising_edge_to_avoid_repeat_toggling() {
|
||
|
|
let mut agg = new_aggregator();
|
||
|
|
agg.quick_toggle_debounce = Duration::from_millis(0);
|
||
|
|
|
||
|
|
agg.observe_quick_toggle(true);
|
||
|
|
assert!(
|
||
|
|
agg.pending_release,
|
||
|
|
"first quick-toggle should switch from remote to local pending-release mode"
|
||
|
|
);
|
||
|
|
assert!(!agg.released);
|
||
|
|
|
||
|
|
agg.observe_quick_toggle(true);
|
||
|
|
assert!(
|
||
|
|
agg.pending_release,
|
||
|
|
"holding the quick-toggle key should not retrigger mode switching"
|
||
|
|
);
|
||
|
|
|
||
|
|
agg.released = true;
|
||
|
|
agg.pending_release = false;
|
||
|
|
agg.observe_quick_toggle(false);
|
||
|
|
agg.observe_quick_toggle(true);
|
||
|
|
assert!(
|
||
|
|
!agg.released,
|
||
|
|
"second rising edge should return to remote mode"
|
||
|
|
);
|
||
|
|
assert!(
|
||
|
|
!agg.pending_release,
|
||
|
|
"remote-mode transition should clear pending release state"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn observe_quick_toggle_honors_debounce_window() {
|
||
|
|
let mut agg = new_aggregator();
|
||
|
|
agg.quick_toggle_debounce = Duration::from_secs(60);
|
||
|
|
|
||
|
|
agg.released = true;
|
||
|
|
agg.pending_release = false;
|
||
|
|
agg.observe_quick_toggle(true);
|
||
|
|
assert!(!agg.released, "first edge should switch to remote");
|
||
|
|
|
||
|
|
agg.released = true;
|
||
|
|
agg.pending_release = false;
|
||
|
|
agg.observe_quick_toggle(false);
|
||
|
|
agg.observe_quick_toggle(true);
|
||
|
|
assert!(
|
||
|
|
agg.released,
|
||
|
|
"second edge inside debounce window should be ignored"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|