use crate::tests::mono_style_test;
use crate::{Action, ActionResult, Point, TextContext, TextState};
#[test]
pub fn test() {
let mut ctx = TextContext::default();
let initial_text = "Hello World".to_string();
let mut text_state = TextState::new_with_text(initial_text, &mut ctx.font_system, ());
text_state.set_style(&mono_style_test());
text_state.set_outer_size(&Point::from((200.0, 25.0)));
text_state.is_editable = true;
text_state.is_editing = true;
text_state.is_selectable = true;
text_state.are_actions_enabled = true;
text_state.recalculate(&mut ctx);
let mono_width = text_state.first_glyph().unwrap().w;
assert!(mono_width > 0.0);
assert_eq!(text_state.cursor_char_index(), Some(0));
assert_eq!(text_state.caret_position_relative().unwrap().x, 0.0);
text_state.handle_press(&mut ctx, Point { x: 25.0, y: 10.0 });
assert_eq!(text_state.cursor_char_index(), Some(3));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 3.0).floor()
);
let result = text_state.apply_action(&mut ctx, &Action::InsertChar("a".into()));
assert!(matches!(result, ActionResult::TextChanged));
assert_eq!(text_state.text_char_len(), 12);
assert_eq!(text_state.cursor_char_index(), Some(4));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 4.0).floor()
);
assert_eq!(text_state.text(), "Helalo World");
let result = text_state.apply_action(&mut ctx, &Action::MoveCursorRight);
assert!(matches!(result, ActionResult::CursorUpdated));
assert_eq!(text_state.text_char_len(), 12);
assert_eq!(text_state.cursor_char_index(), Some(5));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 5.0).floor()
);
}
#[test]
pub fn test_cyrillic() {
let mut ctx = TextContext::default();
let initial_text = "Привет Мир".to_string();
let mut text_state = TextState::new_with_text(initial_text, &mut ctx.font_system, ());
text_state.set_style(&mono_style_test());
text_state.set_outer_size(&Point::from((200.0, 25.0)));
text_state.is_editable = true;
text_state.is_editing = true;
text_state.is_selectable = true;
text_state.are_actions_enabled = true;
text_state.recalculate(&mut ctx);
let mono_width = text_state.first_glyph().unwrap().w;
assert!(mono_width > 0.0);
assert_eq!(text_state.text_char_len(), 10);
assert_eq!(text_state.cursor_char_index(), Some(0));
assert_eq!(text_state.caret_position_relative().unwrap().x, 0.0);
let result = text_state.apply_action(&mut ctx, &Action::MoveCursorRight);
assert!(matches!(result, ActionResult::CursorUpdated));
assert_eq!(text_state.text_char_len(), 10);
assert_eq!(text_state.cursor_char_index(), Some(1));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 1.0).floor()
);
let result = text_state.apply_action(&mut ctx, &Action::MoveCursorRight);
assert!(matches!(result, ActionResult::CursorUpdated));
assert_eq!(text_state.text_char_len(), 10);
assert_eq!(text_state.cursor_char_index(), Some(2));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 2.0).floor()
);
text_state.handle_press(&mut ctx, Point { x: 25.0, y: 10.0 });
assert_eq!(text_state.cursor_char_index(), Some(3));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 3.0).floor()
);
let result = text_state.apply_action(&mut ctx, &Action::InsertChar("ш".into()));
assert!(matches!(result, ActionResult::TextChanged));
assert_eq!(text_state.text_char_len(), 11);
assert_eq!(text_state.cursor_char_index(), Some(4));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 4.0).floor()
);
assert_eq!(text_state.text(), "Пришвет Мир");
let result = text_state.apply_action(&mut ctx, &Action::MoveCursorRight);
assert!(matches!(result, ActionResult::CursorUpdated));
assert_eq!(text_state.text_char_len(), 11);
assert_eq!(text_state.cursor_char_index(), Some(5));
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 5.0).floor()
);
}
#[test]
pub fn test_insert_into_empty_text() {
let mut ctx = TextContext::default();
let initial_text = "".to_string();
let mut text_state = TextState::new_with_text(initial_text, &mut ctx.font_system, ());
text_state.set_style(&mono_style_test());
text_state.set_outer_size(&Point::from((200.0, 25.0)));
text_state.is_editable = true;
text_state.is_editing = true;
text_state.is_selectable = true;
text_state.are_actions_enabled = true;
text_state.recalculate(&mut ctx);
assert_eq!(text_state.text_char_len(), 0);
assert_eq!(text_state.cursor_char_index(), Some(0));
assert_eq!(text_state.caret_position_relative().unwrap().x, 0.0);
let result = text_state.apply_action(&mut ctx, &Action::InsertChar("a".into()));
assert!(matches!(result, ActionResult::TextChanged));
assert_eq!(text_state.text_char_len(), 1);
assert_eq!(text_state.text(), "a");
assert_eq!(text_state.cursor_char_index(), Some(1));
let mono_width = text_state.first_glyph().unwrap().w;
assert_eq!(
text_state.caret_position_relative().unwrap().x,
(mono_width * 1.0).floor()
);
}
#[test]
pub fn test_delete_at_end_of_text() {
let mut ctx = TextContext::default();
let initial_text = "Hello".to_string();
let mut text_state = TextState::new_with_text(initial_text, &mut ctx.font_system, ());
text_state.set_style(&mono_style_test());
text_state.set_outer_size(&Point::from((200.0, 25.0)));
text_state.is_editable = true;
text_state.is_editing = true;
text_state.is_selectable = true;
text_state.are_actions_enabled = true;
text_state.recalculate(&mut ctx);
for _ in 0..5 {
text_state.apply_action(&mut ctx, &Action::MoveCursorRight);
}
assert_eq!(text_state.cursor_char_index(), Some(5));
assert_eq!(text_state.text_char_len(), 5);
let result = text_state.apply_action(&mut ctx, &Action::DeleteBackward);
assert!(matches!(result, ActionResult::TextChanged));
assert_eq!(text_state.text_char_len(), 4);
assert_eq!(text_state.text(), "Hell");
assert_eq!(text_state.cursor_char_index(), Some(4));
}
#[test]
pub fn test_insert_newline_at_end_of_text() {
let mut ctx = TextContext::default();
let initial_text = "Hello".to_string();
let mut text_state = TextState::new_with_text(initial_text, &mut ctx.font_system, ());
text_state.set_style(&mono_style_test());
text_state.set_outer_size(&Point::from((200.0, 25.0)));
text_state.is_editable = true;
text_state.is_editing = true;
text_state.is_selectable = true;
text_state.are_actions_enabled = true;
text_state.recalculate(&mut ctx);
for _ in 0..5 {
text_state.apply_action(&mut ctx, &Action::MoveCursorRight);
}
assert_eq!(text_state.cursor_char_index(), Some(5));
assert_eq!(text_state.text_char_len(), 5);
let result = text_state.apply_action(&mut ctx, &Action::InsertChar("\n".into()));
assert!(matches!(result, ActionResult::TextChanged));
assert_eq!(text_state.text_char_len(), 7);
assert_eq!(text_state.text(), "Hello\n\n");
assert_eq!(text_state.cursor_char_index(), Some(6));
}
#[test]
pub fn test_click_after_text_then_insert_keeps_caret_moving_forward() {
let mut ctx = TextContext::default();
let initial_text = "Hehe".to_string();
let mut text_state = TextState::new_with_text(initial_text, &mut ctx.font_system, ());
text_state.set_outer_size(&Point::from((200.0, 25.0)));
text_state.is_editable = true;
text_state.is_editing = true;
text_state.is_selectable = true;
text_state.are_actions_enabled = true;
text_state.recalculate(&mut ctx);
text_state.handle_press(&mut ctx, Point::new(198.0, 10.0));
assert_eq!(text_state.cursor_char_index(), Some(4));
let caret_x_before_insert = text_state
.caret_position_relative()
.expect("Caret should be visible")
.x;
let result = text_state.apply_action(&mut ctx, &Action::InsertChar("x".into()));
assert!(matches!(result, ActionResult::TextChanged));
assert_eq!(text_state.text(), "Hehex");
assert_eq!(text_state.cursor_char_index(), Some(5));
let caret_x_after_insert = text_state
.caret_position_relative()
.expect("Caret should be visible")
.x;
assert!(
caret_x_after_insert > caret_x_before_insert,
"Caret should move to the right after inserting at end. before={caret_x_before_insert}, after={caret_x_after_insert}"
);
}