#[cfg(test)]
mod tui_ui_tests {
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers};
#[test]
fn test_key_event_creation() {
let key_event = KeyEvent {
code: KeyCode::Char('q'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(key_event.code, KeyCode::Char('q'));
assert_eq!(key_event.modifiers, KeyModifiers::NONE);
assert_eq!(key_event.kind, KeyEventKind::Press);
}
#[test]
fn test_special_key_events() {
let enter_key = KeyEvent {
code: KeyCode::Enter,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let escape_key = KeyEvent {
code: KeyCode::Esc,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let tab_key = KeyEvent {
code: KeyCode::Tab,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(enter_key.code, KeyCode::Enter);
assert_eq!(escape_key.code, KeyCode::Esc);
assert_eq!(tab_key.code, KeyCode::Tab);
}
#[test]
fn test_arrow_key_events() {
let up_key = KeyEvent {
code: KeyCode::Up,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let down_key = KeyEvent {
code: KeyCode::Down,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let left_key = KeyEvent {
code: KeyCode::Left,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let right_key = KeyEvent {
code: KeyCode::Right,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(up_key.code, KeyCode::Up);
assert_eq!(down_key.code, KeyCode::Down);
assert_eq!(left_key.code, KeyCode::Left);
assert_eq!(right_key.code, KeyCode::Right);
}
#[test]
fn test_modifier_key_events() {
let ctrl_c = KeyEvent {
code: KeyCode::Char('c'),
modifiers: KeyModifiers::CONTROL,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let shift_tab = KeyEvent {
code: KeyCode::BackTab,
modifiers: KeyModifiers::SHIFT,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let alt_enter = KeyEvent {
code: KeyCode::Enter,
modifiers: KeyModifiers::ALT,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(ctrl_c.modifiers, KeyModifiers::CONTROL);
assert_eq!(shift_tab.modifiers, KeyModifiers::SHIFT);
assert_eq!(alt_enter.modifiers, KeyModifiers::ALT);
}
#[test]
fn test_function_key_events() {
let f1_key = KeyEvent {
code: KeyCode::F(1),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let f12_key = KeyEvent {
code: KeyCode::F(12),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(f1_key.code, KeyCode::F(1));
assert_eq!(f12_key.code, KeyCode::F(12));
}
#[test]
fn test_key_event_kind() {
let press_event = KeyEvent {
code: KeyCode::Char('a'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let release_event = KeyEvent {
code: KeyCode::Char('a'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Release,
state: KeyEventState::NONE,
};
let repeat_event = KeyEvent {
code: KeyCode::Char('a'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Repeat,
state: KeyEventState::NONE,
};
assert_eq!(press_event.kind, KeyEventKind::Press);
assert_eq!(release_event.kind, KeyEventKind::Release);
assert_eq!(repeat_event.kind, KeyEventKind::Repeat);
}
#[test]
fn test_alphanumeric_key_events() {
let letter_a = KeyEvent {
code: KeyCode::Char('a'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let letter_z = KeyEvent {
code: KeyCode::Char('z'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let digit_0 = KeyEvent {
code: KeyCode::Char('0'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let digit_9 = KeyEvent {
code: KeyCode::Char('9'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(letter_a.code, KeyCode::Char('a'));
assert_eq!(letter_z.code, KeyCode::Char('z'));
assert_eq!(digit_0.code, KeyCode::Char('0'));
assert_eq!(digit_9.code, KeyCode::Char('9'));
}
#[test]
fn test_special_character_key_events() {
let space = KeyEvent {
code: KeyCode::Char(' '),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let exclamation = KeyEvent {
code: KeyCode::Char('!'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let at_symbol = KeyEvent {
code: KeyCode::Char('@'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(space.code, KeyCode::Char(' '));
assert_eq!(exclamation.code, KeyCode::Char('!'));
assert_eq!(at_symbol.code, KeyCode::Char('@'));
}
#[test]
fn test_backspace_and_delete() {
let backspace = KeyEvent {
code: KeyCode::Backspace,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let delete = KeyEvent {
code: KeyCode::Delete,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(backspace.code, KeyCode::Backspace);
assert_eq!(delete.code, KeyCode::Delete);
}
#[test]
fn test_page_navigation_keys() {
let page_up = KeyEvent {
code: KeyCode::PageUp,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let page_down = KeyEvent {
code: KeyCode::PageDown,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let home = KeyEvent {
code: KeyCode::Home,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let end = KeyEvent {
code: KeyCode::End,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(page_up.code, KeyCode::PageUp);
assert_eq!(page_down.code, KeyCode::PageDown);
assert_eq!(home.code, KeyCode::Home);
assert_eq!(end.code, KeyCode::End);
}
#[test]
fn test_insert_key() {
let insert = KeyEvent {
code: KeyCode::Insert,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
assert_eq!(insert.code, KeyCode::Insert);
}
#[test]
fn test_event_matching_patterns() {
let quit_key = KeyEvent {
code: KeyCode::Char('q'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let ctrl_c = KeyEvent {
code: KeyCode::Char('c'),
modifiers: KeyModifiers::CONTROL,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let should_quit = match quit_key.code {
KeyCode::Char('q') if quit_key.modifiers.is_empty() => true,
_ => false,
};
let is_interrupt = match ctrl_c {
KeyEvent {
code: KeyCode::Char('c'),
modifiers: KeyModifiers::CONTROL,
..
} => true,
_ => false,
};
assert!(should_quit);
assert!(is_interrupt);
}
#[test]
fn test_navigation_key_handling() {
let keys = vec![
KeyCode::Up,
KeyCode::Down,
KeyCode::Left,
KeyCode::Right,
KeyCode::Tab,
KeyCode::BackTab,
];
for key in keys {
let event = KeyEvent {
code: key,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
};
let is_navigation = matches!(
event.code,
KeyCode::Up
| KeyCode::Down
| KeyCode::Left
| KeyCode::Right
| KeyCode::Tab
| KeyCode::BackTab
);
assert!(is_navigation);
}
}
#[test]
fn test_text_input_filtering() {
let events = vec![
KeyEvent {
code: KeyCode::Char('a'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
},
KeyEvent {
code: KeyCode::Char('Z'),
modifiers: KeyModifiers::SHIFT,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
},
KeyEvent {
code: KeyCode::Char('5'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
},
KeyEvent {
code: KeyCode::Char(' '),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
},
KeyEvent {
code: KeyCode::Enter,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
},
];
let text_chars: Vec<char> = events
.iter()
.filter_map(|event| match event.code {
KeyCode::Char(c) => Some(c),
_ => None,
})
.collect();
assert_eq!(text_chars, vec!['a', 'Z', '5', ' ']);
}
}