Synvael/crates/client/src/tests/debug.rs

203 lines
6 KiB
Rust

// SPDX-License-Identifier: AGPL-3.0-only
//! Unit tests for the debug chord handling in [`crate::debug`].
use super::*;
/// Presses and releases a key, returning the action produced on the press edge.
fn tap(controls: &mut DebugControls, code: KeyCode) -> Option<DebugAction> {
let action = controls.handle_key(code, true);
controls.handle_key(code, false);
action
}
#[test]
fn chord_key_alone_does_nothing() {
let mut controls = DebugControls::default();
assert_eq!(tap(&mut controls, KeyCode::KeyV), None);
}
#[test]
fn modifier_alone_produces_no_action() {
let mut controls = DebugControls::default();
assert_eq!(controls.handle_key(DEBUG_MODIFIER, true), None);
assert_eq!(controls.handle_key(DEBUG_MODIFIER, false), None);
}
#[test]
fn held_modifier_plus_bound_key_selects_the_mode() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
assert_eq!(
tap(&mut controls, KeyCode::KeyV),
Some(DebugAction::SetRenderMode(RenderMode::FilledPoints))
);
}
#[test]
fn each_bound_key_selects_a_distinct_overlay_mode() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
for (code, expected) in [
(KeyCode::KeyV, RenderMode::FilledPoints),
(KeyCode::KeyB, RenderMode::FilledWireframe),
] {
assert_eq!(
tap(&mut controls, code),
Some(DebugAction::SetRenderMode(expected))
);
}
}
#[test]
fn solo_modifier_drops_the_filled_pass() {
for solo in SOLO_MODIFIER {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
controls.handle_key(solo, true);
assert_eq!(
tap(&mut controls, KeyCode::KeyV),
Some(DebugAction::SetRenderMode(RenderMode::Points))
);
assert_eq!(
tap(&mut controls, KeyCode::KeyB),
Some(DebugAction::SetRenderMode(RenderMode::Wireframe))
);
}
}
#[test]
fn solo_modifier_is_tracked_before_the_debug_modifier() {
let mut controls = DebugControls::default();
controls.handle_key(KeyCode::ShiftLeft, true);
controls.handle_key(DEBUG_MODIFIER, true);
assert_eq!(
tap(&mut controls, KeyCode::KeyV),
Some(DebugAction::SetRenderMode(RenderMode::Points))
);
}
#[test]
fn releasing_the_solo_modifier_restores_the_overlay_form() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
controls.handle_key(KeyCode::ShiftLeft, true);
tap(&mut controls, KeyCode::KeyV);
controls.handle_key(KeyCode::ShiftLeft, false);
assert_eq!(
tap(&mut controls, KeyCode::KeyV),
Some(DebugAction::SetRenderMode(RenderMode::FilledPoints))
);
}
#[test]
fn switching_between_modes_does_not_pass_through_filled() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
tap(&mut controls, KeyCode::KeyV);
assert_eq!(
tap(&mut controls, KeyCode::KeyB),
Some(DebugAction::SetRenderMode(RenderMode::FilledWireframe))
);
}
#[test]
fn repeating_the_chord_toggles_back_to_filled() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
tap(&mut controls, KeyCode::KeyV);
assert_eq!(
tap(&mut controls, KeyCode::KeyV),
Some(DebugAction::SetRenderMode(RenderMode::Filled))
);
}
#[test]
fn action_fires_on_the_press_edge_only() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
assert!(controls.handle_key(KeyCode::KeyV, true).is_some());
assert_eq!(controls.handle_key(KeyCode::KeyV, false), None);
}
#[test]
fn releasing_the_modifier_disarms_the_chord() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
controls.handle_key(DEBUG_MODIFIER, false);
assert_eq!(tap(&mut controls, KeyCode::KeyV), None);
}
#[test]
fn unbound_key_under_the_modifier_is_ignored() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
assert_eq!(tap(&mut controls, KeyCode::KeyW), None);
}
#[test]
fn solo_modifier_alone_produces_no_action() {
let mut controls = DebugControls::default();
assert_eq!(controls.handle_key(KeyCode::ShiftLeft, true), None);
assert_eq!(tap(&mut controls, KeyCode::KeyV), None);
}
#[test]
fn the_stats_chord_toggles_the_overlay_on_and_off() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
assert_eq!(
tap(&mut controls, STATS_KEY),
Some(DebugAction::SetStatsOverlay(true))
);
assert_eq!(
tap(&mut controls, STATS_KEY),
Some(DebugAction::SetStatsOverlay(false))
);
}
#[test]
fn the_stats_chord_leaves_the_render_mode_untouched() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
tap(&mut controls, KeyCode::KeyV);
tap(&mut controls, STATS_KEY);
// The raster axis must survive a toggle on the statistics axis; a single-enum design would have reset it.
assert_eq!(controls.render_mode, RenderMode::FilledPoints);
}
#[test]
fn a_raster_chord_leaves_the_stats_overlay_untouched() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
tap(&mut controls, STATS_KEY);
assert_eq!(
tap(&mut controls, KeyCode::KeyB),
Some(DebugAction::SetRenderMode(RenderMode::FilledWireframe))
);
assert!(controls.stats_enabled);
}
#[test]
fn the_solo_modifier_does_not_change_the_stats_chord() {
let mut controls = DebugControls::default();
controls.handle_key(DEBUG_MODIFIER, true);
controls.handle_key(KeyCode::ShiftLeft, true);
assert_eq!(
tap(&mut controls, STATS_KEY),
Some(DebugAction::SetStatsOverlay(true))
);
}
#[test]
fn the_stats_chord_requires_the_debug_modifier() {
let mut controls = DebugControls::default();
assert_eq!(tap(&mut controls, STATS_KEY), None);
assert!(!controls.stats_enabled);
}