Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/tests/test/movement.rs')
| -rw-r--r-- | helix-term/tests/test/movement.rs | 608 |
1 files changed, 61 insertions, 547 deletions
diff --git a/helix-term/tests/test/movement.rs b/helix-term/tests/test/movement.rs index 062d3796..fedf4b0e 100644 --- a/helix-term/tests/test/movement.rs +++ b/helix-term/tests/test/movement.rs @@ -8,7 +8,6 @@ async fn insert_mode_cursor_position() -> anyhow::Result<()> { in_keys: "i".into(), out_text: String::new(), out_selection: Selection::single(0, 0), - line_feed_handling: LineFeedHandling::AsIs, }) .await?; @@ -65,350 +64,6 @@ async fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> { Ok(()) } -#[tokio::test(flavor = "multi_thread")] -async fn surround_by_character() -> anyhow::Result<()> { - // Only pairs matching the passed character count - test(( - "(so [many {go#[o|]#d} text] here)", - "mi{", - "(so [many {#[good|]#} text] here)", - )) - .await?; - test(( - "(so [many {go#[o|]#d} text] here)", - "mi[", - "(so [#[many {good} text|]#] here)", - )) - .await?; - test(( - "(so [many {go#[o|]#d} text] here)", - "mi(", - "(#[so [many {good} text] here|]#)", - )) - .await?; - - // Works with characters that aren't pairs too - test(( - "'so 'many 'go#[o|]#d' text' here'", - "mi'", - "'so 'many '#[good|]#' text' here'", - )) - .await?; - test(( - "'so 'many 'go#[o|]#d' text' here'", - "2mi'", - "'so '#[many 'good' text|]#' here'", - )) - .await?; - test(( - "'so \"many 'go#[o|]#d' text\" here'", - "mi\"", - "'so \"#[many 'good' text|]#\" here'", - )) - .await?; - - // Selection direction is preserved - test(( - "(so [many {go#[|od]#} text] here)", - "mi{", - "(so [many {#[|good]#} text] here)", - )) - .await?; - - Ok(()) -} - -#[tokio::test(flavor = "multi_thread")] -async fn surround_inside_pair() -> anyhow::Result<()> { - // Works at first character of buffer - // TODO: Adjust test when opening pair failure is fixed - test(("#[(|]#something)", "mim", "#[(|]#something)")).await?; - - // Inside a valid pair selects pair - test(("some (#[t|]#ext) here", "mim", "some (#[text|]#) here")).await?; - - // On pair character selects pair - // TODO: Opening pair character is a known failure case that needs addressing - // test(("some #[(|]#text) here", "mim", "some (#[text|]#) here")).await?; - test(("some (text#[)|]# here", "mim", "some (#[text|]#) here")).await?; - - // No valid pair does nothing - test(("so#[m|]#e (text) here", "mim", "so#[m|]#e (text) here")).await?; - - // Count skips to outer pairs - test(( - "(so (many (go#[o|]#d) text) here)", - "1mim", - "(so (many (#[good|]#) text) here)", - )) - .await?; - test(( - "(so (many (go#[o|]#d) text) here)", - "2mim", - "(so (#[many (good) text|]#) here)", - )) - .await?; - test(( - "(so (many (go#[o|]#d) text) here)", - "3mim", - "(#[so (many (good) text) here|]#)", - )) - .await?; - - // Matching pairs outside selection don't match - test(( - "((so)((many) go#[o|]#d (text))(here))", - "mim", - "((so)(#[(many) good (text)|]#)(here))", - )) - .await?; - test(( - "((so)((many) go#[o|]#d (text))(here))", - "2mim", - "(#[(so)((many) good (text))(here)|]#)", - )) - .await?; - - // Works with mixed braces - test(( - "(so [many {go#[o|]#d} text] here)", - "mim", - "(so [many {#[good|]#} text] here)", - )) - .await?; - test(( - "(so [many {go#[o|]#d} text] here)", - "2mim", - "(so [#[many {good} text|]#] here)", - )) - .await?; - test(( - "(so [many {go#[o|]#d} text] here)", - "3mim", - "(#[so [many {good} text] here|]#)", - )) - .await?; - - // Selection direction is preserved - test(( - "(so [many {go#[|od]#} text] here)", - "mim", - "(so [many {#[|good]#} text] here)", - )) - .await?; - test(( - "(so [many {go#[|od]#} text] here)", - "2mim", - "(so [#[|many {good} text]#] here)", - )) - .await?; - test(( - "(so [many {go#[|od]#} text] here)", - "3mim", - "(#[|so [many {good} text] here]#)", - )) - .await?; - - // Only pairs outside of full selection range are considered - test(( - "(so (many (go#[od) |]#text) here)", - "mim", - "(so (#[many (good) text|]#) here)", - )) - .await?; - test(( - "(so (many#[ (go|]#od) text) here)", - "mim", - "(so (#[many (good) text|]#) here)", - )) - .await?; - test(( - "(so#[ (many (go|]#od) text) here)", - "mim", - "(#[so (many (good) text) here|]#)", - )) - .await?; - test(( - "(so (many (go#[od) text) |]#here)", - "mim", - "(#[so (many (good) text) here|]#)", - )) - .await?; - - // Works with multiple cursors - test(( - "(so (many (good) text) #[he|]#re\nso (many (good) text) #(|he)#re)", - "mim", - "(#[so (many (good) text) here\nso (many (good) text) here|]#)", - )) - .await?; - - Ok(()) -} - -#[tokio::test(flavor = "multi_thread")] -async fn surround_around_pair() -> anyhow::Result<()> { - // Works at first character of buffer - // TODO: Adjust test when opening pair failure is fixed - test(("#[(|]#something)", "mam", "#[(|]#something)")).await?; - - // Inside a valid pair selects pair - test(("some (#[t|]#ext) here", "mam", "some #[(text)|]# here")).await?; - - // On pair character selects pair - // TODO: Opening pair character is a known failure case that needs addressing - // test(("some #[(|]#text) here", "mam", "some #[(text)|]# here")).await?; - test(("some (text#[)|]# here", "mam", "some #[(text)|]# here")).await?; - - // No valid pair does nothing - test(("so#[m|]#e (text) here", "mam", "so#[m|]#e (text) here")).await?; - - // Count skips to outer pairs - test(( - "(so (many (go#[o|]#d) text) here)", - "1mam", - "(so (many #[(good)|]# text) here)", - )) - .await?; - test(( - "(so (many (go#[o|]#d) text) here)", - "2mam", - "(so #[(many (good) text)|]# here)", - )) - .await?; - test(( - "(so (many (go#[o|]#d) text) here)", - "3mam", - "#[(so (many (good) text) here)|]#", - )) - .await?; - - // Matching pairs outside selection don't match - test(( - "((so)((many) go#[o|]#d (text))(here))", - "mam", - "((so)#[((many) good (text))|]#(here))", - )) - .await?; - test(( - "((so)((many) go#[o|]#d (text))(here))", - "2mam", - "#[((so)((many) good (text))(here))|]#", - )) - .await?; - - // Works with mixed braces - test(( - "(so [many {go#[o|]#d} text] here)", - "mam", - "(so [many #[{good}|]# text] here)", - )) - .await?; - test(( - "(so [many {go#[o|]#d} text] here)", - "2mam", - "(so #[[many {good} text]|]# here)", - )) - .await?; - test(( - "(so [many {go#[o|]#d} text] here)", - "3mam", - "#[(so [many {good} text] here)|]#", - )) - .await?; - - // Selection direction is preserved - test(( - "(so [many {go#[|od]#} text] here)", - "mam", - "(so [many #[|{good}]# text] here)", - )) - .await?; - test(( - "(so [many {go#[|od]#} text] here)", - "2mam", - "(so #[|[many {good} text]]# here)", - )) - .await?; - test(( - "(so [many {go#[|od]#} text] here)", - "3mam", - "#[|(so [many {good} text] here)]#", - )) - .await?; - - // Only pairs outside of full selection range are considered - test(( - "(so (many (go#[od) |]#text) here)", - "mam", - "(so #[(many (good) text)|]# here)", - )) - .await?; - test(( - "(so (many#[ (go|]#od) text) here)", - "mam", - "(so #[(many (good) text)|]# here)", - )) - .await?; - test(( - "(so#[ (many (go|]#od) text) here)", - "mam", - "#[(so (many (good) text) here)|]#", - )) - .await?; - test(( - "(so (many (go#[od) text) |]#here)", - "mam", - "#[(so (many (good) text) here)|]#", - )) - .await?; - - // Works with multiple cursors - test(( - "(so (many (good) text) #[he|]#re\nso (many (good) text) #(|he)#re)", - "mam", - "#[(so (many (good) text) here\nso (many (good) text) here)|]#", - )) - .await?; - - Ok(()) -} - -#[tokio::test(flavor = "multi_thread")] -async fn match_around_closest_ts() -> anyhow::Result<()> { - test_with_config( - AppBuilder::new().with_file("foo.rs", None), - ( - r#"fn main() {testing!{"f#[|oo]#)"};}"#, - "mam", - r#"fn main() {testing!{#[|"foo)"]#};}"#, - ), - ) - .await?; - - test_with_config( - AppBuilder::new().with_file("foo.rs", None), - ( - r##"fn main() { let _ = ("#[|1]#23", "#(|1)#23"); } "##, - "3mam", - r##"fn main() #[|{ let _ = ("123", "123"); }]# "##, - ), - ) - .await?; - - test_with_config( - AppBuilder::new().with_file("foo.rs", None), - ( - r##" fn main() { let _ = ("12#[|3", "12]#3"); } "##, - "1mam", - r##" fn main() { let _ = #[|("123", "123")]#; } "##, - ), - ) - .await?; - - Ok(()) -} - /// Ensure the very initial cursor in an opened file is the width of /// the first grapheme #[tokio::test(flavor = "multi_thread")] @@ -435,11 +90,21 @@ async fn cursor_position_newly_opened_file() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread")] async fn cursor_position_append_eof() -> anyhow::Result<()> { - // Selection is forwards - test(("#[foo|]#", "abar<esc>", "#[foobar|]#\n")).await?; + // Selection is fowards + test(( + "#[foo|]#", + "abar<esc>", + helpers::platform_line("#[foobar|]#\n").as_ref(), + )) + .await?; // Selection is backwards - test(("#[|foo]#", "abar<esc>", "#[foobar|]#\n")).await?; + test(( + "#[|foo]#", + "abar<esc>", + helpers::platform_line("#[foobar|]#\n").as_ref(), + )) + .await?; Ok(()) } @@ -447,21 +112,28 @@ async fn cursor_position_append_eof() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread")] async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::Result<()> { test_with_config( - AppBuilder::new().with_file("foo.rs", None), + Args { + files: vec![(PathBuf::from("foo.rs"), Position::default())], + ..Default::default() + }, + Config::default(), + helpers::test_syntax_conf(None), ( - indoc! {"\ + helpers::platform_line(indoc! {"\ #[/|]#// Increments fn inc(x: usize) -> usize { x + 1 } /// Decrements fn dec(x: usize) -> usize { x - 1 } - "}, + "}) + .as_ref(), "]fv]f", - indoc! {"\ + helpers::platform_line(indoc! {"\ /// Increments #[fn inc(x: usize) -> usize { x + 1 } /// Decrements fn dec(x: usize) -> usize { x - 1 }|]# - "}, + "}) + .as_ref(), ), ) .await?; @@ -472,21 +144,28 @@ async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow:: #[tokio::test(flavor = "multi_thread")] async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Result<()> { test_with_config( - AppBuilder::new().with_file("foo.rs", None), + Args { + files: vec![(PathBuf::from("foo.rs"), Position::default())], + ..Default::default() + }, + Config::default(), + helpers::test_syntax_conf(None), ( - indoc! {"\ + helpers::platform_line(indoc! {"\ /// Increments #[fn inc(x: usize) -> usize { x + 1 } /// Decrements fn dec(x: usize) -> usize { x - 1 }|]# - "}, + "}) + .as_ref(), "v[f", - indoc! {"\ + helpers::platform_line(indoc! {"\ /// Increments #[fn inc(x: usize) -> usize { x + 1 }|]# /// Decrements fn dec(x: usize) -> usize { x - 1 } - "}, + "}) + .as_ref(), ), ) .await?; @@ -498,228 +177,63 @@ async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Res async fn select_mode_tree_sitter_prev_function_goes_backwards_to_object() -> anyhow::Result<()> { // Note: the anchor stays put and the head moves back. test_with_config( - AppBuilder::new().with_file("foo.rs", None), + Args { + files: vec![(PathBuf::from("foo.rs"), Position::default())], + ..Default::default() + }, + Config::default(), + helpers::test_syntax_conf(None), ( - indoc! {"\ + helpers::platform_line(indoc! {"\ /// Increments fn inc(x: usize) -> usize { x + 1 } /// Decrements fn dec(x: usize) -> usize { x - 1 } /// Identity #[fn ident(x: usize) -> usize { x }|]# - "}, + "}) + .as_ref(), "v[f", - indoc! {"\ + helpers::platform_line(indoc! {"\ /// Increments fn inc(x: usize) -> usize { x + 1 } /// Decrements #[|fn dec(x: usize) -> usize { x - 1 } /// Identity ]#fn ident(x: usize) -> usize { x } - "}, + "}) + .as_ref(), ), ) .await?; test_with_config( - AppBuilder::new().with_file("foo.rs", None), + Args { + files: vec![(PathBuf::from("foo.rs"), Position::default())], + ..Default::default() + }, + Config::default(), + helpers::test_syntax_conf(None), ( - indoc! {"\ + helpers::platform_line(indoc! {"\ /// Increments fn inc(x: usize) -> usize { x + 1 } /// Decrements fn dec(x: usize) -> usize { x - 1 } /// Identity #[fn ident(x: usize) -> usize { x }|]# - "}, + "}) + .as_ref(), "v[f[f", - indoc! {"\ + helpers::platform_line(indoc! {"\ /// Increments #[|fn inc(x: usize) -> usize { x + 1 } /// Decrements fn dec(x: usize) -> usize { x - 1 } /// Identity ]#fn ident(x: usize) -> usize { x } - "}, - ), - ) - .await?; - - Ok(()) -} - -#[tokio::test(flavor = "multi_thread")] -async fn find_char_line_ending() -> anyhow::Result<()> { - test(( - indoc! { - "\ - one - #[|t]#wo - three" - }, - "T<ret>gll2f<ret>", - indoc! { - "\ - one - two#[ - |]#three" - }, - )) - .await?; - - test(( - indoc! { - "\ - #[|o]#ne - two - three" - }, - "f<ret>2t<ret>ghT<ret>F<ret>", - indoc! { - "\ - one#[| - t]#wo - three" - }, - )) - .await?; - - Ok(()) -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_surround_replace() -> anyhow::Result<()> { - test(( - indoc! {"\ - (#[|a]#) - "}, - "mrm{", - indoc! {"\ - {#[|a]#} - "}, - )) - .await?; - - test(( - indoc! {"\ - (#[a|]#) - "}, - "mrm{", - indoc! {"\ - {#[a|]#} - "}, - )) - .await?; - - test(( - indoc! {"\ - {{ - - #(}|)# - #[}|]# - "}, - "mrm)", - indoc! {"\ - (( - - #()|)# - #[)|]# - "}, - )) - .await?; - - Ok(()) -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_surround_delete() -> anyhow::Result<()> { - test(( - indoc! {"\ - (#[|a]#) - "}, - "mdm", - indoc! {"\ - #[|a]# - "}, - )) - .await?; - - test(( - indoc! {"\ - (#[a|]#) - "}, - "mdm", - indoc! {"\ - #[a|]# - "}, - )) - .await?; - - test(( - indoc! {"\ - {{ - - #(}|)# - #[}|]# - "}, - "mdm", - "\n\n#(\n|)##[\n|]#", - )) - .await?; - - Ok(()) -} - -#[tokio::test(flavor = "multi_thread")] -async fn tree_sitter_motions_work_across_injections() -> anyhow::Result<()> { - test_with_config( - AppBuilder::new().with_file("foo.html", None), - ( - "<script>let #[|x]# = 1;</script>", - "<A-o>", - "<script>let #[|x = 1]#;</script>", - ), - ) - .await?; - - // When the full injected layer is selected, expand_selection jumps to - // a more shallow layer. - test_with_config( - AppBuilder::new().with_file("foo.html", None), - ( - "<script>#[|let x = 1;]#</script>", - "<A-o>", - "#[|<script>let x = 1;</script>]#", - ), - ) - .await?; - - test_with_config( - AppBuilder::new().with_file("foo.html", None), - ( - "<script>let #[|x = 1]#;</script>", - "<A-i>", - "<script>let #[|x]# = 1;</script>", - ), - ) - .await?; - - test_with_config( - AppBuilder::new().with_file("foo.html", None), - ( - "<script>let #[|x]# = 1;</script>", - "<A-n>", - "<script>let x #[=|]# 1;</script>", - ), - ) - .await?; - - test_with_config( - AppBuilder::new().with_file("foo.html", None), - ( - "<script>let #[|x]# = 1;</script>", - "<A-p>", - "<script>#[|let]# x = 1;</script>", + "}) + .as_ref(), ), ) .await?; |