Recreate repository due to Git object corruption (all files preserved)
This commit is contained in:
73
tests/bindings.rs
Normal file
73
tests/bindings.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use tui_orchestrator::input::{Bindings, Key};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[allow(dead_code)]
|
||||
enum TestAction {
|
||||
Quit,
|
||||
Save,
|
||||
Open,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_new() {
|
||||
let _bindings: Bindings<TestAction> = Bindings::new();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_bind() {
|
||||
let mut bindings: Bindings<TestAction> = Bindings::new();
|
||||
bindings.bind(Key::char('q'), TestAction::Quit);
|
||||
assert_eq!(bindings.get(&Key::char('q')), Some(&TestAction::Quit));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_get_not_found() {
|
||||
let mut bindings: Bindings<TestAction> = Bindings::new();
|
||||
bindings.bind(Key::char('q'), TestAction::Quit);
|
||||
assert_eq!(bindings.get(&Key::char('x')), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_remove() {
|
||||
let mut bindings: Bindings<TestAction> = Bindings::new();
|
||||
bindings.bind(Key::char('q'), TestAction::Quit);
|
||||
bindings.remove(&Key::char('q'));
|
||||
assert_eq!(bindings.get(&Key::char('q')), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_is_empty() {
|
||||
let mut bindings: Bindings<TestAction> = Bindings::new();
|
||||
assert!(bindings.is_empty());
|
||||
|
||||
bindings.bind(Key::char('q'), TestAction::Quit);
|
||||
assert!(!bindings.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_len() {
|
||||
let mut bindings: Bindings<TestAction> = Bindings::new();
|
||||
assert_eq!(bindings.len(), 0);
|
||||
|
||||
bindings.bind(Key::char('q'), TestAction::Quit);
|
||||
assert_eq!(bindings.len(), 1);
|
||||
|
||||
bindings.bind(Key::char('s'), TestAction::Save);
|
||||
assert_eq!(bindings.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_iter() {
|
||||
let mut bindings: Bindings<TestAction> = Bindings::new();
|
||||
bindings.bind(Key::char('q'), TestAction::Quit);
|
||||
bindings.bind(Key::char('s'), TestAction::Save);
|
||||
|
||||
let actions: Vec<_> = bindings.iter().map(|(_, a)| *a).collect();
|
||||
assert!(actions.contains(&TestAction::Quit));
|
||||
assert!(actions.contains(&TestAction::Save));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bindings_default() {
|
||||
let _bindings: Bindings<TestAction> = Bindings::default();
|
||||
}
|
||||
122
tests/component_tests.rs
Normal file
122
tests/component_tests.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
extern crate alloc;
|
||||
|
||||
use tui_orchestrator::component::{Component, ComponentAction};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
enum TestFocus {
|
||||
FieldA,
|
||||
FieldB,
|
||||
ButtonC,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum TestEvent {
|
||||
ButtonCPressed,
|
||||
TextTyped(char),
|
||||
}
|
||||
|
||||
struct TestComponent {
|
||||
field_a: alloc::string::String,
|
||||
field_b: alloc::string::String,
|
||||
}
|
||||
|
||||
impl Component for TestComponent {
|
||||
type Focus = TestFocus;
|
||||
type Action = ComponentAction;
|
||||
type Event = TestEvent;
|
||||
|
||||
fn targets(&self) -> &[Self::Focus] {
|
||||
&[
|
||||
Self::Focus::FieldA,
|
||||
Self::Focus::FieldB,
|
||||
Self::Focus::ButtonC,
|
||||
]
|
||||
}
|
||||
|
||||
fn handle(
|
||||
&mut self,
|
||||
focus: &Self::Focus,
|
||||
action: Self::Action,
|
||||
) -> Result<Option<Self::Event>, tui_orchestrator::component::error::ComponentError> {
|
||||
match (focus, action) {
|
||||
(Self::Focus::ButtonC, ComponentAction::Select) => {
|
||||
Ok(Some(Self::Event::ButtonCPressed))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn on_enter(&mut self) -> Result<(), tui_orchestrator::component::error::ComponentError> {
|
||||
self.field_a.clear();
|
||||
self.field_b.clear();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_targets() {
|
||||
let mut component = TestComponent {
|
||||
field_a: alloc::string::String::new(),
|
||||
field_b: alloc::string::String::new(),
|
||||
};
|
||||
|
||||
let targets = component.targets();
|
||||
assert_eq!(targets.len(), 3);
|
||||
assert_eq!(targets[0], TestFocus::FieldA);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_handle_select() {
|
||||
let mut component = TestComponent {
|
||||
field_a: alloc::string::String::new(),
|
||||
field_b: alloc::string::String::new(),
|
||||
};
|
||||
|
||||
let focus = TestFocus::ButtonC;
|
||||
let action = ComponentAction::Select;
|
||||
|
||||
let event = component.handle(&focus, action);
|
||||
assert!(event.is_ok());
|
||||
assert!(matches!(event.unwrap(), Some(TestEvent::ButtonCPressed)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_handle_text() {
|
||||
let mut component = TestComponent {
|
||||
field_a: alloc::string::String::new(),
|
||||
field_b: alloc::string::String::new(),
|
||||
};
|
||||
|
||||
let focus = TestFocus::FieldA;
|
||||
let ch = 'x';
|
||||
|
||||
let event = component.handle_text(&focus, ch);
|
||||
assert!(event.is_ok());
|
||||
assert!(matches!(event.unwrap(), Some(TestEvent::TextTyped('x'))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_on_enter_clears() {
|
||||
let mut component = TestComponent {
|
||||
field_a: alloc::string::String::from("test"),
|
||||
field_b: alloc::string::String::from("test"),
|
||||
};
|
||||
|
||||
component.on_enter().unwrap();
|
||||
assert_eq!(component.field_a.as_str(), "");
|
||||
assert_eq!(component.field_b.as_str(), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_defaults() {
|
||||
let component = TestComponent {
|
||||
field_a: alloc::string::String::new(),
|
||||
field_b: alloc::string::String::new(),
|
||||
};
|
||||
|
||||
assert!(component.on_exit().is_ok());
|
||||
assert!(component.on_focus(&TestFocus::FieldA).is_ok());
|
||||
assert!(component.on_blur(&TestFocus::FieldA).is_ok());
|
||||
assert!(component.can_navigate_forward(&TestFocus::FieldA));
|
||||
assert!(component.can_navigate_backward(&TestFocus::FieldA));
|
||||
}
|
||||
283
tests/focus.rs
Normal file
283
tests/focus.rs
Normal file
@@ -0,0 +1,283 @@
|
||||
extern crate alloc;
|
||||
|
||||
use tui_orchestrator::focus::{FocusError, FocusManager, Focusable};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[allow(dead_code)]
|
||||
enum TestId {
|
||||
Field(usize),
|
||||
Button(&'static str),
|
||||
Menu,
|
||||
Dialog,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_focus_id_trait() {
|
||||
let id1 = TestId::Button("save");
|
||||
let id2 = TestId::Button("save");
|
||||
assert_eq!(id1, id2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_new() {
|
||||
let manager: FocusManager<TestId> = FocusManager::new();
|
||||
assert!(manager.is_empty());
|
||||
assert_eq!(manager.current(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_set_targets() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
assert_eq!(manager.len(), 3);
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_navigation() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(0)));
|
||||
|
||||
manager.next();
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(1)));
|
||||
|
||||
manager.next();
|
||||
assert_eq!(manager.current(), Some(&TestId::Button("save")));
|
||||
|
||||
manager.next();
|
||||
assert_eq!(manager.current(), Some(&TestId::Button("save")));
|
||||
|
||||
manager.prev();
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(1)));
|
||||
|
||||
manager.first();
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(0)));
|
||||
|
||||
manager.last();
|
||||
assert_eq!(manager.current(), Some(&TestId::Button("save")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_prev_at_start() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
manager.prev();
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_set_focus() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
let result = manager.set_focus(TestId::Button("save"));
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(manager.current(), Some(&TestId::Button("save")));
|
||||
|
||||
let result = manager.set_focus(TestId::Field(0));
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_set_focus_not_found() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
let result = manager.set_focus(TestId::Menu);
|
||||
assert_eq!(result, Err(FocusError::TargetNotFound));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_set_focus_empty() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
let result = manager.set_focus(TestId::Menu);
|
||||
assert_eq!(result, Err(FocusError::EmptyTargets));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_overlay() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
manager.set_overlay(TestId::Menu);
|
||||
assert!(manager.has_overlay());
|
||||
assert_eq!(manager.current(), Some(&TestId::Menu));
|
||||
|
||||
manager.next();
|
||||
assert_eq!(manager.current(), Some(&TestId::Menu));
|
||||
|
||||
manager.clear_overlay();
|
||||
assert!(!manager.has_overlay());
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_overlay_with_focus() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
manager.set_focus(TestId::Button("save")).unwrap();
|
||||
assert_eq!(manager.current(), Some(&TestId::Button("save")));
|
||||
|
||||
manager.set_overlay(TestId::Menu);
|
||||
assert_eq!(manager.current(), Some(&TestId::Menu));
|
||||
|
||||
manager.clear_overlay();
|
||||
assert_eq!(manager.current(), Some(&TestId::Button("save")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_add_remove_target() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.add_target(TestId::Field(0));
|
||||
manager.add_target(TestId::Field(1));
|
||||
|
||||
assert_eq!(manager.len(), 2);
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(0)));
|
||||
|
||||
manager.remove_target(&TestId::Field(0));
|
||||
assert_eq!(manager.len(), 1);
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(1)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_remove_current_adjusts_index() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![TestId::Field(0), TestId::Field(1), TestId::Field(2)]);
|
||||
|
||||
manager.next();
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(1)));
|
||||
|
||||
manager.remove_target(&TestId::Field(1));
|
||||
assert_eq!(manager.len(), 2);
|
||||
assert_eq!(manager.current(), Some(&TestId::Field(2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_query() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
let query = manager.query();
|
||||
assert_eq!(query.current, Some(&TestId::Field(0)));
|
||||
assert!(query.is_focused(&TestId::Field(0)));
|
||||
assert!(!query.is_focused(&TestId::Field(1)));
|
||||
assert!(query.has_focus());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_query_no_focus() {
|
||||
let manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
let query = manager.query();
|
||||
assert_eq!(query.current, None);
|
||||
assert!(!query.has_focus());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manager_is_focused() {
|
||||
let mut manager: FocusManager<TestId> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![
|
||||
TestId::Field(0),
|
||||
TestId::Field(1),
|
||||
TestId::Button("save"),
|
||||
]);
|
||||
|
||||
assert!(manager.is_focused(&TestId::Field(0)));
|
||||
assert!(!manager.is_focused(&TestId::Field(1)));
|
||||
|
||||
manager.next();
|
||||
assert!(!manager.is_focused(&TestId::Field(0)));
|
||||
assert!(manager.is_focused(&TestId::Field(1)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_focusable_trait() {
|
||||
struct TestComponent;
|
||||
|
||||
impl Focusable<TestId> for TestComponent {
|
||||
fn focus_targets(&self) -> alloc::vec::Vec<TestId> {
|
||||
vec![TestId::Field(0), TestId::Field(1), TestId::Button("save")]
|
||||
}
|
||||
}
|
||||
|
||||
let component = TestComponent;
|
||||
let targets = component.focus_targets();
|
||||
assert_eq!(targets.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_usize_focus_id() {
|
||||
let mut manager: FocusManager<usize> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec![0, 1, 2, 3]);
|
||||
assert_eq!(manager.current(), Some(&0));
|
||||
|
||||
manager.next();
|
||||
assert_eq!(manager.current(), Some(&1));
|
||||
|
||||
manager.set_focus(3).unwrap();
|
||||
assert_eq!(manager.current(), Some(&3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string_focus_id() {
|
||||
let mut manager: FocusManager<&str> = FocusManager::new();
|
||||
|
||||
manager.set_targets(vec!["input1", "input2", "button_save"]);
|
||||
assert_eq!(manager.current(), Some(&"input1"));
|
||||
|
||||
manager.next();
|
||||
assert_eq!(manager.current(), Some(&"input2"));
|
||||
|
||||
manager.set_focus("button_save").unwrap();
|
||||
assert_eq!(manager.current(), Some(&"button_save"));
|
||||
}
|
||||
96
tests/key.rs
Normal file
96
tests/key.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
use tui_orchestrator::input::{Key, KeyCode, KeyModifiers};
|
||||
|
||||
#[test]
|
||||
fn test_key_char() {
|
||||
let key = Key::char('a');
|
||||
assert_eq!(key.code, KeyCode::Char('a'));
|
||||
assert!(key.modifiers.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_ctrl() {
|
||||
let key = Key::ctrl('s');
|
||||
assert_eq!(key.code, KeyCode::Char('s'));
|
||||
assert!(key.modifiers.control);
|
||||
assert!(!key.modifiers.alt);
|
||||
assert!(!key.modifiers.shift);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_new() {
|
||||
let key = Key::new(KeyCode::Enter, KeyModifiers::new().with_alt());
|
||||
assert_eq!(key.code, KeyCode::Enter);
|
||||
assert!(key.modifiers.alt);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_from_keycode() {
|
||||
let key = Key::from(KeyCode::Esc);
|
||||
assert_eq!(key.code, KeyCode::Esc);
|
||||
assert!(key.modifiers.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_display_char() {
|
||||
let key = Key::char('x');
|
||||
let display = key.display_string();
|
||||
assert!(display.contains('x'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_display_ctrl() {
|
||||
let key = Key::ctrl('c');
|
||||
let display = key.display_string();
|
||||
assert!(display.contains("Ctrl+"));
|
||||
assert!(display.contains('c'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_display_all_modifiers() {
|
||||
let key = Key::new(
|
||||
KeyCode::Char('a'),
|
||||
KeyModifiers::new().with_control().with_alt().with_shift(),
|
||||
);
|
||||
let display = key.display_string();
|
||||
assert!(display.contains("Ctrl+"));
|
||||
assert!(display.contains("Alt+"));
|
||||
assert!(display.contains("Shift+"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_display_special() {
|
||||
let key = Key::new(KeyCode::F(5), KeyModifiers::new());
|
||||
let display = key.display_string();
|
||||
assert!(display.contains("F5"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_modifiers_new() {
|
||||
let mods = KeyModifiers::new();
|
||||
assert!(!mods.control);
|
||||
assert!(!mods.alt);
|
||||
assert!(!mods.shift);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_modifiers_builders() {
|
||||
let mods = KeyModifiers::new().with_control().with_shift();
|
||||
assert!(mods.control);
|
||||
assert!(!mods.alt);
|
||||
assert!(mods.shift);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_modifiers_is_empty() {
|
||||
assert!(KeyModifiers::new().is_empty());
|
||||
assert!(!KeyModifiers::new().with_control().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_equality() {
|
||||
let k1 = Key::char('a');
|
||||
let k2 = Key::char('a');
|
||||
let k3 = Key::ctrl('a');
|
||||
assert_eq!(k1, k2);
|
||||
assert_ne!(k1, k3);
|
||||
}
|
||||
Reference in New Issue
Block a user