use super::*;
use crate::input::{Event, Key, Modifiers};
#[path = "selection_tests.rs"]
mod selection_tests;
#[test]
fn test_new() {
let state = TextAreaState::new();
assert!(state.is_empty());
assert_eq!(state.line_count(), 1);
assert_eq!(state.line(0), Some(""));
assert_eq!(state.cursor_position(), (0, 0));
}
#[test]
fn test_default() {
let state = TextAreaState::default();
assert!(state.is_empty());
assert_eq!(state.line_count(), 1);
}
#[test]
fn test_with_value() {
let state = TextAreaState::new().with_value("Hello\nWorld");
assert_eq!(state.line_count(), 2);
assert_eq!(state.line(0), Some("Hello"));
assert_eq!(state.line(1), Some("World"));
assert_eq!(state.cursor_position(), (1, 5));
}
#[test]
fn test_with_value_empty() {
let state = TextAreaState::new().with_value("");
assert!(state.is_empty());
assert_eq!(state.line_count(), 1);
}
#[test]
fn test_with_placeholder() {
let state = TextAreaState::new().with_placeholder("Enter text...");
assert_eq!(state.placeholder(), "Enter text...");
assert!(state.is_empty());
}
#[test]
fn test_value() {
let state = TextAreaState::new().with_value("Line 1\nLine 2\nLine 3");
assert_eq!(state.value(), "Line 1\nLine 2\nLine 3");
}
#[test]
fn test_set_value() {
let mut state = TextAreaState::new();
state.set_value("New\nContent");
assert_eq!(state.line_count(), 2);
assert_eq!(state.line(0), Some("New"));
assert_eq!(state.line(1), Some("Content"));
assert_eq!(state.cursor_position(), (1, 7));
}
#[test]
fn test_line() {
let state = TextAreaState::new().with_value("a\nb\nc");
assert_eq!(state.line(0), Some("a"));
assert_eq!(state.line(1), Some("b"));
assert_eq!(state.line(2), Some("c"));
assert_eq!(state.line(3), None);
}
#[test]
fn test_current_line() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 0);
assert_eq!(state.current_line(), "Hello");
state.set_cursor_position(1, 0);
assert_eq!(state.current_line(), "World");
}
#[test]
fn test_line_count() {
assert_eq!(TextAreaState::new().line_count(), 1);
assert_eq!(TextAreaState::new().with_value("a").line_count(), 1);
assert_eq!(TextAreaState::new().with_value("a\nb").line_count(), 2);
assert_eq!(TextAreaState::new().with_value("a\nb\nc").line_count(), 3);
}
#[test]
fn test_is_empty() {
assert!(TextAreaState::new().is_empty());
assert!(!TextAreaState::new().with_value("a").is_empty());
assert!(!TextAreaState::new().with_value("\n").is_empty()); }
#[test]
fn test_cursor_position() {
let state = TextAreaState::new().with_value("Hello\nWorld");
assert_eq!(state.cursor_position(), (1, 5));
}
#[test]
fn test_set_cursor_position() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 2);
assert_eq!(state.cursor_position(), (0, 2));
}
#[test]
fn test_cursor_clamp_row() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(10, 0); assert_eq!(state.cursor_row(), 0);
}
#[test]
fn test_cursor_clamp_col() {
let mut state = TextAreaState::new().with_value("Hi");
state.set_cursor_position(0, 100); assert_eq!(state.cursor_position(), (0, 2));
}
#[test]
fn test_insert() {
let mut state = TextArea::init();
let output = TextArea::update(&mut state, TextAreaMessage::Insert('H'));
assert_eq!(state.value(), "H");
assert!(matches!(output, Some(TextAreaOutput::Changed(_))));
TextArea::update(&mut state, TextAreaMessage::Insert('i'));
assert_eq!(state.value(), "Hi");
}
#[test]
fn test_insert_unicode() {
let mut state = TextArea::init();
TextArea::update(&mut state, TextAreaMessage::Insert('日'));
TextArea::update(&mut state, TextAreaMessage::Insert('本'));
assert_eq!(state.value(), "日本");
assert_eq!(state.cursor_position(), (0, 2));
}
#[test]
fn test_newline() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 2);
TextArea::update(&mut state, TextAreaMessage::NewLine);
assert_eq!(state.line_count(), 2);
assert_eq!(state.line(0), Some("He"));
assert_eq!(state.line(1), Some("llo"));
assert_eq!(state.cursor_position(), (1, 0));
}
#[test]
fn test_newline_at_start() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::NewLine);
assert_eq!(state.line(0), Some(""));
assert_eq!(state.line(1), Some("Hello"));
}
#[test]
fn test_newline_at_end() {
let mut state = TextAreaState::new().with_value("Hello");
TextArea::update(&mut state, TextAreaMessage::NewLine);
assert_eq!(state.line(0), Some("Hello"));
assert_eq!(state.line(1), Some(""));
}
#[test]
fn test_backspace() {
let mut state = TextAreaState::new().with_value("Hello");
let output = TextArea::update(&mut state, TextAreaMessage::Backspace);
assert_eq!(state.value(), "Hell");
assert!(matches!(output, Some(TextAreaOutput::Changed(_))));
}
#[test]
fn test_backspace_join_lines() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(1, 0); TextArea::update(&mut state, TextAreaMessage::Backspace);
assert_eq!(state.value(), "HelloWorld");
assert_eq!(state.cursor_position(), (0, 5));
}
#[test]
fn test_backspace_first_line_start() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 0);
let output = TextArea::update(&mut state, TextAreaMessage::Backspace);
assert_eq!(output, None);
assert_eq!(state.value(), "Hello");
}
#[test]
fn test_delete() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 0);
let output = TextArea::update(&mut state, TextAreaMessage::Delete);
assert_eq!(state.value(), "ello");
assert!(matches!(output, Some(TextAreaOutput::Changed(_))));
}
#[test]
fn test_delete_join_lines() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 5); TextArea::update(&mut state, TextAreaMessage::Delete);
assert_eq!(state.value(), "HelloWorld");
}
#[test]
fn test_delete_last_line_end() {
let mut state = TextAreaState::new().with_value("Hello");
let output = TextArea::update(&mut state, TextAreaMessage::Delete);
assert_eq!(output, None);
}
#[test]
fn test_left() {
let mut state = TextAreaState::new().with_value("Hello");
TextArea::update(&mut state, TextAreaMessage::Left);
assert_eq!(state.cursor_position(), (0, 4));
}
#[test]
fn test_left_wrap() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(1, 0);
TextArea::update(&mut state, TextAreaMessage::Left);
assert_eq!(state.cursor_position(), (0, 5)); }
#[test]
fn test_left_at_start() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::Left);
assert_eq!(state.cursor_position(), (0, 0)); }
#[test]
fn test_right() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::Right);
assert_eq!(state.cursor_position(), (0, 1));
}
#[test]
fn test_right_wrap() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 5); TextArea::update(&mut state, TextAreaMessage::Right);
assert_eq!(state.cursor_position(), (1, 0)); }
#[test]
fn test_right_at_end() {
let mut state = TextAreaState::new().with_value("Hello");
TextArea::update(&mut state, TextAreaMessage::Right);
assert_eq!(state.cursor_position(), (0, 5)); }
#[test]
fn test_up() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
TextArea::update(&mut state, TextAreaMessage::Up);
assert_eq!(state.cursor_position(), (0, 5));
}
#[test]
fn test_up_clamps_column() {
let mut state = TextAreaState::new().with_value("Hi\nHello");
state.set_cursor_position(1, 5); TextArea::update(&mut state, TextAreaMessage::Up);
assert_eq!(state.cursor_position(), (0, 2)); }
#[test]
fn test_up_at_first_line() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 2);
TextArea::update(&mut state, TextAreaMessage::Up);
assert_eq!(state.cursor_position(), (0, 2)); }
#[test]
fn test_down() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 2);
TextArea::update(&mut state, TextAreaMessage::Down);
assert_eq!(state.cursor_position(), (1, 2));
}
#[test]
fn test_down_clamps_column() {
let mut state = TextAreaState::new().with_value("Hello\nHi");
state.set_cursor_position(0, 5); TextArea::update(&mut state, TextAreaMessage::Down);
assert_eq!(state.cursor_position(), (1, 2)); }
#[test]
fn test_down_at_last_line() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
TextArea::update(&mut state, TextAreaMessage::Down);
assert_eq!(state.cursor_row(), 1); }
#[test]
fn test_home() {
let mut state = TextAreaState::new().with_value("Hello");
TextArea::update(&mut state, TextAreaMessage::Home);
assert_eq!(state.cursor_position(), (0, 0));
}
#[test]
fn test_end() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::End);
assert_eq!(state.cursor_position(), (0, 5));
}
#[test]
fn test_text_start() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
TextArea::update(&mut state, TextAreaMessage::TextStart);
assert_eq!(state.cursor_position(), (0, 0));
}
#[test]
fn test_text_end() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::TextEnd);
assert_eq!(state.cursor_position(), (1, 5));
}
#[test]
fn test_word_left() {
let mut state = TextAreaState::new().with_value("hello world");
TextArea::update(&mut state, TextAreaMessage::WordLeft);
assert_eq!(state.cursor_position(), (0, 6)); }
#[test]
fn test_word_right() {
let mut state = TextAreaState::new().with_value("hello world");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::WordRight);
assert_eq!(state.cursor_position(), (0, 6)); }
#[test]
fn test_delete_line() {
let mut state = TextAreaState::new().with_value("Line 1\nLine 2\nLine 3");
state.set_cursor_position(1, 0);
TextArea::update(&mut state, TextAreaMessage::DeleteLine);
assert_eq!(state.line_count(), 2);
assert_eq!(state.value(), "Line 1\nLine 3");
}
#[test]
fn test_delete_line_single() {
let mut state = TextAreaState::new().with_value("Hello");
TextArea::update(&mut state, TextAreaMessage::DeleteLine);
assert!(state.is_empty());
assert_eq!(state.line_count(), 1);
}
#[test]
fn test_delete_to_end() {
let mut state = TextAreaState::new().with_value("Hello World");
state.set_cursor_position(0, 5);
TextArea::update(&mut state, TextAreaMessage::DeleteToEnd);
assert_eq!(state.value(), "Hello");
}
#[test]
fn test_delete_to_start() {
let mut state = TextAreaState::new().with_value("Hello World");
state.set_cursor_position(0, 6);
TextArea::update(&mut state, TextAreaMessage::DeleteToStart);
assert_eq!(state.value(), "World");
assert_eq!(state.cursor_position(), (0, 0));
}
#[test]
fn test_clear() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
let output = TextArea::update(&mut state, TextAreaMessage::Clear);
assert!(state.is_empty());
assert!(matches!(output, Some(TextAreaOutput::Changed(_))));
}
#[test]
fn test_clear_empty() {
let mut state = TextArea::init();
let output = TextArea::update(&mut state, TextAreaMessage::Clear);
assert_eq!(output, None);
}
#[test]
fn test_set_value_message() {
let mut state = TextArea::init();
let output = TextArea::update(
&mut state,
TextAreaMessage::SetValue("New\nValue".to_string()),
);
assert_eq!(state.value(), "New\nValue");
assert!(matches!(output, Some(TextAreaOutput::Changed(_))));
}
#[test]
fn test_set_value_same() {
let mut state = TextAreaState::new().with_value("Same");
let output = TextArea::update(&mut state, TextAreaMessage::SetValue("Same".to_string()));
assert_eq!(output, None);
}
#[test]
fn test_submit() {
let mut state = TextAreaState::new().with_value("My content");
let output = TextArea::update(&mut state, TextAreaMessage::Submit);
assert_eq!(
output,
Some(TextAreaOutput::Submitted("My content".to_string()))
);
}
#[test]
fn test_scroll_offset() {
let state = TextAreaState::new();
assert_eq!(state.scroll_offset(), 0);
}
#[test]
fn test_ensure_cursor_visible_down() {
let mut state = TextAreaState::new().with_value("1\n2\n3\n4\n5\n6\n7\n8\n9\n10");
state.set_cursor_position(9, 0); state.ensure_cursor_visible(5);
assert!(state.scroll_offset > 0);
assert!(state.cursor_row >= state.scroll_offset);
assert!(state.cursor_row < state.scroll_offset + 5);
}
#[test]
fn test_ensure_cursor_visible_up() {
let mut state = TextAreaState::new().with_value("1\n2\n3\n4\n5\n6\n7\n8\n9\n10");
state.scroll_offset = 5;
state.set_cursor_position(2, 0);
state.ensure_cursor_visible(5);
assert_eq!(state.scroll_offset, 2);
}
#[test]
fn test_view_focused() {
let state = TextAreaState::new().with_value("Hello");
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 10);
terminal
.draw(|frame| {
TextArea::view(
&state,
&mut RenderContext::new(frame, frame.area(), &theme).focused(true),
);
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_unfocused() {
let state = TextAreaState::new().with_value("Hello");
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 10);
terminal
.draw(|frame| {
TextArea::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_placeholder() {
let state = TextAreaState::new().with_placeholder("Enter text...");
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 10);
terminal
.draw(|frame| {
TextArea::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_renders() {
let state = TextAreaState::new().with_value("Line 1\nLine 2\nLine 3");
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 10);
terminal
.draw(|frame| {
TextArea::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_full_workflow() {
let mut state = TextAreaState::new();
TextArea::update(&mut state, TextAreaMessage::Insert('H'));
TextArea::update(&mut state, TextAreaMessage::Insert('e'));
TextArea::update(&mut state, TextAreaMessage::Insert('l'));
TextArea::update(&mut state, TextAreaMessage::Insert('l'));
TextArea::update(&mut state, TextAreaMessage::Insert('o'));
TextArea::update(&mut state, TextAreaMessage::NewLine);
TextArea::update(&mut state, TextAreaMessage::Insert('W'));
TextArea::update(&mut state, TextAreaMessage::Insert('o'));
TextArea::update(&mut state, TextAreaMessage::Insert('r'));
TextArea::update(&mut state, TextAreaMessage::Insert('l'));
TextArea::update(&mut state, TextAreaMessage::Insert('d'));
assert_eq!(state.value(), "Hello\nWorld");
assert_eq!(state.line_count(), 2);
TextArea::update(&mut state, TextAreaMessage::Up);
assert_eq!(state.cursor_position(), (0, 5));
TextArea::update(&mut state, TextAreaMessage::Home);
assert_eq!(state.cursor_position(), (0, 0));
TextArea::update(&mut state, TextAreaMessage::DeleteLine);
assert_eq!(state.value(), "World");
TextArea::update(&mut state, TextAreaMessage::Clear);
assert!(state.is_empty());
}
#[test]
fn test_init() {
let state = TextArea::init();
assert!(state.is_empty());
}
#[test]
fn test_set_value_empty_string() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_value("");
assert!(state.is_empty());
assert_eq!(state.line_count(), 1);
assert_eq!(state.cursor_position(), (0, 0));
}
#[test]
fn test_set_placeholder_method() {
let mut state = TextAreaState::new();
state.set_placeholder("Type here...");
assert_eq!(state.placeholder(), "Type here...");
}
#[test]
fn test_cursor_col_accessor() {
let state = TextAreaState::new().with_value("Hello");
assert_eq!(state.cursor_col(), 5);
}
#[test]
fn test_word_left_at_line_start() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(1, 0); TextArea::update(&mut state, TextAreaMessage::WordLeft);
assert_eq!(state.cursor_position(), (0, 5));
}
#[test]
fn test_word_left_skip_whitespace() {
let mut state = TextAreaState::new().with_value("hello world");
state.set_cursor_position(0, 8); TextArea::update(&mut state, TextAreaMessage::WordLeft);
assert!(state.cursor_col() < 8);
}
#[test]
fn test_word_right_at_line_end() {
let mut state = TextAreaState::new().with_value("Hello\nWorld");
state.set_cursor_position(0, 5); TextArea::update(&mut state, TextAreaMessage::WordRight);
assert_eq!(state.cursor_position(), (1, 0));
}
#[test]
fn test_word_right_skip_word() {
let mut state = TextAreaState::new().with_value("abc def");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::WordRight);
assert_eq!(state.cursor_position(), (0, 4));
}
#[test]
fn test_delete_line_last_line() {
let mut state = TextAreaState::new().with_value("Line 1\nLine 2");
state.set_cursor_position(1, 3); TextArea::update(&mut state, TextAreaMessage::DeleteLine);
assert_eq!(state.line_count(), 1);
assert_eq!(state.cursor_row(), 0);
}
#[test]
fn test_delete_line_single_empty() {
let mut state = TextArea::init();
let output = TextArea::update(&mut state, TextAreaMessage::DeleteLine);
assert_eq!(output, None);
}
#[test]
fn test_delete_to_end_at_end() {
let mut state = TextAreaState::new().with_value("Hello");
let output = TextArea::update(&mut state, TextAreaMessage::DeleteToEnd);
assert_eq!(output, None);
}
#[test]
fn test_delete_to_start_at_start() {
let mut state = TextAreaState::new().with_value("Hello");
state.set_cursor_position(0, 0);
let output = TextArea::update(&mut state, TextAreaMessage::DeleteToStart);
assert_eq!(output, None);
}
#[test]
fn test_view_with_scroll() {
let state = TextAreaState::new().with_value(
"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8\nLine 9\nLine 10",
);
let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 5);
terminal
.draw(|frame| {
TextArea::view(
&state,
&mut RenderContext::new(frame, frame.area(), &theme).focused(true),
);
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_view_cursor_above_scroll() {
let mut state = TextAreaState::new().with_value("1\n2\n3\n4\n5\n6\n7\n8\n9\n10");
state.scroll_offset = 5; state.set_cursor_position(2, 0); let (mut terminal, theme) = crate::component::test_utils::setup_render(40, 5);
terminal
.draw(|frame| {
TextArea::view(
&state,
&mut RenderContext::new(frame, frame.area(), &theme).focused(true),
);
})
.unwrap();
insta::assert_snapshot!(terminal.backend().to_string());
}
#[test]
fn test_ensure_cursor_visible_zero_lines() {
let mut state = TextAreaState::new().with_value("Hello");
state.ensure_cursor_visible(0);
assert_eq!(state.scroll_offset(), 0);
}
#[test]
fn test_backspace_unicode() {
let mut state = TextAreaState::new().with_value("日本");
TextArea::update(&mut state, TextAreaMessage::Backspace);
assert_eq!(state.value(), "日");
}
#[test]
fn test_delete_unicode() {
let mut state = TextAreaState::new().with_value("日本");
state.set_cursor_position(0, 0);
TextArea::update(&mut state, TextAreaMessage::Delete);
assert_eq!(state.value(), "本");
}
#[test]
fn test_insert_emoji() {
let mut state = TextAreaState::new();
TextArea::update(&mut state, TextAreaMessage::Insert('\u{1F600}'));
assert!(state.value().contains('\u{1F600}'));
}
#[test]
fn test_backspace_emoji() {
let mut state = TextAreaState::new();
TextArea::update(&mut state, TextAreaMessage::Insert('A'));
TextArea::update(&mut state, TextAreaMessage::Insert('\u{1F600}'));
assert!(state.value().contains('\u{1F600}'));
TextArea::update(&mut state, TextAreaMessage::Backspace);
assert!(!state.value().contains('\u{1F600}'));
assert_eq!(state.value(), "A");
}
#[test]
fn test_combining_diacritics() {
let mut state = TextAreaState::new();
TextArea::update(&mut state, TextAreaMessage::Insert('e'));
TextArea::update(&mut state, TextAreaMessage::Insert('\u{0301}'));
assert!(state.value().contains('e'));
assert!(state.value().contains('\u{0301}'));
}
#[test]
fn test_multiline_mixed_unicode() {
let mut state = TextAreaState::new();
for c in "日本語".chars() {
TextArea::update(&mut state, TextAreaMessage::Insert(c));
}
TextArea::update(&mut state, TextAreaMessage::NewLine);
TextArea::update(&mut state, TextAreaMessage::Insert('\u{1F600}'));
TextArea::update(&mut state, TextAreaMessage::Insert('\u{1F389}'));
let value = state.value();
assert!(value.contains("日本語"));
assert!(value.contains('\u{1F600}'));
assert!(value.contains('\u{1F389}'));
}
#[test]
fn test_handle_event_char_insert() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::char('a'),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::Insert('a')));
}
#[test]
fn test_handle_event_enter() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::key(Key::Enter),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::NewLine));
}
#[test]
fn test_handle_event_arrow_up() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::key(Key::Up),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::Up));
}
#[test]
fn test_handle_event_arrow_down() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::key(Key::Down),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::Down));
}
#[test]
fn test_handle_event_arrow_left() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::key(Key::Left),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::Left));
}
#[test]
fn test_handle_event_arrow_right() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::key(Key::Right),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::Right));
}
#[test]
fn test_handle_event_ctrl_home() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::key_with(Key::Home, Modifiers::CONTROL),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::TextStart));
}
#[test]
fn test_handle_event_ctrl_end() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::key_with(Key::End, Modifiers::CONTROL),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::TextEnd));
}
#[test]
fn test_handle_event_ctrl_k() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::ctrl('k'),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::DeleteToEnd));
}
#[test]
fn test_handle_event_ctrl_u() {
let state = TextArea::init();
let msg = TextArea::handle_event(
&state,
&Event::ctrl('u'),
&EventContext::new().focused(true),
);
assert_eq!(msg, Some(TextAreaMessage::DeleteToStart));
}
#[test]
fn test_handle_event_ignored_when_unfocused() {
let state = TextArea::init();
let msg = TextArea::handle_event(&state, &Event::char('a'), &EventContext::default());
assert_eq!(msg, None);
}
#[test]
fn test_dispatch_event_insert() {
let mut state = TextArea::init();
let output = TextArea::dispatch_event(
&mut state,
&Event::char('a'),
&EventContext::new().focused(true),
);
assert!(matches!(output, Some(TextAreaOutput::Changed(_))));
assert_eq!(state.value(), "a");
}
#[test]
fn test_instance_update() {
let mut state = TextArea::init();
let output = state.update(TextAreaMessage::Insert('a'));
assert!(matches!(output, Some(TextAreaOutput::Changed(_))));
assert_eq!(state.value(), "a");
}
#[test]
fn test_cursor_display_position_emoji() {
let mut state = TextAreaState::new();
TextArea::update(&mut state, TextAreaMessage::Insert('A'));
TextArea::update(&mut state, TextAreaMessage::Insert('\u{1F600}'));
TextArea::update(&mut state, TextAreaMessage::Insert('B'));
assert_eq!(state.cursor_position(), (0, 3));
assert_eq!(state.cursor_display_position(), (0, 4));
}
#[test]
fn test_cursor_display_position_cjk() {
let mut state = TextAreaState::new();
TextArea::update(&mut state, TextAreaMessage::Insert('日'));
TextArea::update(&mut state, TextAreaMessage::Insert('本'));
assert_eq!(state.cursor_position(), (0, 2));
assert_eq!(state.cursor_display_position(), (0, 4));
}
#[test]
fn test_cursor_display_position_multiline_emoji() {
let mut state = TextAreaState::new();
for c in "Hello".chars() {
TextArea::update(&mut state, TextAreaMessage::Insert(c));
}
TextArea::update(&mut state, TextAreaMessage::NewLine);
TextArea::update(&mut state, TextAreaMessage::Insert('😀'));
TextArea::update(&mut state, TextAreaMessage::Insert('B'));
assert_eq!(state.cursor_position(), (1, 2));
assert_eq!(state.cursor_display_position(), (1, 3));
}
#[test]
fn test_cursor_display_position_ascii() {
let state = TextAreaState::new().with_value("hello");
assert_eq!(state.cursor_display_position(), (0, 5));
assert_eq!(state.cursor_position(), (0, 5));
}
#[test]
fn test_cursor_display_position_empty() {
let state = TextAreaState::new();
assert_eq!(state.cursor_display_position(), (0, 0));
}
#[test]
fn test_annotation_emitted() {
use crate::annotation::{WidgetType, with_annotations};
let state = TextAreaState::new();
let (mut terminal, theme) = crate::component::test_utils::setup_render(30, 10);
let registry = with_annotations(|| {
terminal
.draw(|frame| {
TextArea::view(&state, &mut RenderContext::new(frame, frame.area(), &theme));
})
.unwrap();
});
assert_eq!(registry.len(), 1);
let regions = registry.find_by_type(&WidgetType::TextArea);
assert_eq!(regions.len(), 1);
assert!(!regions[0].annotation.focused);
assert!(!regions[0].annotation.disabled);
}