From f486f34ebe0e21f0e109e24037e73182b2cf510a Mon Sep 17 00:00:00 2001 From: Skyler Hawthorne Date: Fri, 21 Oct 2022 00:28:29 -0400 Subject: [PATCH] flush writes on force quit (#4397) When force quitting, we need to block on the pending writes to ensure that write commands succeed before exiting, and also to avoid a crash when all the views are gone before the auto format call returns from the LS. --- helix-term/src/commands/typed.rs | 1 + helix-term/tests/integration.rs | 2 +- helix-term/tests/test/auto_indent.rs | 2 +- helix-term/tests/test/auto_pairs.rs | 50 ++++++++++++++-------------- helix-term/tests/test/commands.rs | 2 +- helix-term/tests/test/movement.rs | 14 ++++---- helix-term/tests/test/prompt.rs | 2 +- helix-term/tests/test/write.rs | 14 ++++---- 8 files changed, 44 insertions(+), 43 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index f154fd389..394c07339 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -51,6 +51,7 @@ fn force_quit( ensure!(args.is_empty(), ":quit! takes no arguments"); + cx.block_try_flush_writes()?; cx.editor.close(view!(cx.editor).id); Ok(()) diff --git a/helix-term/tests/integration.rs b/helix-term/tests/integration.rs index e3754c436..a378af7a9 100644 --- a/helix-term/tests/integration.rs +++ b/helix-term/tests/integration.rs @@ -11,7 +11,7 @@ mod test { use self::helpers::*; - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn hello_world() -> anyhow::Result<()> { test(("#[\n|]#", "ihello world", "hello world#[|\n]#")).await?; Ok(()) diff --git a/helix-term/tests/test/auto_indent.rs b/helix-term/tests/test/auto_indent.rs index 5c093a5db..d5c220b7a 100644 --- a/helix-term/tests/test/auto_indent.rs +++ b/helix-term/tests/test/auto_indent.rs @@ -1,6 +1,6 @@ use super::*; -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn auto_indent_c() -> anyhow::Result<()> { test_with_config( Args { diff --git a/helix-term/tests/test/auto_pairs.rs b/helix-term/tests/test/auto_pairs.rs index f2ab49c7f..e18c71195 100644 --- a/helix-term/tests/test/auto_pairs.rs +++ b/helix-term/tests/test/auto_pairs.rs @@ -12,7 +12,7 @@ fn matching_pairs() -> impl Iterator { DEFAULT_PAIRS.iter().filter(|(open, close)| open == close) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_basic() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -26,7 +26,7 @@ async fn insert_basic() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_configured_multi_byte_chars() -> anyhow::Result<()> { // NOTE: these are multi-byte Unicode characters let pairs = hashmap!('„' => '“', '‚' => '‘', '「' => '」'); @@ -68,7 +68,7 @@ async fn insert_configured_multi_byte_chars() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_after_word() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -91,7 +91,7 @@ async fn insert_after_word() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_before_word() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -105,7 +105,7 @@ async fn insert_before_word() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_before_word_selection() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -119,7 +119,7 @@ async fn insert_before_word_selection() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_before_word_selection_trailing_word() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -133,7 +133,7 @@ async fn insert_before_word_selection_trailing_word() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_closer_selection_trailing_word() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -147,7 +147,7 @@ async fn insert_closer_selection_trailing_word() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_before_eol() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -166,7 +166,7 @@ async fn insert_before_eol() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_auto_pairs_disabled() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test_with_config( @@ -191,7 +191,7 @@ async fn insert_auto_pairs_disabled() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_multi_range() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -210,7 +210,7 @@ async fn insert_multi_range() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_before_multi_code_point_graphemes() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -223,7 +223,7 @@ async fn insert_before_multi_code_point_graphemes() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_at_end_of_document() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(TestCase { @@ -248,7 +248,7 @@ async fn insert_at_end_of_document() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_close_inside_pair() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -272,7 +272,7 @@ async fn insert_close_inside_pair() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_close_inside_pair_multi() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -296,7 +296,7 @@ async fn insert_close_inside_pair_multi() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_nested_open_inside_pair() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -320,7 +320,7 @@ async fn insert_nested_open_inside_pair() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_nested_open_inside_pair_multi() -> anyhow::Result<()> { for outer_pair in DEFAULT_PAIRS { for inner_pair in DEFAULT_PAIRS { @@ -352,7 +352,7 @@ async fn insert_nested_open_inside_pair_multi() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_basic() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -371,7 +371,7 @@ async fn append_basic() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_multi_range() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -390,7 +390,7 @@ async fn append_multi_range() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_close_inside_pair() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -414,7 +414,7 @@ async fn append_close_inside_pair() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_close_inside_pair_multi() -> anyhow::Result<()> { for pair in DEFAULT_PAIRS { test(( @@ -438,7 +438,7 @@ async fn append_close_inside_pair_multi() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_end_of_word() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -457,7 +457,7 @@ async fn append_end_of_word() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_middle_of_word() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -471,7 +471,7 @@ async fn append_middle_of_word() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_end_of_word_multi() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -490,7 +490,7 @@ async fn append_end_of_word_multi() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_inside_nested_pair() -> anyhow::Result<()> { for pair in differing_pairs() { test(( @@ -514,7 +514,7 @@ async fn append_inside_nested_pair() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn append_inside_nested_pair_multi() -> anyhow::Result<()> { for outer_pair in DEFAULT_PAIRS { for inner_pair in DEFAULT_PAIRS { diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs index 5238cc69b..e24ee3e08 100644 --- a/helix-term/tests/test/commands.rs +++ b/helix-term/tests/test/commands.rs @@ -94,7 +94,7 @@ async fn test_buffer_close_concurrent() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_selection_duplication() -> anyhow::Result<()> { // Forward test(( diff --git a/helix-term/tests/test/movement.rs b/helix-term/tests/test/movement.rs index 81c66e534..fedf4b0e6 100644 --- a/helix-term/tests/test/movement.rs +++ b/helix-term/tests/test/movement.rs @@ -1,6 +1,6 @@ use super::*; -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_mode_cursor_position() -> anyhow::Result<()> { test(TestCase { in_text: String::new(), @@ -19,7 +19,7 @@ async fn insert_mode_cursor_position() -> anyhow::Result<()> { } /// Range direction is preserved when escaping insert mode to normal -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> { test(("#[f|]#oo\n", "vll", "#[|foo]#\n")).await?; test(( @@ -66,7 +66,7 @@ async fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> { /// Ensure the very initial cursor in an opened file is the width of /// the first grapheme -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn cursor_position_newly_opened_file() -> anyhow::Result<()> { let test = |content: &str, expected_sel: Selection| -> anyhow::Result<()> { let file = helpers::temp_file_with_contents(content)?; @@ -88,7 +88,7 @@ async fn cursor_position_newly_opened_file() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn cursor_position_append_eof() -> anyhow::Result<()> { // Selection is fowards test(( @@ -109,7 +109,7 @@ async fn cursor_position_append_eof() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::Result<()> { test_with_config( Args { @@ -141,7 +141,7 @@ async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow:: Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Result<()> { test_with_config( Args { @@ -173,7 +173,7 @@ async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Res Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] 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( diff --git a/helix-term/tests/test/prompt.rs b/helix-term/tests/test/prompt.rs index 62ec03f1b..4f3bf7632 100644 --- a/helix-term/tests/test/prompt.rs +++ b/helix-term/tests/test/prompt.rs @@ -1,6 +1,6 @@ use super::*; -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_history_completion() -> anyhow::Result<()> { test_key_sequence( &mut AppBuilder::new().build()?, diff --git a/helix-term/tests/test/write.rs b/helix-term/tests/test/write.rs index 6aa51a315..d0128edca 100644 --- a/helix-term/tests/test/write.rs +++ b/helix-term/tests/test/write.rs @@ -8,7 +8,7 @@ use helix_view::doc; use super::*; -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_write() -> anyhow::Result<()> { let mut file = tempfile::NamedTempFile::new()?; let mut app = helpers::AppBuilder::new() @@ -92,7 +92,7 @@ async fn test_write_concurrent() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_write_fail_mod_flag() -> anyhow::Result<()> { let file = helpers::new_readonly_tempfile()?; let mut app = helpers::AppBuilder::new() @@ -133,7 +133,7 @@ async fn test_write_fail_mod_flag() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_write_scratch_to_new_path() -> anyhow::Result<()> { let mut file = tempfile::NamedTempFile::new()?; @@ -158,7 +158,7 @@ async fn test_write_scratch_to_new_path() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_write_scratch_no_path_fails() -> anyhow::Result<()> { helpers::test_key_sequence_with_input_text( None, @@ -179,7 +179,7 @@ async fn test_write_scratch_no_path_fails() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_write_auto_format_fails_still_writes() -> anyhow::Result<()> { let mut file = tempfile::Builder::new().suffix(".rs").tempfile()?; @@ -203,7 +203,7 @@ async fn test_write_auto_format_fails_still_writes() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_write_new_path() -> anyhow::Result<()> { let mut file1 = tempfile::NamedTempFile::new().unwrap(); let mut file2 = tempfile::NamedTempFile::new().unwrap(); @@ -249,7 +249,7 @@ async fn test_write_new_path() -> anyhow::Result<()> { Ok(()) } -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_write_fail_new_path() -> anyhow::Result<()> { let file = helpers::new_readonly_tempfile()?;