Add editor handlers.rs tests (15 tests, was 0)
editor/handlers.rs now has comprehensive key dispatch tests: - Mode checks (default is Insert) - Esc/F10 behavior (save-before-close prompt on dirty buffer) - F2 save, F9 menubar toggle, Ctrl-Q literal insert toggle - Backspace, Enter, Tab, printable char insertion - Bookmark toggle, Ctrl-S syntax toggle - Ctrl-H backspace alias (MC parity) - Prompt mode Esc cancel - Insert literal mode pass-through Also: made viewer mod tests pub(crate) for cross-module test access. 1455 tests passing, zero warnings.
This commit is contained in:
@@ -1343,3 +1343,145 @@ fn word_at_cursor(buf: &crate::editor::buffer::Buffer, pos: usize) -> String {
|
||||
}
|
||||
text[start..end].to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::editor::EditorResult;
|
||||
|
||||
fn empty_editor() -> Editor {
|
||||
Editor::new_empty()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_mode_is_insert() {
|
||||
let e = empty_editor();
|
||||
assert!(matches!(e.mode(), Mode::Insert));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn esc_with_modified_prompts_save() {
|
||||
let mut e = empty_editor();
|
||||
e.insert_str("test");
|
||||
e.modified = true;
|
||||
let result = e.handle_key(Key::ESCAPE);
|
||||
assert!(matches!(result, EditorResult::Running));
|
||||
// Esc with dirty buffer opens save-before-close prompt
|
||||
assert!(matches!(e.mode(), Mode::Prompt(PromptKind::SaveBeforeClose)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f10_with_modified_prompts_save() {
|
||||
let mut e = empty_editor();
|
||||
e.insert_str("test");
|
||||
e.modified = true;
|
||||
let result = e.handle_key(Key::f(10));
|
||||
assert!(matches!(result, EditorResult::Running));
|
||||
assert!(matches!(e.mode(), Mode::Prompt(PromptKind::SaveBeforeClose)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_s_in_insert_returns_running() {
|
||||
let mut e = empty_editor();
|
||||
e.insert_str("test");
|
||||
let result = e.handle_key(Key::ctrl('s'));
|
||||
assert!(matches!(result, EditorResult::Running));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_q_toggles_literal_insert() {
|
||||
let mut e = empty_editor();
|
||||
assert!(!e.insert_literal);
|
||||
let _ = e.handle_key(Key::ctrl('q'));
|
||||
assert!(e.insert_literal);
|
||||
let _ = e.handle_key(Key::ctrl('q'));
|
||||
assert!(!e.insert_literal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f2_returns_save() {
|
||||
let mut e = empty_editor();
|
||||
let result = e.handle_key(Key::f(2));
|
||||
assert!(matches!(result, EditorResult::Save));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enter_in_insert_splits_line() {
|
||||
let mut e = empty_editor();
|
||||
e.insert_str("hello");
|
||||
let len_before = e.buffer.len();
|
||||
let _ = e.handle_key(Key::ENTER);
|
||||
// Enter inserts a newline, buffer grows
|
||||
assert!(e.buffer.len() > len_before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backspace_in_insert_deletes() {
|
||||
let mut e = empty_editor();
|
||||
e.insert_str("hello");
|
||||
e.cursor.set_position(5, &e.buffer);
|
||||
let len_before = e.buffer.len();
|
||||
let _ = e.handle_key(Key::BACKSPACE);
|
||||
assert!(e.buffer.len() < len_before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_in_insert_inserts_tab() {
|
||||
let mut e = empty_editor();
|
||||
let len_before = e.buffer.len();
|
||||
let _ = e.handle_key(Key::TAB);
|
||||
assert!(e.buffer.len() > len_before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn printable_char_in_insert_inserts() {
|
||||
let mut e = empty_editor();
|
||||
let len_before = e.buffer.len();
|
||||
let _ = e.handle_key(Key { code: b'x' as u32, mods: Modifiers::empty() });
|
||||
assert_eq!(e.buffer.len(), len_before + 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_literal_mode_passes_char_through() {
|
||||
let mut e = empty_editor();
|
||||
e.insert_literal = true;
|
||||
// ESC in literal mode inserts the escape char, doesn't close
|
||||
let _ = e.handle_key(Key::ESCAPE);
|
||||
assert!(!e.insert_literal); // literal mode consumed
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f9_toggles_menubar() {
|
||||
let mut e = empty_editor();
|
||||
assert!(e.menubar.is_none());
|
||||
let _ = e.handle_key(Key::f(9));
|
||||
assert!(e.menubar.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompt_mode_esc_cancels() {
|
||||
let mut e = empty_editor();
|
||||
e.mode = Mode::Prompt(PromptKind::Find);
|
||||
let result = e.handle_key(Key::ESCAPE);
|
||||
assert!(matches!(result, EditorResult::Running));
|
||||
assert!(!matches!(e.mode(), Mode::Prompt(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bookmark_toggle_switches_to_prompt() {
|
||||
let mut e = empty_editor();
|
||||
let _ = e.handle_key(Key::alt('m'));
|
||||
assert!(matches!(e.mode(), Mode::Prompt(PromptKind::BookmarkSet)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_h_in_insert_is_backspace() {
|
||||
let mut e = empty_editor();
|
||||
e.insert_str("hello");
|
||||
e.cursor.set_position(5, &e.buffer);
|
||||
let len_before = e.buffer.len();
|
||||
let _ = e.handle_key(Key::ctrl('h'));
|
||||
// Ctrl-H is backspace alias (MC parity) — deletes character
|
||||
assert_eq!(e.buffer.len(), len_before - 1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user