Added unittest

This commit is contained in:
Christoffer Martinsson 2025-09-16 20:19:34 +02:00
parent cd54773b70
commit a165558875
2 changed files with 146 additions and 1 deletions

View File

@ -112,7 +112,114 @@ impl<'a, const R: usize, const C: usize, const N: usize> ButtonMatrix<'a, R, C,
///
/// For small `N` this copy is cheap. If needed, the API could be extended to
/// return a reference in the future.
pub fn buttons_pressed(&mut self) -> [bool; N] {
pub fn buttons_pressed(&mut self) -> [bool; N] {
self.pressed
}
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
use core::cell::Cell;
use embedded_hal::digital::ErrorType;
use std::rc::Rc;
struct MockInputPin {
state: Rc<Cell<bool>>,
}
impl MockInputPin {
fn new(state: Rc<Cell<bool>>) -> Self {
Self { state }
}
}
impl ErrorType for MockInputPin {
type Error = Infallible;
}
impl InputPin for MockInputPin {
fn is_high(&mut self) -> Result<bool, Self::Error> {
Ok(!self.state.get())
}
fn is_low(&mut self) -> Result<bool, Self::Error> {
Ok(self.state.get())
}
}
struct MockOutputPin {
state: Rc<Cell<bool>>,
}
impl MockOutputPin {
fn new(state: Rc<Cell<bool>>) -> Self {
Self { state }
}
}
impl ErrorType for MockOutputPin {
type Error = Infallible;
}
impl OutputPin for MockOutputPin {
fn set_high(&mut self) -> Result<(), Self::Error> {
self.state.set(true);
Ok(())
}
fn set_low(&mut self) -> Result<(), Self::Error> {
self.state.set(false);
Ok(())
}
}
fn matrix_fixture() -> (
ButtonMatrix<'static, 1, 1, 1>,
Rc<Cell<bool>>,
Rc<Cell<bool>>,
) {
let row_state = Rc::new(Cell::new(false));
let col_state = Rc::new(Cell::new(false));
let row_pin: &'static mut dyn InputPin<Error = Infallible> =
Box::leak(Box::new(MockInputPin::new(row_state.clone())));
let col_pin: &'static mut dyn OutputPin<Error = Infallible> =
Box::leak(Box::new(MockOutputPin::new(col_state.clone())));
let rows: &'static mut [&'static mut dyn InputPin<Error = Infallible>; 1] =
Box::leak(Box::new([row_pin]));
let cols: &'static mut [&'static mut dyn OutputPin<Error = Infallible>; 1] =
Box::leak(Box::new([col_pin]));
let matrix = ButtonMatrix::new(rows, cols, 2);
(matrix, row_state, col_state)
}
#[test]
fn init_pins_sets_columns_high() {
let (mut matrix, _row_state, col_state) = matrix_fixture();
assert!(!col_state.get());
matrix.init_pins();
assert!(col_state.get());
}
#[test]
fn process_column_obeys_debounce() {
let (mut matrix, row_state, _col_state) = matrix_fixture();
let mut states = matrix.buttons_pressed();
assert!(!states[0]);
row_state.set(true);
matrix.process_column(0);
matrix.process_column(0);
states = matrix.buttons_pressed();
assert!(states[0]);
row_state.set(false);
matrix.process_column(0);
matrix.process_column(0);
states = matrix.buttons_pressed();
assert!(!states[0]);
}
}

View File

@ -163,3 +163,41 @@ pub fn configure_button_mappings(buttons: &mut [Button]) {
buttons[BUTTON_FRONT_LEFT_EXTRA].usb_button = USB_BUTTON_30;
buttons[BUTTON_FRONT_RIGHT_EXTRA].usb_button = USB_BUTTON_31;
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
use crate::buttons::{Button, TOTAL_BUTTONS};
#[test]
fn front_buttons_have_expected_mappings() {
let mut buttons = [Button::default(); TOTAL_BUTTONS];
configure_button_mappings(&mut buttons);
assert_eq!(buttons[BUTTON_FRONT_LEFT_LOWER].usb_button, USB_BUTTON_29);
assert_eq!(buttons[BUTTON_FRONT_RIGHT_UPPER].usb_button, USB_BUTTON_1);
assert_eq!(buttons[BUTTON_FRONT_CONFIG].usb_button_long, USB_BUTTON_3);
}
#[test]
fn long_press_flags_set_correctly() {
let mut buttons = [Button::default(); TOTAL_BUTTONS];
configure_button_mappings(&mut buttons);
assert!(buttons[BUTTON_TOP_LEFT_LOW].enable_long_press);
assert!(buttons[BUTTON_TOP_LEFT_LOW].enable_long_hold);
assert!(buttons[BUTTON_TOP_RIGHT_LOW].enable_long_press);
assert!(!buttons[BUTTON_TOP_RIGHT_LOW].enable_long_hold);
}
#[test]
fn hat_buttons_map_to_expected_ids() {
let mut buttons = [Button::default(); TOTAL_BUTTONS];
configure_button_mappings(&mut buttons);
assert_eq!(buttons[BUTTON_TOP_RIGHT_HAT_UP].usb_button, USB_HAT_UP);
assert_eq!(buttons[BUTTON_TOP_RIGHT_HAT_RIGHT].usb_button, USB_HAT_RIGHT);
assert_eq!(buttons[BUTTON_TOP_RIGHT_HAT_DOWN].usb_button, USB_HAT_DOWN);
assert_eq!(buttons[BUTTON_TOP_RIGHT_HAT_LEFT].usb_button, USB_HAT_LEFT);
}
}