use super::*;
#[test]
fn test_dialog_button_new() {
let button = DialogButton::new("ok", "OK");
assert_eq!(button.id(), "ok");
assert_eq!(button.label(), "OK");
}
#[test]
fn test_dialog_button_clone() {
let button = DialogButton::new("save", "Save");
let cloned = button.clone();
assert_eq!(cloned.id(), "save");
assert_eq!(cloned.label(), "Save");
}
#[test]
fn test_new() {
let buttons = vec![
DialogButton::new("ok", "OK"),
DialogButton::new("cancel", "Cancel"),
];
let state = DialogState::new("Title", "Message", buttons);
assert_eq!(state.title(), "Title");
assert_eq!(state.message(), "Message");
assert_eq!(state.buttons().len(), 2);
assert_eq!(state.primary_button(), 0);
assert_eq!(state.focused_button(), 0);
assert!(!Dialog::is_visible(&state));
}
#[test]
fn test_with_primary() {
let buttons = vec![
DialogButton::new("cancel", "Cancel"),
DialogButton::new("ok", "OK"),
];
let state = DialogState::with_primary("Title", "Message", buttons, 1);
assert_eq!(state.primary_button(), 1);
assert_eq!(state.focused_button(), 1);
}
#[test]
fn test_with_primary_clamps() {
let buttons = vec![DialogButton::new("ok", "OK")];
let state = DialogState::with_primary("Title", "Message", buttons, 10);
assert_eq!(state.primary_button(), 0);
}
#[test]
fn test_alert() {
let state = DialogState::alert("Error", "Something went wrong.");
assert_eq!(state.title(), "Error");
assert_eq!(state.message(), "Something went wrong.");
assert_eq!(state.buttons().len(), 1);
assert_eq!(state.buttons()[0].id(), "ok");
assert_eq!(state.buttons()[0].label(), "OK");
}
#[test]
fn test_confirm() {
let state = DialogState::confirm("Delete?", "This cannot be undone.");
assert_eq!(state.title(), "Delete?");
assert_eq!(state.buttons().len(), 2);
assert_eq!(state.buttons()[0].id(), "cancel");
assert_eq!(state.buttons()[1].id(), "ok");
assert_eq!(state.primary_button(), 1);
}
#[test]
fn test_default() {
let state = DialogState::default();
assert_eq!(state.title(), "");
assert_eq!(state.message(), "");
assert!(state.buttons().is_empty());
assert!(!Dialog::is_visible(&state));
}
#[test]
fn test_new_empty_buttons() {
let state = DialogState::new("Title", "Message", vec![]);
assert!(state.buttons().is_empty());
assert_eq!(state.primary_button(), 0);
assert_eq!(state.focused_button(), 0);
}
#[test]
fn test_set_buttons() {
let mut state = DialogState::alert("Title", "Message");
let new_buttons = vec![
DialogButton::new("yes", "Yes"),
DialogButton::new("no", "No"),
];
state.set_buttons(new_buttons);
assert_eq!(state.buttons().len(), 2);
assert_eq!(state.buttons()[0].id(), "yes");
}
#[test]
fn test_set_buttons_resets_focus() {
let mut state = DialogState::with_primary(
"T",
"M",
vec![
DialogButton::new("a", "A"),
DialogButton::new("b", "B"),
DialogButton::new("c", "C"),
],
2,
);
assert_eq!(state.focused_button(), 2);
state.set_buttons(vec![DialogButton::new("x", "X")]);
assert_eq!(state.primary_button(), 0);
assert_eq!(state.focused_button(), 0);
}
#[test]
fn test_set_primary_clamps() {
let mut state = DialogState::alert("T", "M");
state.set_primary_button(10);
assert_eq!(state.primary_button(), 0);
}
#[test]
fn test_focus_next() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
assert_eq!(state.focused_button(), 1);
Dialog::update(&mut state, DialogMessage::FocusNext);
assert_eq!(state.focused_button(), 0); }
#[test]
fn test_focus_next_wraps() {
let buttons = vec![
DialogButton::new("a", "A"),
DialogButton::new("b", "B"),
DialogButton::new("c", "C"),
];
let mut state = DialogState::with_primary("T", "M", buttons, 2);
Dialog::show(&mut state);
assert_eq!(state.focused_button(), 2);
Dialog::update(&mut state, DialogMessage::FocusNext);
assert_eq!(state.focused_button(), 0);
}
#[test]
fn test_focus_prev() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
assert_eq!(state.focused_button(), 1);
Dialog::update(&mut state, DialogMessage::FocusPrev);
assert_eq!(state.focused_button(), 0);
}
#[test]
fn test_focus_prev_wraps() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
Dialog::update(&mut state, DialogMessage::FocusPrev); Dialog::update(&mut state, DialogMessage::FocusPrev); assert_eq!(state.focused_button(), 1);
}
#[test]
fn test_focus_empty() {
let mut state = DialogState::new("T", "M", vec![]);
Dialog::show(&mut state);
Dialog::update(&mut state, DialogMessage::FocusNext);
Dialog::update(&mut state, DialogMessage::FocusPrev);
assert_eq!(state.focused_button(), 0);
}
#[test]
fn test_press() {
let mut state = DialogState::alert("T", "M");
Dialog::show(&mut state);
let output = Dialog::update(&mut state, DialogMessage::Press);
assert_eq!(output, Some(DialogOutput::ButtonPressed("ok".into())));
}
#[test]
fn test_press_hides_dialog() {
let mut state = DialogState::alert("T", "M");
Dialog::show(&mut state);
assert!(Dialog::is_visible(&state));
Dialog::update(&mut state, DialogMessage::Press);
assert!(!Dialog::is_visible(&state));
}
#[test]
fn test_press_empty() {
let mut state = DialogState::new("T", "M", vec![]);
Dialog::show(&mut state);
let output = Dialog::update(&mut state, DialogMessage::Press);
assert_eq!(output, None);
}
#[test]
fn test_close() {
let mut state = DialogState::alert("T", "M");
Dialog::show(&mut state);
let output = Dialog::update(&mut state, DialogMessage::Close);
assert_eq!(output, Some(DialogOutput::Closed));
}
#[test]
fn test_close_hides_dialog() {
let mut state = DialogState::alert("T", "M");
Dialog::show(&mut state);
assert!(Dialog::is_visible(&state));
Dialog::update(&mut state, DialogMessage::Close);
assert!(!Dialog::is_visible(&state));
}
#[test]
fn test_open() {
let mut state = DialogState::confirm("T", "M");
assert!(!Dialog::is_visible(&state));
Dialog::update(&mut state, DialogMessage::Open);
assert!(Dialog::is_visible(&state));
assert_eq!(state.focused_button(), 1); }
#[test]
fn test_open_when_visible() {
let mut state = DialogState::alert("T", "M");
Dialog::show(&mut state);
let output = Dialog::update(&mut state, DialogMessage::Open);
assert_eq!(output, None);
assert!(Dialog::is_visible(&state));
}
#[test]
fn test_update_when_hidden() {
let mut state = DialogState::confirm("T", "M");
assert!(!Dialog::is_visible(&state));
let output = Dialog::update(&mut state, DialogMessage::FocusNext);
assert_eq!(output, None);
let output = Dialog::update(&mut state, DialogMessage::FocusPrev);
assert_eq!(output, None);
let output = Dialog::update(&mut state, DialogMessage::Press);
assert_eq!(output, None);
let output = Dialog::update(&mut state, DialogMessage::Close);
assert_eq!(output, None);
}
#[test]
fn test_view_when_hidden() {
let state = DialogState::alert("Title", "Message");
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_renders() {
let mut state = DialogState::alert("Test Title", "Test message content.");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_title() {
let mut state = DialogState::alert("My Dialog Title", "Message");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_message() {
let mut state = DialogState::alert("Title", "This is the message content.");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_buttons() {
let mut state = DialogState::confirm("Title", "Message");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_focused_button() {
let mut state = DialogState::confirm("Title", "Message");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_primary_button() {
let mut state = DialogState::confirm("Title", "Message");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_multiline_message() {
let mut state = DialogState::alert("Title", "Line 1\nLine 2\nLine 3");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_init() {
let state = Dialog::init();
assert_eq!(state.title(), "");
assert_eq!(state.message(), "");
assert!(state.buttons().is_empty());
}
#[test]
fn test_alert_workflow() {
let mut state = DialogState::alert("Error", "File not found.");
Dialog::show(&mut state);
let output = Dialog::update(&mut state, DialogMessage::Press);
assert_eq!(output, Some(DialogOutput::ButtonPressed("ok".into())));
assert!(!Dialog::is_visible(&state));
}
#[test]
fn test_confirm_workflow() {
let mut state = DialogState::confirm("Delete?", "This cannot be undone.");
Dialog::show(&mut state);
assert_eq!(state.focused_button(), 1);
Dialog::update(&mut state, DialogMessage::FocusPrev);
assert_eq!(state.focused_button(), 0);
let output = Dialog::update(&mut state, DialogMessage::Press);
assert_eq!(output, Some(DialogOutput::ButtonPressed("cancel".into())));
assert!(!Dialog::is_visible(&state));
}
#[test]
fn test_custom_workflow() {
let buttons = vec![
DialogButton::new("save", "Save"),
DialogButton::new("discard", "Discard"),
DialogButton::new("cancel", "Cancel"),
];
let mut state = DialogState::with_primary("Unsaved Changes", "Save your work?", buttons, 0);
Dialog::show(&mut state);
Dialog::update(&mut state, DialogMessage::FocusNext);
assert_eq!(state.focused_button(), 1);
let output = Dialog::update(&mut state, DialogMessage::Press);
assert_eq!(output, Some(DialogOutput::ButtonPressed("discard".into())));
}
#[test]
fn test_show_resets_focus_to_primary() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
Dialog::update(&mut state, DialogMessage::FocusPrev);
assert_eq!(state.focused_button(), 0);
Dialog::hide(&mut state);
Dialog::show(&mut state);
assert_eq!(state.focused_button(), 1);
}
use crate::input::{Event, Key, Modifiers};
#[test]
fn test_handle_event_tab() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
let msg = Dialog::handle_event(&state, &Event::key(Key::Tab), &EventContext::default());
assert_eq!(msg, Some(DialogMessage::FocusNext));
}
#[test]
fn test_handle_event_backtab() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
let msg = Dialog::handle_event(
&state,
&Event::key_with(Key::Tab, Modifiers::SHIFT),
&EventContext::default(),
);
assert_eq!(msg, Some(DialogMessage::FocusPrev));
}
#[test]
fn test_handle_event_enter() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
let msg = Dialog::handle_event(&state, &Event::key(Key::Enter), &EventContext::default());
assert_eq!(msg, Some(DialogMessage::Press));
}
#[test]
fn test_handle_event_escape() {
let mut state = DialogState::confirm("T", "M");
Dialog::show(&mut state);
let msg = Dialog::handle_event(&state, &Event::key(Key::Esc), &EventContext::default());
assert_eq!(msg, Some(DialogMessage::Close));
}
#[test]
fn test_handle_event_ignored_when_not_visible() {
let state = DialogState::confirm("T", "M");
assert!(!Dialog::is_visible(&state));
let msg = Dialog::handle_event(&state, &Event::key(Key::Enter), &EventContext::default());
assert_eq!(msg, None);
}
#[test]
fn test_dispatch_event() {
let mut state = DialogState::alert("T", "M");
Dialog::show(&mut state);
let output = Dialog::dispatch_event(
&mut state,
&Event::key(Key::Enter),
&EventContext::default(),
);
assert_eq!(output, Some(DialogOutput::ButtonPressed("ok".into())));
assert!(!Dialog::is_visible(&state));
}
#[test]
fn test_instance_is_visible() {
let mut state = DialogState::alert("T", "M");
assert!(!state.is_visible());
state.set_visible(true);
assert!(state.is_visible());
}
#[test]
fn test_instance_set_visible() {
let mut state = DialogState::confirm("T", "M");
state.set_visible(true);
assert!(state.is_visible());
assert_eq!(state.focused_button(), 1);
state.set_visible(false);
assert!(!state.is_visible());
}
#[test]
fn test_with_visible() {
let state = DialogState::alert("T", "M").with_visible(true);
assert!(state.is_visible());
}
#[test]
fn test_with_visible_false() {
let state = DialogState::alert("T", "M").with_visible(false);
assert!(!state.is_visible());
}
#[test]
fn test_with_title() {
let state = DialogState::default().with_title("My Title");
assert_eq!(state.title(), "My Title");
}
#[test]
fn test_with_message_builder() {
let state = DialogState::default().with_message("Important message");
assert_eq!(state.message(), "Important message");
}
#[test]
fn test_with_buttons_builder() {
let buttons = vec![
DialogButton::new("yes", "Yes"),
DialogButton::new("no", "No"),
];
let state = DialogState::default().with_buttons(buttons);
assert_eq!(state.buttons().len(), 2);
assert_eq!(state.buttons()[0].id(), "yes");
assert_eq!(state.buttons()[1].id(), "no");
}
#[test]
fn test_with_primary_button_builder() {
let state = DialogState::new(
"T",
"M",
vec![
DialogButton::new("a", "A"),
DialogButton::new("b", "B"),
DialogButton::new("c", "C"),
],
)
.with_primary_button(2);
assert_eq!(state.primary_button(), 2);
}
#[test]
fn test_with_primary_button_clamps() {
let state =
DialogState::new("T", "M", vec![DialogButton::new("ok", "OK")]).with_primary_button(10);
assert_eq!(state.primary_button(), 0);
}
#[test]
fn test_with_primary_button_empty() {
let state = DialogState::default().with_primary_button(5);
assert_eq!(state.primary_button(), 0);
}
#[test]
fn test_builder_chaining_dialog() {
let state = DialogState::default()
.with_title("Delete?")
.with_message("Are you sure?")
.with_buttons(vec![
DialogButton::new("cancel", "Cancel"),
DialogButton::new("ok", "OK"),
])
.with_primary_button(1);
assert_eq!(state.title(), "Delete?");
assert_eq!(state.message(), "Are you sure?");
assert_eq!(state.buttons().len(), 2);
assert_eq!(state.primary_button(), 1);
}
#[test]
fn test_annotation_emitted() {
use crate::annotation::{WidgetType, with_annotations};
let mut state = DialogState::alert("Title", "Message");
Dialog::show(&mut state);
let (mut terminal, theme) = crate::component::test_utils::setup_render(80, 24);
let registry = with_annotations(|| {
terminal
.draw(|frame| {
Dialog::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
});
assert_eq!(registry.len(), 1);
let regions = registry.find_by_type(&WidgetType::Dialog);
assert_eq!(regions.len(), 1);
assert!(regions[0].annotation.has_id("dialog"));
}