use super::*; use iced::widget::text_editor::Motion; type Buffer = Content; fn at(line: usize, column: usize) -> Position { Position { line, column } } fn range(start: Position, end: Position, reverse: bool) -> Cursor { Cursor { position: if reverse { start } else { end }, selection: Some(if reverse { end } else { start }), } } #[test] fn caret_inserts_four_spaces_and_outdent_removes_only_leading_whitespace() { let mut content = Buffer::with_text(" 雨🚀\r\nnext"); content.move_to(Cursor { position: at(0, " 雨".len()), selection: None, }); apply(&mut content, false); assert_eq!(content.text(), " 雨 🚀\r\nnext"); assert_eq!(content.cursor().position, at(0, " 雨 ".len())); apply(&mut content, true); assert_eq!(content.text(), "雨 🚀\r\nnext"); assert_eq!(content.cursor().position, at(0, "雨 ".len())); apply(&mut content, true); assert_eq!(content.text(), "雨 🚀\r\nnext"); } #[test] fn directional_blocks_preserve_unicode_endings_and_exclude_final_zero_column() { let source = "雨\r\n🚀\nlast\r\n"; for reverse in [false, true] { let mut content = Buffer::with_text(source); let original = range(at(0, 0), at(2, 0), reverse); content.move_to(original); apply(&mut content, false); assert_eq!(content.text(), " 雨\r\n 🚀\nlast\r\n"); assert_eq!(content.cursor(), range(at(0, 4), at(2, 0), reverse)); apply(&mut content, true); assert_eq!(content.text(), source); assert_eq!(content.cursor(), original); } } #[test] fn outdent_handles_tabs_partial_spaces_and_clamps_endpoint_inside_removed_indent() { for reverse in [false, true] { let mut content = Buffer::with_text("\t雨\r\n 🚀\n fin"); content.move_to(range(at(0, 0), at(2, 2), reverse)); apply(&mut content, true); assert_eq!(content.text(), "雨\r\n🚀\nfin"); assert_eq!(content.cursor(), range(at(0, 0), at(2, 0), reverse)); } } #[test] fn word_and_line_selections_indent_effective_range_in_both_directions() { for line_mode in [false, true] { for reverse in [false, true] { let mut content = Buffer::with_text("one alpha\r\ntwo beta\nthree gamma"); content.move_to(Cursor { position: if reverse { at(2, 8) } else { at(0, 6) }, selection: None, }); content.perform(if line_mode { Action::SelectLine } else { Action::SelectWord }); content.perform(Action::Select(if reverse { Motion::DocumentStart } else { Motion::DocumentEnd })); let selected = content.selection().unwrap(); apply(&mut content, false); assert_eq!( content.text(), " one alpha\r\n two beta\n three gamma" ); let cursor = content.cursor(); assert_eq!( cursor.position.line < cursor.selection.unwrap().line, reverse ); apply(&mut content, true); assert_eq!(content.text(), "one alpha\r\ntwo beta\nthree gamma"); assert_eq!(content.selection(), Some(selected)); } } } #[test] fn no_op_outdent_preserves_semantic_word_selection_and_last_empty_line_is_excluded() { let mut content = Buffer::with_text("alpha tail\r\n"); content.move_to(Cursor { position: at(0, 2), selection: None, }); content.perform(Action::SelectWord); let raw = content.cursor(); apply(&mut content, true); assert_eq!(content.cursor(), raw); assert_eq!(content.selection().as_deref(), Some("alpha")); content.perform(Action::SelectAll); apply(&mut content, false); assert_eq!(content.text(), " alpha tail\r\n"); assert_eq!(content.cursor().position, at(1, 0)); }