test.rs

  1mod neovim_backed_binding_test_context;
  2mod neovim_backed_test_context;
  3mod neovim_connection;
  4mod vim_binding_test_context;
  5mod vim_test_context;
  6
  7use command_palette::CommandPalette;
  8use editor::DisplayPoint;
  9pub use neovim_backed_binding_test_context::*;
 10pub use neovim_backed_test_context::*;
 11pub use vim_binding_test_context::*;
 12pub use vim_test_context::*;
 13
 14use indoc::indoc;
 15use search::BufferSearchBar;
 16
 17use crate::state::Mode;
 18
 19#[gpui::test]
 20async fn test_initially_disabled(cx: &mut gpui::TestAppContext) {
 21    let mut cx = VimTestContext::new(cx, false).await;
 22    cx.simulate_keystrokes(["h", "j", "k", "l"]);
 23    cx.assert_editor_state("hjklˇ");
 24}
 25
 26#[gpui::test]
 27async fn test_neovim(cx: &mut gpui::TestAppContext) {
 28    let mut cx = NeovimBackedTestContext::new(cx).await;
 29
 30    cx.simulate_shared_keystroke("i").await;
 31    cx.assert_state_matches().await;
 32    cx.simulate_shared_keystrokes([
 33        "shift-T", "e", "s", "t", " ", "t", "e", "s", "t", "escape", "0", "d", "w",
 34    ])
 35    .await;
 36    cx.assert_state_matches().await;
 37    cx.assert_editor_state("ˇtest");
 38}
 39
 40#[gpui::test]
 41async fn test_toggle_through_settings(cx: &mut gpui::TestAppContext) {
 42    let mut cx = VimTestContext::new(cx, true).await;
 43
 44    cx.simulate_keystroke("i");
 45    assert_eq!(cx.mode(), Mode::Insert);
 46
 47    // Editor acts as though vim is disabled
 48    cx.disable_vim();
 49    cx.simulate_keystrokes(["h", "j", "k", "l"]);
 50    cx.assert_editor_state("hjklˇ");
 51
 52    // Selections aren't changed if editor is blurred but vim-mode is still disabled.
 53    cx.set_state("«hjklˇ»", Mode::Normal);
 54    cx.assert_editor_state("«hjklˇ»");
 55    cx.update_editor(|_, cx| cx.blur());
 56    cx.assert_editor_state("«hjklˇ»");
 57    cx.update_editor(|_, cx| cx.focus_self());
 58    cx.assert_editor_state("«hjklˇ»");
 59
 60    // Enabling dynamically sets vim mode again and restores normal mode
 61    cx.enable_vim();
 62    assert_eq!(cx.mode(), Mode::Normal);
 63    cx.simulate_keystrokes(["h", "h", "h", "l"]);
 64    assert_eq!(cx.buffer_text(), "hjkl".to_owned());
 65    cx.assert_editor_state("hˇjkl");
 66    cx.simulate_keystrokes(["i", "T", "e", "s", "t"]);
 67    cx.assert_editor_state("hTestˇjkl");
 68
 69    // Disabling and enabling resets to normal mode
 70    assert_eq!(cx.mode(), Mode::Insert);
 71    cx.disable_vim();
 72    cx.enable_vim();
 73    assert_eq!(cx.mode(), Mode::Normal);
 74}
 75
 76#[gpui::test]
 77async fn test_buffer_search(cx: &mut gpui::TestAppContext) {
 78    let mut cx = VimTestContext::new(cx, true).await;
 79
 80    cx.set_state(
 81        indoc! {"
 82            The quick brown
 83            fox juˇmps over
 84            the lazy dog"},
 85        Mode::Normal,
 86    );
 87    cx.simulate_keystroke("/");
 88
 89    let search_bar = cx.workspace(|workspace, cx| {
 90        workspace
 91            .active_pane()
 92            .read(cx)
 93            .toolbar()
 94            .read(cx)
 95            .item_of_type::<BufferSearchBar>()
 96            .expect("Buffer search bar should be deployed")
 97    });
 98
 99    search_bar.read_with(cx.cx, |bar, cx| {
100        assert_eq!(bar.query_editor.read(cx).text(cx), "");
101    })
102}
103
104#[gpui::test]
105async fn test_count_down(cx: &mut gpui::TestAppContext) {
106    let mut cx = VimTestContext::new(cx, true).await;
107
108    cx.set_state(indoc! {"aˇa\nbb\ncc\ndd\nee"}, Mode::Normal);
109    cx.simulate_keystrokes(["2", "down"]);
110    cx.assert_editor_state("aa\nbb\ncˇc\ndd\nee");
111    cx.simulate_keystrokes(["9", "down"]);
112    cx.assert_editor_state("aa\nbb\ncc\ndd\neˇe");
113}
114
115#[gpui::test]
116async fn test_end_of_document_710(cx: &mut gpui::TestAppContext) {
117    let mut cx = VimTestContext::new(cx, true).await;
118
119    // goes to end by default
120    cx.set_state(indoc! {"aˇa\nbb\ncc"}, Mode::Normal);
121    cx.simulate_keystrokes(["shift-g"]);
122    cx.assert_editor_state("aa\nbb\ncˇc");
123
124    // can go to line 1 (https://github.com/zed-industries/community/issues/710)
125    cx.simulate_keystrokes(["1", "shift-g"]);
126    cx.assert_editor_state("aˇa\nbb\ncc");
127}
128
129#[gpui::test]
130async fn test_indent_outdent(cx: &mut gpui::TestAppContext) {
131    let mut cx = VimTestContext::new(cx, true).await;
132
133    // works in normal mode
134    cx.set_state(indoc! {"aa\nbˇb\ncc"}, Mode::Normal);
135    cx.simulate_keystrokes([">", ">"]);
136    cx.assert_editor_state("aa\n    bˇb\ncc");
137    cx.simulate_keystrokes(["<", "<"]);
138    cx.assert_editor_state("aa\nbˇb\ncc");
139
140    // works in visuial mode
141    cx.simulate_keystrokes(["shift-v", "down", ">"]);
142    cx.assert_editor_state("aa\n    b«b\n    cˇ»c");
143}
144
145#[gpui::test]
146async fn test_escape_command_palette(cx: &mut gpui::TestAppContext) {
147    let mut cx = VimTestContext::new(cx, true).await;
148
149    cx.set_state("aˇbc\n", Mode::Normal);
150    cx.simulate_keystrokes(["i", "cmd-shift-p"]);
151
152    assert!(cx.workspace(|workspace, _| workspace.modal::<CommandPalette>().is_some()));
153    cx.simulate_keystroke("escape");
154    assert!(!cx.workspace(|workspace, _| workspace.modal::<CommandPalette>().is_some()));
155    cx.assert_state("aˇbc\n", Mode::Insert);
156}
157
158#[gpui::test]
159async fn test_selection_on_search(cx: &mut gpui::TestAppContext) {
160    let mut cx = VimTestContext::new(cx, true).await;
161
162    cx.set_state(indoc! {"aa\nbˇb\ncc\ncc\ncc\n"}, Mode::Normal);
163    cx.simulate_keystrokes(["/", "c", "c"]);
164
165    let search_bar = cx.workspace(|workspace, cx| {
166        workspace
167            .active_pane()
168            .read(cx)
169            .toolbar()
170            .read(cx)
171            .item_of_type::<BufferSearchBar>()
172            .expect("Buffer search bar should be deployed")
173    });
174
175    search_bar.read_with(cx.cx, |bar, cx| {
176        assert_eq!(bar.query_editor.read(cx).text(cx), "cc");
177    });
178
179    // wait for the query editor change event to fire.
180    search_bar.next_notification(&cx).await;
181
182    cx.update_editor(|editor, cx| {
183        let highlights = editor.all_background_highlights(cx);
184        assert_eq!(3, highlights.len());
185        assert_eq!(
186            DisplayPoint::new(2, 0)..DisplayPoint::new(2, 2),
187            highlights[0].0
188        )
189    });
190    cx.simulate_keystrokes(["enter"]);
191
192    cx.assert_state(indoc! {"aa\nbb\nˇcc\ncc\ncc\n"}, Mode::Normal);
193    cx.simulate_keystrokes(["n"]);
194    cx.assert_state(indoc! {"aa\nbb\ncc\nˇcc\ncc\n"}, Mode::Normal);
195    cx.simulate_keystrokes(["shift-n"]);
196    cx.assert_state(indoc! {"aa\nbb\nˇcc\ncc\ncc\n"}, Mode::Normal);
197}