Factor out line ending handling in integration tests (#9921)

Prior to this change, every integration test which wanted its line
endings to be handled transparently across platforms, i.e. test with
the same input that has its platform's line feed characters, converting
the line endings was up to each individual test by calling the
`platform_line` helper function. This significantly increases the amount
of boilerplate one has to copy between all the tests.

However, there are some test cases that need to exert strict control
over the exact input text without being manipulated behind the scenes by
the test framework.

So, with this change, the line feed conversions are factored into
the `TestCase` struct. By default, line endings of the input text
are converted to the platform's native line feed ending, but one can
explicitly specify in their test case when the input text should be left
alone and tested as is.
This commit is contained in:
Skyler Hawthorne 2024-03-31 08:12:17 -04:00 committed by GitHub
parent 2533b08f64
commit f5991657f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 564 additions and 478 deletions

View File

@ -6,13 +6,13 @@ async fn auto_indent_c() -> anyhow::Result<()> {
AppBuilder::new().with_file("foo.c", None),
// switches to append mode?
(
helpers::platform_line("void foo() {#[|}]#"),
"void foo() {#[|}]#",
"i<ret><esc>",
helpers::platform_line(indoc! {"\
indoc! {"\
void foo() {
#[|\n]#\
}
"}),
"},
),
)
.await?;

View File

@ -19,6 +19,7 @@ async fn insert_basic() -> anyhow::Result<()> {
format!("#[{}|]#", LINE_END),
format!("i{}", pair.0),
format!("{}#[|{}]#{}", pair.0, pair.1, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -46,6 +47,7 @@ async fn insert_configured_multi_byte_chars() -> anyhow::Result<()> {
format!("#[{}|]#", LINE_END),
format!("i{}", open),
format!("{}#[|{}]#{}", open, close, LINE_END),
LineFeedHandling::AsIs,
),
)
.await?;
@ -56,6 +58,7 @@ async fn insert_configured_multi_byte_chars() -> anyhow::Result<()> {
format!("{}#[{}|]#{}", open, close, LINE_END),
format!("i{}", close),
format!("{}{}#[|{}]#", open, close, LINE_END),
LineFeedHandling::AsIs,
),
)
.await?;
@ -71,6 +74,7 @@ async fn insert_after_word() -> anyhow::Result<()> {
format!("foo#[{}|]#", LINE_END),
format!("i{}", pair.0),
format!("foo{}#[|{}]#{}", pair.0, pair.1, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -80,6 +84,7 @@ async fn insert_after_word() -> anyhow::Result<()> {
format!("foo#[{}|]#", LINE_END),
format!("i{}", pair.0),
format!("foo{}#[|{}]#", pair.0, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -94,6 +99,7 @@ async fn insert_before_word() -> anyhow::Result<()> {
format!("#[f|]#oo{}", LINE_END),
format!("i{}", pair.0),
format!("{}#[|f]#oo{}", pair.0, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -108,6 +114,7 @@ async fn insert_before_word_selection() -> anyhow::Result<()> {
format!("#[foo|]#{}", LINE_END),
format!("i{}", pair.0),
format!("{}#[|foo]#{}", pair.0, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -122,6 +129,7 @@ async fn insert_before_word_selection_trailing_word() -> anyhow::Result<()> {
format!("foo#[ wor|]#{}", LINE_END),
format!("i{}", pair.0),
format!("foo{}#[|{} wor]#{}", pair.0, pair.1, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -136,6 +144,7 @@ async fn insert_closer_selection_trailing_word() -> anyhow::Result<()> {
format!("foo{}#[|{} wor]#{}", pair.0, pair.1, LINE_END),
format!("i{}", pair.1),
format!("foo{}{}#[| wor]#{}", pair.0, pair.1, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -155,6 +164,7 @@ async fn insert_before_eol() -> anyhow::Result<()> {
open = pair.0,
close = pair.1
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -177,6 +187,7 @@ async fn insert_auto_pairs_disabled() -> anyhow::Result<()> {
format!("#[{}|]#", LINE_END),
format!("i{}", pair.0),
format!("{}#[|{}]#", pair.0, LINE_END),
LineFeedHandling::AsIs,
),
)
.await?;
@ -197,6 +208,7 @@ async fn insert_multi_range() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -211,6 +223,7 @@ async fn insert_before_multi_code_point_graphemes() -> anyhow::Result<()> {
format!("hello #[👨‍👩‍👧‍👦|]# goodbye{}", LINE_END),
format!("i{}", pair.1),
format!("hello {}#[|👨‍👩‍👧‍👦]# goodbye{}", pair.1, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -226,6 +239,7 @@ async fn insert_at_end_of_document() -> anyhow::Result<()> {
in_keys: format!("i{}", pair.0),
out_text: format!("{}{}{}", LINE_END, pair.0, pair.1),
out_selection: Selection::single(LINE_END.len() + 1, LINE_END.len() + 2),
line_feed_handling: LineFeedHandling::AsIs,
})
.await?;
@ -235,6 +249,7 @@ async fn insert_at_end_of_document() -> anyhow::Result<()> {
in_keys: format!("i{}", pair.0),
out_text: format!("foo{}{}{}", LINE_END, pair.0, pair.1),
out_selection: Selection::single(LINE_END.len() + 4, LINE_END.len() + 5),
line_feed_handling: LineFeedHandling::AsIs,
})
.await?;
}
@ -259,6 +274,7 @@ async fn insert_close_inside_pair() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -283,6 +299,7 @@ async fn insert_close_inside_pair_multi() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -307,6 +324,7 @@ async fn insert_nested_open_inside_pair() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -338,6 +356,7 @@ async fn insert_nested_open_inside_pair_multi() -> anyhow::Result<()> {
inner_close = inner_pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -358,6 +377,7 @@ async fn append_basic() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -377,6 +397,7 @@ async fn append_multi_range() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -401,6 +422,7 @@ async fn append_close_inside_pair() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -425,6 +447,7 @@ async fn append_close_inside_pair_multi() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -444,6 +467,7 @@ async fn append_end_of_word() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -458,6 +482,7 @@ async fn append_middle_of_word() -> anyhow::Result<()> {
format!("#[wo|]#rd{}", LINE_END),
format!("a{}", pair.1),
format!("#[wo{}r|]#d{}", pair.1, LINE_END),
LineFeedHandling::AsIs,
))
.await?;
}
@ -477,6 +502,7 @@ async fn append_end_of_word_multi() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -501,6 +527,7 @@ async fn append_inside_nested_pair() -> anyhow::Result<()> {
close = pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}
@ -532,6 +559,7 @@ async fn append_inside_nested_pair_multi() -> anyhow::Result<()> {
inner_close = inner_pair.1,
eol = LINE_END
),
LineFeedHandling::AsIs,
))
.await?;
}

View File

@ -9,89 +9,89 @@
async fn test_selection_duplication() -> anyhow::Result<()> {
// Forward
test((
platform_line(indoc! {"\
indoc! {"\
#[lo|]#rem
ipsum
dolor
"}),
"},
"CC",
platform_line(indoc! {"\
indoc! {"\
#(lo|)#rem
#(ip|)#sum
#[do|]#lor
"}),
"},
))
.await?;
// Backward
test((
platform_line(indoc! {"\
indoc! {"\
#[|lo]#rem
ipsum
dolor
"}),
"},
"CC",
platform_line(indoc! {"\
indoc! {"\
#(|lo)#rem
#(|ip)#sum
#[|do]#lor
"}),
"},
))
.await?;
// Copy the selection to previous line, skipping the first line in the file
test((
platform_line(indoc! {"\
indoc! {"\
test
#[testitem|]#
"}),
"},
"<A-C>",
platform_line(indoc! {"\
indoc! {"\
test
#[testitem|]#
"}),
"},
))
.await?;
// Copy the selection to previous line, including the first line in the file
test((
platform_line(indoc! {"\
indoc! {"\
test
#[test|]#
"}),
"},
"<A-C>",
platform_line(indoc! {"\
indoc! {"\
#[test|]#
#(test|)#
"}),
"},
))
.await?;
// Copy the selection to next line, skipping the last line in the file
test((
platform_line(indoc! {"\
indoc! {"\
#[testitem|]#
test
"}),
"},
"C",
platform_line(indoc! {"\
indoc! {"\
#[testitem|]#
test
"}),
"},
))
.await?;
// Copy the selection to next line, including the last line in the file
test((
platform_line(indoc! {"\
indoc! {"\
#[test|]#
test
"}),
"},
"C",
platform_line(indoc! {"\
indoc! {"\
#(test|)#
#[test|]#
"}),
"},
))
.await?;
Ok(())
@ -159,17 +159,17 @@ fn match_paths(app: &Application, matches: Vec<&str>) -> usize {
#[tokio::test(flavor = "multi_thread")]
async fn test_multi_selection_paste() -> anyhow::Result<()> {
test((
platform_line(indoc! {"\
indoc! {"\
#[|lorem]#
#(|ipsum)#
#(|dolor)#
"}),
"},
"yp",
platform_line(indoc! {"\
indoc! {"\
lorem#[|lorem]#
ipsum#(|ipsum)#
dolor#(|dolor)#
"}),
"},
))
.await?;
@ -180,58 +180,58 @@ async fn test_multi_selection_paste() -> anyhow::Result<()> {
async fn test_multi_selection_shell_commands() -> anyhow::Result<()> {
// pipe
test((
platform_line(indoc! {"\
indoc! {"\
#[|lorem]#
#(|ipsum)#
#(|dolor)#
"}),
"},
"|echo foo<ret>",
platform_line(indoc! {"\
indoc! {"\
#[|foo\n]#
#(|foo\n)#
#(|foo\n)#
"}),
"},
))
.await?;
// insert-output
test((
platform_line(indoc! {"\
indoc! {"\
#[|lorem]#
#(|ipsum)#
#(|dolor)#
"}),
"},
"!echo foo<ret>",
platform_line(indoc! {"\
indoc! {"\
#[|foo\n]#
lorem
#(|foo\n)#
ipsum
#(|foo\n)#
dolor
"}),
"},
))
.await?;
// append-output
test((
platform_line(indoc! {"\
indoc! {"\
#[|lorem]#
#(|ipsum)#
#(|dolor)#
"}),
"},
"<A-!>echo foo<ret>",
platform_line(indoc! {"\
indoc! {"\
lorem#[|foo\n]#
ipsum#(|foo\n)#
dolor#(|foo\n)#
"}),
"},
))
.await?;
@ -247,7 +247,13 @@ async fn test_undo_redo() -> anyhow::Result<()> {
// * u Undo the two newlines. We're now on line 1.
// * <C-o><C-i> Jump forward an back again in the jumplist. This would panic
// if the jumplist were not being updated correctly.
test(("#[|]#", "2[<space><C-s>u<C-o><C-i>", "#[|]#")).await?;
test((
"#[|]#",
"2[<space><C-s>u<C-o><C-i>",
"#[|]#",
LineFeedHandling::AsIs,
))
.await?;
// A jumplist selection is passed through an edit and then an undo and then a redo.
//
@ -258,10 +264,22 @@ async fn test_undo_redo() -> anyhow::Result<()> {
// * <C-o> Jump back in the jumplist. This would panic if the jumplist were not being
// updated correctly.
// * <C-i> Jump forward to line 1.
test(("#[|]#", "[<space><C-s>kduU<C-o><C-i>", "#[|]#")).await?;
test((
"#[|]#",
"[<space><C-s>kduU<C-o><C-i>",
"#[|]#",
LineFeedHandling::AsIs,
))
.await?;
// In this case we 'redo' manually to ensure that the transactions are composing correctly.
test(("#[|]#", "[<space>u[<space>u", "#[|]#")).await?;
test((
"#[|]#",
"[<space>u[<space>u",
"#[|]#",
LineFeedHandling::AsIs,
))
.await?;
Ok(())
}
@ -270,35 +288,35 @@ async fn test_undo_redo() -> anyhow::Result<()> {
async fn test_extend_line() -> anyhow::Result<()> {
// extend with line selected then count
test((
platform_line(indoc! {"\
indoc! {"\
#[l|]#orem
ipsum
dolor
"}),
"},
"x2x",
platform_line(indoc! {"\
indoc! {"\
#[lorem
ipsum
dolor\n|]#
"}),
"},
))
.await?;
// extend with count on partial selection
test((
platform_line(indoc! {"\
indoc! {"\
#[l|]#orem
ipsum
"}),
"},
"2x",
platform_line(indoc! {"\
indoc! {"\
#[lorem
ipsum\n|]#
"}),
"},
))
.await?;
@ -366,16 +384,11 @@ async fn test_character_info() -> anyhow::Result<()> {
#[tokio::test(flavor = "multi_thread")]
async fn test_delete_char_backward() -> anyhow::Result<()> {
// don't panic when deleting overlapping ranges
test(("#(x|)# #[x|]#", "c<space><backspace><esc>", "#[\n|]#")).await?;
test((
platform_line("#(x|)# #[x|]#"),
"c<space><backspace><esc>",
platform_line("#[\n|]#"),
))
.await?;
test((
platform_line("#( |)##( |)#a#( |)#axx#[x|]#a"),
"#( |)##( |)#a#( |)#axx#[x|]#a",
"li<backspace><esc>",
platform_line("#(a|)##(|a)#xx#[|a]#"),
"#(a|)##(|a)#xx#[|a]#",
))
.await?;
@ -385,43 +398,33 @@ async fn test_delete_char_backward() -> anyhow::Result<()> {
#[tokio::test(flavor = "multi_thread")]
async fn test_delete_word_backward() -> anyhow::Result<()> {
// don't panic when deleting overlapping ranges
test((
platform_line("fo#[o|]#ba#(r|)#"),
"a<C-w><esc>",
platform_line("#[\n|]#"),
))
.await?;
test(("fo#[o|]#ba#(r|)#", "a<C-w><esc>", "#[\n|]#")).await?;
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_delete_word_forward() -> anyhow::Result<()> {
// don't panic when deleting overlapping ranges
test((
platform_line("fo#[o|]#b#(|ar)#"),
"i<A-d><esc>",
platform_line("fo#[\n|]#"),
))
.await?;
test(("fo#[o|]#b#(|ar)#", "i<A-d><esc>", "fo#[\n|]#")).await?;
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_delete_char_forward() -> anyhow::Result<()> {
test((
platform_line(indoc! {"\
indoc! {"\
#[abc|]#def
#(abc|)#ef
#(abc|)#f
#(abc|)#
"}),
"},
"a<del><esc>",
platform_line(indoc! {"\
indoc! {"\
#[abc|]#ef
#(abc|)#f
#(abc|)#
#(abc|)#
"}),
"},
))
.await?;
@ -430,33 +433,37 @@ async fn test_delete_char_forward() -> anyhow::Result<()> {
#[tokio::test(flavor = "multi_thread")]
async fn test_insert_with_indent() -> anyhow::Result<()> {
const INPUT: &str = "\
#[f|]#n foo() {
if let Some(_) = None {
const INPUT: &str = indoc! { "
#[f|]#n foo() {
if let Some(_) = None {
}
\x20
}
}
}
fn bar() {
fn bar() {
}";
}
"
};
// insert_at_line_start
test((
INPUT,
":lang rust<ret>%<A-s>I",
"\
#[f|]#n foo() {
#(i|)#f let Some(_) = None {
#(\n|)#\
\x20 #(}|)#
#(\x20|)#
#(}|)#
#(\n|)#\
#(f|)#n bar() {
#(\n|)#\
#(}|)#",
indoc! { "
#[f|]#n foo() {
#(i|)#f let Some(_) = None {
#(\n|)#
#(}|)#
#( |)#
#(}|)#
#(\n|)#
#(f|)#n bar() {
#(\n|)#
#(}|)#
"
},
))
.await?;
@ -464,17 +471,19 @@ fn bar() {
test((
INPUT,
":lang rust<ret>%<A-s>A",
"\
fn foo() {#[\n|]#\
\x20 if let Some(_) = None {#(\n|)#\
\x20 #(\n|)#\
\x20 }#(\n|)#\
\x20#(\n|)#\
}#(\n|)#\
#(\n|)#\
fn bar() {#(\n|)#\
\x20 #(\n|)#\
}#(|)#",
indoc! { "
fn foo() {#[\n|]#
if let Some(_) = None {#(\n|)#
#(\n|)#
}#(\n|)#
#(\n|)#
}#(\n|)#
#(\n|)#
fn bar() {#(\n|)#
#(\n|)#
}#(\n|)#
"
},
))
.await?;
@ -485,42 +494,42 @@ fn bar() {#(\n|)#\
async fn test_join_selections() -> anyhow::Result<()> {
// normal join
test((
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc
def
"}),
"},
"J",
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc def
"}),
"},
))
.await?;
// join with empty line
test((
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc
def
"}),
"},
"JJ",
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc def
"}),
"},
))
.await?;
// join with additional space in non-empty line
test((
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc
def
"}),
"},
"JJ",
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc def
"}),
"},
))
.await?;
@ -531,7 +540,7 @@ async fn test_join_selections() -> anyhow::Result<()> {
async fn test_join_selections_space() -> anyhow::Result<()> {
// join with empty lines panic
test((
platform_line(indoc! {"\
indoc! {"\
#[a
b
@ -541,69 +550,69 @@ async fn test_join_selections_space() -> anyhow::Result<()> {
d
e|]#
"}),
"},
"<A-J>",
platform_line(indoc! {"\
indoc! {"\
a#[ |]#b#( |)#c#( |)#d#( |)#e
"}),
"},
))
.await?;
// normal join
test((
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc
def
"}),
"},
"<A-J>",
platform_line(indoc! {"\
indoc! {"\
abc#[ |]#def
"}),
"},
))
.await?;
// join with empty line
test((
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc
def
"}),
"},
"<A-J>",
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc
def
"}),
"},
))
.await?;
// join with additional space in non-empty line
test((
platform_line(indoc! {"\
indoc! {"\
#[a|]#bc
def
"}),
"},
"<A-J><A-J>",
platform_line(indoc! {"\
indoc! {"\
abc#[ |]#def
"}),
"},
))
.await?;
// join with retained trailing spaces
test((
platform_line(indoc! {"\
indoc! {"\
#[aaa
bb
c |]#
"}),
"},
"<A-J>",
platform_line(indoc! {"\
indoc! {"\
aaa #[ |]#bb #( |)#c
"}),
"},
))
.await?;

View File

@ -6,7 +6,7 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
// single cursor stays single cursor, first goes to end of current
// node, then parent
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
fn foo() {
let result = if true {
"yes"
@ -14,9 +14,9 @@ fn foo() {
"no#["|]#
}
}
"##}),
"##},
"<A-e>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -24,10 +24,10 @@ fn foo() {
\"no\"#[\n|]#
}
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -35,9 +35,9 @@ fn foo() {
\"no\"#[\n|]#
}
}
"}),
"},
"<A-e>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -45,11 +45,11 @@ fn foo() {
\"no\"
}#[\n|]#
}
"}),
"},
),
// select mode extends
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
fn foo() {
let result = if true {
"yes"
@ -57,9 +57,9 @@ fn foo() {
#["no"|]#
}
}
"##}),
"##},
"v<A-e><A-e>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -67,7 +67,7 @@ fn foo() {
#[\"no\"
}\n|]#
}
"}),
"},
),
];
@ -84,7 +84,7 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
// single cursor stays single cursor, first goes to end of current
// node, then parent
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
fn foo() {
let result = if true {
"yes"
@ -92,9 +92,9 @@ fn foo() {
"no#["|]#
}
}
"##}),
"##},
"<A-b>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -102,10 +102,10 @@ fn foo() {
#[\"|]#no\"
}
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -113,9 +113,9 @@ fn foo() {
\"no\"#[\n|]#
}
}
"}),
"},
"<A-b>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -123,10 +123,10 @@ fn foo() {
\"no\"
}
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -134,9 +134,9 @@ fn foo() {
\"no\"
}
}
"}),
"},
"<A-b>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -144,11 +144,11 @@ fn foo() {
\"no\"
}
}
"}),
"},
),
// select mode extends
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
fn foo() {
let result = if true {
"yes"
@ -156,9 +156,9 @@ fn foo() {
#["no"|]#
}
}
"##}),
"##},
"v<A-b><A-b>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -166,10 +166,10 @@ fn foo() {
]#\"no\"
}
}
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
fn foo() {
let result = if true {
"yes"
@ -177,9 +177,9 @@ fn foo() {
#["no"|]#
}
}
"##}),
"##},
"v<A-b><A-b><A-b>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -187,7 +187,7 @@ fn foo() {
]#\"no\"
}
}
"}),
"},
),
];
@ -204,7 +204,7 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
// single cursor stays single cursor, first goes to end of current
// node, then parent
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
fn foo() {
let result = if true {
"yes"
@ -212,9 +212,9 @@ fn foo() {
"no#["|]#
}
}
"##}),
"##},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -222,10 +222,10 @@ fn foo() {
\"no\"#[|\n]#
}
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -233,9 +233,9 @@ fn foo() {
\"no\"#[\n|]#
}
}
"}),
"},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -243,12 +243,12 @@ fn foo() {
\"no\"
}#[|\n]#
}
"}),
"},
),
// appending to the end of a line should still look at the current
// line, not the next one
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -256,9 +256,9 @@ fn foo() {
\"no#[\"|]#
}
}
"}),
"},
"a<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -266,11 +266,11 @@ fn foo() {
\"no\"
}#[\n|]#
}
"}),
"},
),
// before cursor is all whitespace, so insert tab
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -278,9 +278,9 @@ fn foo() {
#[\"no\"|]#
}
}
"}),
"},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -288,12 +288,12 @@ fn foo() {
#[|\"no\"]#
}
}
"}),
"},
),
// if selection spans multiple lines, it should still only look at the
// line on which the head is
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"
@ -301,9 +301,9 @@ fn foo() {
\"no\"|]#
}
}
"}),
"},
"a<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -311,10 +311,10 @@ fn foo() {
\"no\"
}#[\n|]#
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"
@ -322,9 +322,9 @@ fn foo() {
\"no\"|]#
}
}
"}),
"},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[|\"yes\"
@ -332,10 +332,10 @@ fn foo() {
\"no\"]#
}
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
#[l|]#et result = if true {
#(\"yes\"
@ -343,9 +343,9 @@ fn foo() {
\"no\"|)#
}
}
"}),
"},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
#[|l]#et result = if true {
#(|\"yes\"
@ -353,10 +353,10 @@ fn foo() {
\"no\")#
}
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"#[\n|]#
@ -364,9 +364,9 @@ fn foo() {
\"no\"#(\n|)#
}
}
"}),
"},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -374,10 +374,10 @@ fn foo() {
\"no\"
}#(|\n)#
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"|]#
@ -385,9 +385,9 @@ fn foo() {
#(\"no\"|)#
}
}
"}),
"},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[|\"yes\"]#
@ -395,12 +395,12 @@ fn foo() {
#(|\"no\")#
}
}
"}),
"},
),
// if any cursors are not preceded by all whitespace, then do the
// smart_tab action
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"\n|]#
@ -408,9 +408,9 @@ fn foo() {
\"no#(\"\n|)#
}
}
"}),
"},
"i<tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@ -418,11 +418,11 @@ fn foo() {
\"no\"
}#(|\n)#
}
"}),
"},
),
// Ctrl-tab always inserts a tab
(
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"\n|]#
@ -430,9 +430,9 @@ fn foo() {
\"no#(\"\n|)#
}
}
"}),
"},
"i<S-tab>",
helpers::platform_line(indoc! {"\
indoc! {"\
fn foo() {
let result = if true {
#[|\"yes\"\n]#
@ -440,7 +440,7 @@ fn foo() {
\"no #(|\"\n)#
}
}
"}),
"},
),
];

View File

@ -94,7 +94,10 @@ async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
)
.await?;
helpers::assert_file_has_content(file.as_file_mut(), &platform_line(&RANGE.end().to_string()))?;
helpers::assert_file_has_content(
file.as_file_mut(),
&LineFeedHandling::Native.apply(&RANGE.end().to_string()),
)?;
Ok(())
}
@ -121,7 +124,7 @@ async fn test_write() -> anyhow::Result<()> {
file.as_file_mut().read_to_string(&mut file_content)?;
assert_eq!(
helpers::platform_line("the gostak distims the doshes"),
LineFeedHandling::Native.apply("the gostak distims the doshes"),
file_content
);
@ -138,7 +141,7 @@ async fn test_overwrite_protection() -> anyhow::Result<()> {
helpers::run_event_loop_until_idle(&mut app).await;
file.as_file_mut()
.write_all(helpers::platform_line("extremely important content").as_bytes())?;
.write_all("extremely important content".as_bytes())?;
file.as_file_mut().flush()?;
file.as_file_mut().sync_all()?;
@ -152,10 +155,7 @@ async fn test_overwrite_protection() -> anyhow::Result<()> {
let mut file_content = String::new();
file.as_file_mut().read_to_string(&mut file_content)?;
assert_eq!(
helpers::platform_line("extremely important content"),
file_content
);
assert_eq!("extremely important content", file_content);
Ok(())
}
@ -182,7 +182,7 @@ async fn test_write_quit() -> anyhow::Result<()> {
file.as_file_mut().read_to_string(&mut file_content)?;
assert_eq!(
helpers::platform_line("the gostak distims the doshes"),
LineFeedHandling::Native.apply("the gostak distims the doshes"),
file_content
);
@ -210,7 +210,10 @@ async fn test_write_concurrent() -> anyhow::Result<()> {
let mut file_content = String::new();
file.as_file_mut().read_to_string(&mut file_content)?;
assert_eq!(platform_line(&RANGE.end().to_string()), file_content);
assert_eq!(
LineFeedHandling::Native.apply(&RANGE.end().to_string()),
file_content
);
Ok(())
}
@ -276,7 +279,7 @@ async fn test_write_scratch_to_new_path() -> anyhow::Result<()> {
)
.await?;
helpers::assert_file_has_content(file.as_file_mut(), &helpers::platform_line("hello"))?;
helpers::assert_file_has_content(file.as_file_mut(), &LineFeedHandling::Native.apply("hello"))?;
Ok(())
}
@ -361,12 +364,12 @@ async fn test_write_new_path() -> anyhow::Result<()> {
helpers::assert_file_has_content(
file1.as_file_mut(),
&helpers::platform_line("i can eat glass, it will not hurt me\n"),
&LineFeedHandling::Native.apply("i can eat glass, it will not hurt me\n"),
)?;
helpers::assert_file_has_content(
file2.as_file_mut(),
&helpers::platform_line("i can eat glass, it will not hurt me\n"),
&LineFeedHandling::Native.apply("i can eat glass, it will not hurt me\n"),
)?;
Ok(())
@ -437,7 +440,7 @@ async fn test_write_insert_final_newline_added_if_missing() -> anyhow::Result<()
helpers::assert_file_has_content(
file.as_file_mut(),
&helpers::platform_line("have you tried chamomile tea?\n"),
&LineFeedHandling::Native.apply("have you tried chamomile tea?\n"),
)?;
Ok(())
@ -448,14 +451,14 @@ async fn test_write_insert_final_newline_unchanged_if_not_missing() -> anyhow::R
let mut file = tempfile::NamedTempFile::new()?;
let mut app = helpers::AppBuilder::new()
.with_file(file.path(), None)
.with_input_text(&helpers::platform_line("#[t|]#en minutes, please\n"))
.with_input_text(LineFeedHandling::Native.apply("#[t|]#en minutes, please\n"))
.build()?;
test_key_sequence(&mut app, Some(":w<ret>"), None, false).await?;
helpers::assert_file_has_content(
file.as_file_mut(),
&helpers::platform_line("ten minutes, please\n"),
&LineFeedHandling::Native.apply("ten minutes, please\n"),
)?;
Ok(())
@ -508,12 +511,12 @@ async fn test_write_all_insert_final_newline_add_if_missing_and_modified() -> an
helpers::assert_file_has_content(
file1.as_file_mut(),
&helpers::platform_line("we don't serve time travelers here\n"),
&LineFeedHandling::Native.apply("we don't serve time travelers here\n"),
)?;
helpers::assert_file_has_content(
file2.as_file_mut(),
&helpers::platform_line("a time traveler walks into a bar\n"),
&LineFeedHandling::Native.apply("a time traveler walks into a bar\n"),
)?;
Ok(())

View File

@ -14,6 +14,46 @@
use tempfile::NamedTempFile;
use tokio_stream::wrappers::UnboundedReceiverStream;
/// Specify how to set up the input text with line feeds
#[derive(Clone, Debug)]
pub enum LineFeedHandling {
/// Replaces all LF chars with the system's appropriate line feed character,
/// and if one doesn't exist already, appends the system's appropriate line
/// ending to the end of a string.
Native,
/// Do not modify the input text in any way. What you give is what you test.
AsIs,
}
impl LineFeedHandling {
/// Apply the line feed handling to the input string, yielding a set of
/// resulting texts with the appropriate line feed substitutions.
pub fn apply(&self, text: &str) -> String {
let line_end = match self {
LineFeedHandling::Native => helix_core::NATIVE_LINE_ENDING,
LineFeedHandling::AsIs => return text.into(),
}
.as_str();
// we can assume that the source files in this code base will always
// be LF, so indoc strings will always insert LF
let mut output = text.replace('\n', line_end);
if !output.ends_with(line_end) {
output.push_str(line_end);
}
output
}
}
impl Default for LineFeedHandling {
fn default() -> Self {
Self::Native
}
}
#[derive(Clone, Debug)]
pub struct TestCase {
pub in_text: String,
@ -21,6 +61,8 @@ pub struct TestCase {
pub in_keys: String,
pub out_text: String,
pub out_selection: Selection,
pub line_feed_handling: LineFeedHandling,
}
impl<S, R, V> From<(S, R, V)> for TestCase
@ -30,8 +72,19 @@ impl<S, R, V> From<(S, R, V)> for TestCase
V: Into<String>,
{
fn from((input, keys, output): (S, R, V)) -> Self {
let (in_text, in_selection) = test::print(&input.into());
let (out_text, out_selection) = test::print(&output.into());
TestCase::from((input, keys, output, LineFeedHandling::default()))
}
}
impl<S, R, V> From<(S, R, V, LineFeedHandling)> for TestCase
where
S: Into<String>,
R: Into<String>,
V: Into<String>,
{
fn from((input, keys, output, line_feed_handling): (S, R, V, LineFeedHandling)) -> Self {
let (in_text, in_selection) = test::print(&line_feed_handling.apply(&input.into()));
let (out_text, out_selection) = test::print(&line_feed_handling.apply(&output.into()));
TestCase {
in_text,
@ -39,6 +92,7 @@ fn from((input, keys, output): (S, R, V)) -> Self {
in_keys: keys.into(),
out_text,
out_selection,
line_feed_handling,
}
}
}
@ -137,6 +191,7 @@ pub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(
should_exit: bool,
) -> anyhow::Result<()> {
let test_case = test_case.into();
let mut app = match app {
Some(app) => app,
None => Application::new(Args::default(), test_config(), test_syntax_loader(None))?,
@ -240,23 +295,6 @@ pub fn test_editor_config() -> helix_view::editor::Config {
}
}
/// Replaces all LF chars with the system's appropriate line feed
/// character, and if one doesn't exist already, appends the system's
/// appropriate line ending to the end of a string.
pub fn platform_line(input: &str) -> String {
let line_end = helix_core::NATIVE_LINE_ENDING.as_str();
// we can assume that the source files in this code base will always
// be LF, so indoc strings will always insert LF
let mut output = input.replace('\n', line_end);
if !output.ends_with(line_end) {
output.push_str(line_end);
}
output
}
/// Creates a new temporary file that is set to read only. Useful for
/// testing write failures.
pub fn new_readonly_tempfile() -> anyhow::Result<NamedTempFile> {

View File

@ -6,30 +6,30 @@ async fn auto_indent() -> anyhow::Result<()> {
let enter_tests = [
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
type Test struct {#[}|]#
"##}),
"##},
"i<ret>",
helpers::platform_line(indoc! {"\
indoc! {"\
type Test struct {
\t#[|\n]#
}
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
func main() {
\tswitch nil {#[}|]#
}
"}),
"},
"i<ret>",
helpers::platform_line(indoc! {"\
indoc! {"\
func main() {
\tswitch nil {
\t\t#[|\n]#
\t}
}
"}),
"},
),
];

View File

@ -6,7 +6,7 @@ async fn auto_indent() -> anyhow::Result<()> {
let below_tests = [
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
#[t|]#op:
baz: foo
bazi:
@ -17,9 +17,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
#[\n|]#
baz: foo
@ -31,10 +31,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
b#[a|]#z: foo
bazi:
@ -45,9 +45,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
#[\n|]#
@ -59,10 +59,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
baz: foo
bazi#[:|]#
@ -73,9 +73,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -87,10 +87,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
baz: foo
bazi:
@ -101,9 +101,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -115,10 +115,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
baz: foo
bazi:
@ -129,9 +129,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -143,10 +143,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -157,9 +157,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -171,10 +171,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -185,9 +185,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -199,10 +199,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -213,9 +213,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:#[\n|]#
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -227,10 +227,10 @@ async fn auto_indent() -> anyhow::Result<()> {
bax: foox
fook:
#[\n|]#
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: |
@ -239,9 +239,9 @@ async fn auto_indent() -> anyhow::Result<()> {
line
string#[\n|]#
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: |
@ -251,10 +251,10 @@ async fn auto_indent() -> anyhow::Result<()> {
string
#[\n|]#
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >
@ -263,9 +263,9 @@ async fn auto_indent() -> anyhow::Result<()> {
line#[\n|]#
string
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >
@ -275,74 +275,74 @@ async fn auto_indent() -> anyhow::Result<()> {
#[\n|]#
string
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >#[\n|]#
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >
#[\n|]#
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
- top:#[\n|]#
baz: foo
bax: foox
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
#[\n|]#
baz: foo
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
baz: foo#[\n|]#
bax: foox
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
baz: foo
#[\n|]#
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
baz: foo
bax: foox#[\n|]#
fook:
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
baz: foo
bax: foox
#[\n|]#
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz:
- one: two#[\n|]#
@ -350,9 +350,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- top:
baz: foo
bax: foox
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz:
- one: two
@ -361,42 +361,42 @@ async fn auto_indent() -> anyhow::Result<()> {
- top:
baz: foo
bax: foox
"}),
"},
),
// yaml map without a key
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:#[\n|]#
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
#[\n|]#
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top#[:|]#
bottom: withvalue
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
#[\n|]#
bottom: withvalue
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
bottom: withvalue
top#[:|]#
"}),
"},
"o",
helpers::platform_line(indoc! {"\
indoc! {"\
bottom: withvalue
top:
#[\n|]#
"}),
"},
),
];
@ -406,7 +406,7 @@ async fn auto_indent() -> anyhow::Result<()> {
let above_tests = [
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
#[t|]#op:
baz: foo
bazi:
@ -417,9 +417,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
#[\n|]#
top:
baz: foo
@ -431,10 +431,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
b#[a|]#z: foo
bazi:
@ -445,9 +445,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
#[\n|]#
baz: foo
@ -459,10 +459,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
baz: foo
bazi#[:|]#
@ -473,9 +473,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
#[\n|]#
@ -487,10 +487,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
baz: foo
bazi:
@ -501,9 +501,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -515,10 +515,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
top:
baz: foo
bazi:
@ -529,9 +529,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"##}),
"##},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -543,10 +543,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -557,9 +557,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -571,10 +571,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -585,9 +585,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -599,10 +599,10 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -613,9 +613,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- 2
bax: foox
fook:#[\n|]#
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bazi:
@ -627,10 +627,10 @@ async fn auto_indent() -> anyhow::Result<()> {
bax: foox
#[\n|]#
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: |
@ -639,9 +639,9 @@ async fn auto_indent() -> anyhow::Result<()> {
line
string#[\n|]#
fook:
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: |
@ -651,10 +651,10 @@ async fn auto_indent() -> anyhow::Result<()> {
#[\n|]#
string
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >
@ -663,9 +663,9 @@ async fn auto_indent() -> anyhow::Result<()> {
line
string
fook:
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >
@ -675,58 +675,58 @@ async fn auto_indent() -> anyhow::Result<()> {
line
string
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >
fook:#[\n|]#
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz: foo
bax: >
#[\n|]#
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
baz: foo#[\n|]#
bax: foox
fook:
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
#[\n|]#
baz: foo
bax: foox
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
baz: foo
bax: foox
fook:#[\n|]#
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
- top:
baz: foo
bax: foox
#[\n|]#
fook:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz:
- one: two#[\n|]#
@ -734,9 +734,9 @@ async fn auto_indent() -> anyhow::Result<()> {
- top:
baz: foo
bax: foox
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
baz:
#[\n|]#
@ -745,42 +745,42 @@ async fn auto_indent() -> anyhow::Result<()> {
- top:
baz: foo
bax: foox
"}),
"},
),
// yaml map without a key
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:#[\n|]#
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
#[\n|]#
top:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
bottom: withvalue
top#[:|]#
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
bottom: withvalue
#[\n|]#
top:
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
top:
bottom:#[ |]#withvalue
"}),
"},
"O",
helpers::platform_line(indoc! {"\
indoc! {"\
top:
#[\n|]#
bottom: withvalue
"}),
"},
),
];
@ -790,24 +790,24 @@ async fn auto_indent() -> anyhow::Result<()> {
let enter_tests = [
(
helpers::platform_line(indoc! {r##"
indoc! {r##"
foo: #[b|]#ar
"##}),
"##},
"i<ret>",
helpers::platform_line(indoc! {"\
indoc! {"\
foo:
#[|b]#ar
"}),
"},
),
(
helpers::platform_line(indoc! {"\
indoc! {"\
foo:#[\n|]#
"}),
"},
"i<ret>",
helpers::platform_line(indoc! {"\
indoc! {"\
foo:
#[|\n]#
"}),
"},
),
];

View File

@ -8,6 +8,7 @@ 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?;
@ -392,20 +393,10 @@ 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>",
helpers::platform_line("#[foobar|]#\n"),
))
.await?;
test(("#[foo|]#", "abar<esc>", "#[foobar|]#\n")).await?;
// Selection is backwards
test((
"#[|foo]#",
"abar<esc>",
helpers::platform_line("#[foobar|]#\n"),
))
.await?;
test(("#[|foo]#", "abar<esc>", "#[foobar|]#\n")).await?;
Ok(())
}
@ -415,19 +406,19 @@ async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::
test_with_config(
AppBuilder::new().with_file("foo.rs", None),
(
helpers::platform_line(indoc! {"\
indoc! {"\
#[/|]#// Increments
fn inc(x: usize) -> usize { x + 1 }
/// Decrements
fn dec(x: usize) -> usize { x - 1 }
"}),
"},
"]fv]f",
helpers::platform_line(indoc! {"\
indoc! {"\
/// Increments
#[fn inc(x: usize) -> usize { x + 1 }
/// Decrements
fn dec(x: usize) -> usize { x - 1 }|]#
"}),
"},
),
)
.await?;
@ -440,19 +431,19 @@ async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Res
test_with_config(
AppBuilder::new().with_file("foo.rs", None),
(
helpers::platform_line(indoc! {"\
indoc! {"\
/// Increments
#[fn inc(x: usize) -> usize { x + 1 }
/// Decrements
fn dec(x: usize) -> usize { x - 1 }|]#
"}),
"},
"v[f",
helpers::platform_line(indoc! {"\
indoc! {"\
/// Increments
#[fn inc(x: usize) -> usize { x + 1 }|]#
/// Decrements
fn dec(x: usize) -> usize { x - 1 }
"}),
"},
),
)
.await?;
@ -466,23 +457,23 @@ async fn select_mode_tree_sitter_prev_function_goes_backwards_to_object() -> any
test_with_config(
AppBuilder::new().with_file("foo.rs", None),
(
helpers::platform_line(indoc! {"\
indoc! {"\
/// Increments
fn inc(x: usize) -> usize { x + 1 }
/// Decrements
fn dec(x: usize) -> usize { x - 1 }
/// Identity
#[fn ident(x: usize) -> usize { x }|]#
"}),
"},
"v[f",
helpers::platform_line(indoc! {"\
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?;
@ -490,23 +481,23 @@ fn inc(x: usize) -> usize { x + 1 }
test_with_config(
AppBuilder::new().with_file("foo.rs", None),
(
helpers::platform_line(indoc! {"\
indoc! {"\
/// Increments
fn inc(x: usize) -> usize { x + 1 }
/// Decrements
fn dec(x: usize) -> usize { x - 1 }
/// Identity
#[fn ident(x: usize) -> usize { x }|]#
"}),
"},
"v[f[f",
helpers::platform_line(indoc! {"\
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?;
@ -517,36 +508,36 @@ fn dec(x: usize) -> usize { x - 1 }
#[tokio::test(flavor = "multi_thread")]
async fn find_char_line_ending() -> anyhow::Result<()> {
test((
helpers::platform_line(indoc! {
indoc! {
"\
one
#[|t]#wo
three"
}),
},
"T<ret>gll2f<ret>",
helpers::platform_line(indoc! {
indoc! {
"\
one
two#[
|]#three"
}),
},
))
.await?;
test((
helpers::platform_line(indoc! {
indoc! {
"\
#[|o]#ne
two
three"
}),
},
"f<ret>2t<ret>ghT<ret>F<ret>",
helpers::platform_line(indoc! {
indoc! {
"\
one#[|
t]#wo
three"
}),
},
))
.await?;
@ -556,41 +547,41 @@ async fn find_char_line_ending() -> anyhow::Result<()> {
#[tokio::test(flavor = "multi_thread")]
async fn test_surround_replace() -> anyhow::Result<()> {
test((
platform_line(indoc! {"\
indoc! {"\
(#[|a]#)
"}),
"},
"mrm{",
platform_line(indoc! {"\
indoc! {"\
{#[|a]#}
"}),
"},
))
.await?;
test((
platform_line(indoc! {"\
indoc! {"\
(#[a|]#)
"}),
"},
"mrm{",
platform_line(indoc! {"\
indoc! {"\
{#[a|]#}
"}),
"},
))
.await?;
test((
platform_line(indoc! {"\
indoc! {"\
{{
#(}|)#
#[}|]#
"}),
"},
"mrm)",
platform_line(indoc! {"\
indoc! {"\
((
#()|)#
#[)|]#
"}),
"},
))
.await?;
@ -600,36 +591,36 @@ async fn test_surround_replace() -> anyhow::Result<()> {
#[tokio::test(flavor = "multi_thread")]
async fn test_surround_delete() -> anyhow::Result<()> {
test((
platform_line(indoc! {"\
indoc! {"\
(#[|a]#)
"}),
"},
"mdm",
platform_line(indoc! {"\
indoc! {"\
#[|a]#
"}),
"},
))
.await?;
test((
platform_line(indoc! {"\
indoc! {"\
(#[a|]#)
"}),
"},
"mdm",
platform_line(indoc! {"\
indoc! {"\
#[a|]#
"}),
"},
))
.await?;
test((
platform_line(indoc! {"\
indoc! {"\
{{
#(}|)#
#[}|]#
"}),
"},
"mdm",
platform_line("\n\n#(\n|)##[\n|]#"),
"\n\n#(\n|)##[\n|]#",
))
.await?;

View File

@ -62,9 +62,18 @@ async fn test_split_write_quit_all() -> anyhow::Result<()> {
)
.await?;
helpers::assert_file_has_content(file1.as_file_mut(), &platform_line("hello1"))?;
helpers::assert_file_has_content(file2.as_file_mut(), &platform_line("hello2"))?;
helpers::assert_file_has_content(file3.as_file_mut(), &platform_line("hello3"))?;
helpers::assert_file_has_content(
file1.as_file_mut(),
&LineFeedHandling::Native.apply("hello1"),
)?;
helpers::assert_file_has_content(
file2.as_file_mut(),
&LineFeedHandling::Native.apply("hello2"),
)?;
helpers::assert_file_has_content(
file3.as_file_mut(),
&LineFeedHandling::Native.apply("hello3"),
)?;
Ok(())
}
@ -91,7 +100,7 @@ async fn test_split_write_quit_same_file() -> anyhow::Result<()> {
let doc = docs.pop().unwrap();
assert_eq!(
helpers::platform_line("hello\ngoodbye"),
LineFeedHandling::Native.apply("hello\ngoodbye"),
doc.text().to_string()
);
@ -110,7 +119,7 @@ async fn test_split_write_quit_same_file() -> anyhow::Result<()> {
let doc = docs.pop().unwrap();
assert_eq!(
helpers::platform_line("hello\ngoodbye"),
LineFeedHandling::Native.apply("hello\ngoodbye"),
doc.text().to_string()
);
@ -124,7 +133,7 @@ async fn test_split_write_quit_same_file() -> anyhow::Result<()> {
helpers::assert_file_has_content(
file.as_file_mut(),
&helpers::platform_line("hello\ngoodbye"),
&LineFeedHandling::Native.apply("hello\ngoodbye"),
)?;
Ok(())
@ -151,7 +160,13 @@ async fn test_changes_in_splits_apply_to_all_views() -> anyhow::Result<()> {
//
// This panicked in the past because the jumplist entry on line 2 of window 2
// was not updated and after the `kd` step, pointed outside of the document.
test(("#[|]#", "<C-w>v[<space><C-s><C-w>wkd<C-w>qd", "#[|]#")).await?;
test((
"#[|]#",
"<C-w>v[<space><C-s><C-w>wkd<C-w>qd",
"#[|]#",
LineFeedHandling::AsIs,
))
.await?;
// Transactions are applied to the views for windows lazily when they are focused.
// This case panics if the transactions and inversions are not applied in the
@ -160,6 +175,7 @@ async fn test_changes_in_splits_apply_to_all_views() -> anyhow::Result<()> {
"#[|]#",
"[<space>[<space>[<space><C-w>vuuu<C-w>wUUU<C-w>quuu",
"#[|]#",
LineFeedHandling::AsIs,
))
.await?;
@ -185,6 +201,7 @@ async fn test_changes_in_splits_apply_to_all_views() -> anyhow::Result<()> {
"#[|]#",
"3[<space><C-w>v<C-s><C-w>wuu3[<space><C-w>q%d",
"#[|]#",
LineFeedHandling::AsIs,
))
.await?;

View File

@ -46,8 +46,8 @@ pub fn get_diff_base(&self, file: &Path) -> Option<Vec<u8>> {
.find_map(|provider| match provider.get_diff_base(file) {
Ok(res) => Some(res),
Err(err) => {
log::info!("{err:#?}");
log::info!("failed to open diff base for {}", file.display());
log::debug!("{err:#?}");
log::debug!("failed to open diff base for {}", file.display());
None
}
})
@ -59,8 +59,8 @@ pub fn get_current_head_name(&self, file: &Path) -> Option<Arc<ArcSwap<Box<str>>
.find_map(|provider| match provider.get_current_head_name(file) {
Ok(res) => Some(res),
Err(err) => {
log::info!("{err:#?}");
log::info!("failed to obtain current head name for {}", file.display());
log::debug!("{err:#?}");
log::debug!("failed to obtain current head name for {}", file.display());
None
}
})