aboutsummaryrefslogtreecommitdiff
path: root/helix-term/tests/test
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/tests/test')
-rw-r--r--helix-term/tests/test/auto_indent.rs1
-rw-r--r--helix-term/tests/test/auto_pairs.rs1
-rw-r--r--helix-term/tests/test/commands.rs36
-rw-r--r--helix-term/tests/test/helpers.rs136
-rw-r--r--helix-term/tests/test/movement.rs8
-rw-r--r--helix-term/tests/test/prompt.rs4
-rw-r--r--helix-term/tests/test/splits.rs129
-rw-r--r--helix-term/tests/test/write.rs152
8 files changed, 410 insertions, 57 deletions
diff --git a/helix-term/tests/test/auto_indent.rs b/helix-term/tests/test/auto_indent.rs
index 2f638893..5c093a5d 100644
--- a/helix-term/tests/test/auto_indent.rs
+++ b/helix-term/tests/test/auto_indent.rs
@@ -8,6 +8,7 @@ async fn auto_indent_c() -> anyhow::Result<()> {
..Default::default()
},
Config::default(),
+ helpers::test_syntax_conf(None),
// switches to append mode?
(
helpers::platform_line("void foo() {#[|}]#").as_ref(),
diff --git a/helix-term/tests/test/auto_pairs.rs b/helix-term/tests/test/auto_pairs.rs
index ec47a5b4..caf80bd4 100644
--- a/helix-term/tests/test/auto_pairs.rs
+++ b/helix-term/tests/test/auto_pairs.rs
@@ -13,6 +13,7 @@ async fn auto_pairs_basic() -> anyhow::Result<()> {
},
..Default::default()
},
+ helpers::test_syntax_conf(None),
("#[\n|]#", "i(<esc>", "(#[|\n]#"),
)
.await?;
diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs
index f7ce9af0..5238cc69 100644
--- a/helix-term/tests/test/commands.rs
+++ b/helix-term/tests/test/commands.rs
@@ -1,21 +1,25 @@
-use std::{
- io::{Read, Write},
- ops::RangeInclusive,
-};
+use std::ops::RangeInclusive;
use helix_core::diagnostic::Severity;
-use helix_term::application::Application;
use super::*;
-#[tokio::test]
+#[tokio::test(flavor = "multi_thread")]
async fn test_write_quit_fail() -> anyhow::Result<()> {
let file = helpers::new_readonly_tempfile()?;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
test_key_sequence(
- &mut helpers::app_with_file(file.path())?,
+ &mut app,
Some("ihello<esc>:wq<ret>"),
Some(&|app| {
+ let mut docs: Vec<_> = app.editor.documents().collect();
+ assert_eq!(1, docs.len());
+
+ let doc = docs.pop().unwrap();
+ assert_eq!(Some(file.path()), doc.path().map(PathBuf::as_path));
assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);
}),
false,
@@ -25,11 +29,10 @@ async fn test_write_quit_fail() -> anyhow::Result<()> {
Ok(())
}
-#[tokio::test]
-#[ignore]
+#[tokio::test(flavor = "multi_thread")]
async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
test_key_sequences(
- &mut Application::new(Args::default(), Config::default())?,
+ &mut helpers::AppBuilder::new().build()?,
vec![
(
None,
@@ -69,8 +72,12 @@ async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
command.push_str(":buffer<minus>close<ret>");
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
+
test_key_sequence(
- &mut helpers::app_with_file(file.path())?,
+ &mut app,
Some(&command),
Some(&|app| {
assert!(!app.editor.is_err(), "error: {:?}", app.editor.get_status());
@@ -82,12 +89,7 @@ async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
)
.await?;
- file.as_file_mut().flush()?;
- file.as_file_mut().sync_all()?;
-
- let mut file_content = String::new();
- file.as_file_mut().read_to_string(&mut file_content)?;
- assert_eq!(RANGE.end().to_string(), file_content);
+ helpers::assert_file_has_content(file.as_file_mut(), &RANGE.end().to_string())?;
Ok(())
}
diff --git a/helix-term/tests/test/helpers.rs b/helix-term/tests/test/helpers.rs
index 8f2501e6..5adc3354 100644
--- a/helix-term/tests/test/helpers.rs
+++ b/helix-term/tests/test/helpers.rs
@@ -1,10 +1,15 @@
-use std::{io::Write, path::PathBuf, time::Duration};
+use std::{
+ fs::File,
+ io::{Read, Write},
+ path::PathBuf,
+ time::Duration,
+};
use anyhow::bail;
use crossterm::event::{Event, KeyEvent};
-use helix_core::{test, Selection, Transaction};
+use helix_core::{diagnostic::Severity, test, Selection, Transaction};
use helix_term::{application::Application, args::Args, config::Config};
-use helix_view::{doc, input::parse_macro};
+use helix_view::{doc, input::parse_macro, Editor};
use tempfile::NamedTempFile;
use tokio_stream::wrappers::UnboundedReceiverStream;
@@ -56,7 +61,9 @@ pub async fn test_key_sequences(
for (i, (in_keys, test_fn)) in inputs.into_iter().enumerate() {
if let Some(in_keys) = in_keys {
for key_event in parse_macro(in_keys)?.into_iter() {
- tx.send(Ok(Event::Key(KeyEvent::from(key_event))))?;
+ let key = Event::Key(KeyEvent::from(key_event));
+ log::trace!("sending key: {:?}", key);
+ tx.send(Ok(key))?;
}
}
@@ -70,7 +77,7 @@ pub async fn test_key_sequences(
// verify if it exited on the last iteration if it should have and
// the inverse
if i == num_inputs - 1 && app_exited != should_exit {
- bail!("expected app to exit: {} != {}", app_exited, should_exit);
+ bail!("expected app to exit: {} != {}", should_exit, app_exited);
}
if let Some(test) = test_fn {
@@ -87,7 +94,17 @@ pub async fn test_key_sequences(
tokio::time::timeout(TIMEOUT, event_loop).await?;
}
- app.close().await?;
+ let errs = app.close().await;
+
+ if !errs.is_empty() {
+ log::error!("Errors closing app");
+
+ for err in errs {
+ log::error!("{}", err);
+ }
+
+ bail!("Error closing app");
+ }
Ok(())
}
@@ -101,7 +118,7 @@ pub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(
let test_case = test_case.into();
let mut app = match app {
Some(app) => app,
- None => Application::new(Args::default(), Config::default())?,
+ None => Application::new(Args::default(), Config::default(), test_syntax_conf(None))?,
};
let (view, doc) = helix_view::current!(app.editor);
@@ -125,16 +142,30 @@ pub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(
.await
}
+/// Generates language configs that merge in overrides, like a user language
+/// config. The argument string must be a raw TOML document.
+pub fn test_syntax_conf(overrides: Option<String>) -> helix_core::syntax::Configuration {
+ let mut lang = helix_loader::config::default_lang_config();
+
+ if let Some(overrides) = overrides {
+ let override_toml = toml::from_str(&overrides).unwrap();
+ lang = helix_loader::merge_toml_values(lang, override_toml, 3);
+ }
+
+ lang.try_into().unwrap()
+}
+
/// Use this for very simple test cases where there is one input
/// document, selection, and sequence of key presses, and you just
/// want to verify the resulting document and selection.
pub async fn test_with_config<T: Into<TestCase>>(
args: Args,
config: Config,
+ syn_conf: helix_core::syntax::Configuration,
test_case: T,
) -> anyhow::Result<()> {
let test_case = test_case.into();
- let app = Application::new(args, config)?;
+ let app = Application::new(args, config, syn_conf)?;
test_key_sequence_with_input_text(
Some(app),
@@ -155,7 +186,13 @@ pub async fn test_with_config<T: Into<TestCase>>(
}
pub async fn test<T: Into<TestCase>>(test_case: T) -> anyhow::Result<()> {
- test_with_config(Args::default(), Config::default(), test_case).await
+ test_with_config(
+ Args::default(),
+ Config::default(),
+ test_syntax_conf(None),
+ test_case,
+ )
+ .await
}
pub fn temp_file_with_contents<S: AsRef<str>>(
@@ -200,14 +237,75 @@ pub fn new_readonly_tempfile() -> anyhow::Result<NamedTempFile> {
Ok(file)
}
-/// Creates a new Application with default config that opens the given file
-/// path
-pub fn app_with_file<P: Into<PathBuf>>(path: P) -> anyhow::Result<Application> {
- Application::new(
- Args {
- files: vec![(path.into(), helix_core::Position::default())],
- ..Default::default()
- },
- Config::default(),
- )
+#[derive(Default)]
+pub struct AppBuilder {
+ args: Args,
+ config: Config,
+ syn_conf: helix_core::syntax::Configuration,
+ input: Option<(String, Selection)>,
+}
+
+impl AppBuilder {
+ pub fn new() -> Self {
+ AppBuilder::default()
+ }
+
+ pub fn with_file<P: Into<PathBuf>>(
+ mut self,
+ path: P,
+ pos: Option<helix_core::Position>,
+ ) -> Self {
+ self.args.files.push((path.into(), pos.unwrap_or_default()));
+ self
+ }
+
+ pub fn with_config(mut self, config: Config) -> Self {
+ self.config = config;
+ self
+ }
+
+ pub fn with_input_text<S: Into<String>>(mut self, input_text: S) -> Self {
+ self.input = Some(test::print(&input_text.into()));
+ self
+ }
+
+ pub fn with_lang_config(mut self, syn_conf: helix_core::syntax::Configuration) -> Self {
+ self.syn_conf = syn_conf;
+ self
+ }
+
+ pub fn build(self) -> anyhow::Result<Application> {
+ let mut app = Application::new(self.args, self.config, self.syn_conf)?;
+
+ if let Some((text, selection)) = self.input {
+ let (view, doc) = helix_view::current!(app.editor);
+ let sel = doc.selection(view.id).clone();
+ let trans = Transaction::change_by_selection(doc.text(), &sel, |_| {
+ (0, doc.text().len_chars(), Some((text.clone()).into()))
+ })
+ .with_selection(selection);
+
+ // replace the initial text with the input text
+ doc.apply(&trans, view.id);
+ }
+
+ Ok(app)
+ }
+}
+
+pub fn assert_file_has_content(file: &mut File, content: &str) -> anyhow::Result<()> {
+ file.flush()?;
+ file.sync_all()?;
+
+ let mut file_content = String::new();
+ file.read_to_string(&mut file_content)?;
+ assert_eq!(content, file_content);
+
+ Ok(())
+}
+
+pub fn assert_status_not_error(editor: &Editor) {
+ if let Some((_, sev)) = editor.get_status() {
+ assert_ne!(&Severity::Error, sev);
+ }
}
diff --git a/helix-term/tests/test/movement.rs b/helix-term/tests/test/movement.rs
index 45aae39e..81c66e53 100644
--- a/helix-term/tests/test/movement.rs
+++ b/helix-term/tests/test/movement.rs
@@ -70,7 +70,9 @@ async fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> {
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)?;
- let mut app = helpers::app_with_file(file.path())?;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
let (view, doc) = helix_view::current!(app.editor);
let sel = doc.selection(view.id).clone();
@@ -115,6 +117,7 @@ async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::
..Default::default()
},
Config::default(),
+ helpers::test_syntax_conf(None),
(
helpers::platform_line(indoc! {"\
#[/|]#// Increments
@@ -146,6 +149,7 @@ async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Res
..Default::default()
},
Config::default(),
+ helpers::test_syntax_conf(None),
(
helpers::platform_line(indoc! {"\
/// Increments
@@ -178,6 +182,7 @@ async fn select_mode_tree_sitter_prev_function_goes_backwards_to_object() -> any
..Default::default()
},
Config::default(),
+ helpers::test_syntax_conf(None),
(
helpers::platform_line(indoc! {"\
/// Increments
@@ -208,6 +213,7 @@ async fn select_mode_tree_sitter_prev_function_goes_backwards_to_object() -> any
..Default::default()
},
Config::default(),
+ helpers::test_syntax_conf(None),
(
helpers::platform_line(indoc! {"\
/// Increments
diff --git a/helix-term/tests/test/prompt.rs b/helix-term/tests/test/prompt.rs
index 2ab9604c..62ec03f1 100644
--- a/helix-term/tests/test/prompt.rs
+++ b/helix-term/tests/test/prompt.rs
@@ -1,11 +1,9 @@
use super::*;
-use helix_term::application::Application;
-
#[tokio::test]
async fn test_history_completion() -> anyhow::Result<()> {
test_key_sequence(
- &mut Application::new(Args::default(), Config::default())?,
+ &mut AppBuilder::new().build()?,
Some(":asdf<ret>:theme d<C-n><tab>"),
Some(&|app| {
assert!(!app.editor.is_err());
diff --git a/helix-term/tests/test/splits.rs b/helix-term/tests/test/splits.rs
new file mode 100644
index 00000000..5807413a
--- /dev/null
+++ b/helix-term/tests/test/splits.rs
@@ -0,0 +1,129 @@
+use super::*;
+
+#[tokio::test(flavor = "multi_thread")]
+async fn test_split_write_quit_all() -> anyhow::Result<()> {
+ let mut file1 = tempfile::NamedTempFile::new()?;
+ let mut file2 = tempfile::NamedTempFile::new()?;
+ let mut file3 = tempfile::NamedTempFile::new()?;
+
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file1.path(), None)
+ .build()?;
+
+ test_key_sequences(
+ &mut app,
+ vec![
+ (
+ Some(&format!(
+ "ihello1<esc>:sp<ret>:o {}<ret>ihello2<esc>:sp<ret>:o {}<ret>ihello3<esc>",
+ file2.path().to_string_lossy(),
+ file3.path().to_string_lossy()
+ )),
+ Some(&|app| {
+ let docs: Vec<_> = app.editor.documents().collect();
+ assert_eq!(3, docs.len());
+
+ let doc1 = docs
+ .iter()
+ .find(|doc| doc.path().unwrap() == file1.path())
+ .unwrap();
+
+ assert_eq!("hello1", doc1.text().to_string());
+
+ let doc2 = docs
+ .iter()
+ .find(|doc| doc.path().unwrap() == file2.path())
+ .unwrap();
+
+ assert_eq!("hello2", doc2.text().to_string());
+
+ let doc3 = docs
+ .iter()
+ .find(|doc| doc.path().unwrap() == file3.path())
+ .unwrap();
+
+ assert_eq!("hello3", doc3.text().to_string());
+
+ helpers::assert_status_not_error(&app.editor);
+ assert_eq!(3, app.editor.tree.views().count());
+ }),
+ ),
+ (
+ Some(":wqa<ret>"),
+ Some(&|app| {
+ helpers::assert_status_not_error(&app.editor);
+ assert_eq!(0, app.editor.tree.views().count());
+ }),
+ ),
+ ],
+ true,
+ )
+ .await?;
+
+ helpers::assert_file_has_content(file1.as_file_mut(), "hello1")?;
+ helpers::assert_file_has_content(file2.as_file_mut(), "hello2")?;
+ helpers::assert_file_has_content(file3.as_file_mut(), "hello3")?;
+
+ Ok(())
+}
+
+#[tokio::test(flavor = "multi_thread")]
+async fn test_split_write_quit_same_file() -> anyhow::Result<()> {
+ let mut file = tempfile::NamedTempFile::new()?;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
+
+ test_key_sequences(
+ &mut app,
+ vec![
+ (
+ Some("O<esc>ihello<esc>:sp<ret>ogoodbye<esc>"),
+ Some(&|app| {
+ assert_eq!(2, app.editor.tree.views().count());
+ helpers::assert_status_not_error(&app.editor);
+
+ let mut docs: Vec<_> = app.editor.documents().collect();
+ assert_eq!(1, docs.len());
+
+ let doc = docs.pop().unwrap();
+
+ assert_eq!(
+ helpers::platform_line("hello\ngoodbye"),
+ doc.text().to_string()
+ );
+
+ assert!(doc.is_modified());
+ }),
+ ),
+ (
+ Some(":wq<ret>"),
+ Some(&|app| {
+ helpers::assert_status_not_error(&app.editor);
+ assert_eq!(1, app.editor.tree.views().count());
+
+ let mut docs: Vec<_> = app.editor.documents().collect();
+ assert_eq!(1, docs.len());
+
+ let doc = docs.pop().unwrap();
+
+ assert_eq!(
+ helpers::platform_line("hello\ngoodbye"),
+ doc.text().to_string()
+ );
+
+ assert!(!doc.is_modified());
+ }),
+ ),
+ ],
+ false,
+ )
+ .await?;
+
+ helpers::assert_file_has_content(
+ file.as_file_mut(),
+ &helpers::platform_line("hello\ngoodbye"),
+ )?;
+
+ Ok(())
+}
diff --git a/helix-term/tests/test/write.rs b/helix-term/tests/test/write.rs
index 8869d881..6aa51a31 100644
--- a/helix-term/tests/test/write.rs
+++ b/helix-term/tests/test/write.rs
@@ -4,7 +4,6 @@ use std::{
};
use helix_core::diagnostic::Severity;
-use helix_term::application::Application;
use helix_view::doc;
use super::*;
@@ -12,9 +11,12 @@ use super::*;
#[tokio::test]
async fn test_write() -> anyhow::Result<()> {
let mut file = tempfile::NamedTempFile::new()?;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
test_key_sequence(
- &mut helpers::app_with_file(file.path())?,
+ &mut app,
Some("ithe gostak distims the doshes<ret><esc>:w<ret>"),
None,
false,
@@ -35,12 +37,15 @@ async fn test_write() -> anyhow::Result<()> {
Ok(())
}
-#[tokio::test]
+#[tokio::test(flavor = "multi_thread")]
async fn test_write_quit() -> anyhow::Result<()> {
let mut file = tempfile::NamedTempFile::new()?;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
test_key_sequence(
- &mut helpers::app_with_file(file.path())?,
+ &mut app,
Some("ithe gostak distims the doshes<ret><esc>:wq<ret>"),
None,
true,
@@ -61,25 +66,21 @@ async fn test_write_quit() -> anyhow::Result<()> {
Ok(())
}
-#[tokio::test]
-#[ignore]
+#[tokio::test(flavor = "multi_thread")]
async fn test_write_concurrent() -> anyhow::Result<()> {
let mut file = tempfile::NamedTempFile::new()?;
let mut command = String::new();
const RANGE: RangeInclusive<i32> = 1..=5000;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
for i in RANGE {
let cmd = format!("%c{}<esc>:w<ret>", i);
command.push_str(&cmd);
}
- test_key_sequence(
- &mut helpers::app_with_file(file.path())?,
- Some(&command),
- None,
- false,
- )
- .await?;
+ test_key_sequence(&mut app, Some(&command), None, false).await?;
file.as_file_mut().flush()?;
file.as_file_mut().sync_all()?;
@@ -92,12 +93,14 @@ async fn test_write_concurrent() -> anyhow::Result<()> {
}
#[tokio::test]
-#[ignore]
async fn test_write_fail_mod_flag() -> anyhow::Result<()> {
let file = helpers::new_readonly_tempfile()?;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
test_key_sequences(
- &mut helpers::app_with_file(file.path())?,
+ &mut app,
vec![
(
None,
@@ -131,12 +134,127 @@ async fn test_write_fail_mod_flag() -> anyhow::Result<()> {
}
#[tokio::test]
-#[ignore]
+async fn test_write_scratch_to_new_path() -> anyhow::Result<()> {
+ let mut file = tempfile::NamedTempFile::new()?;
+
+ test_key_sequence(
+ &mut AppBuilder::new().build()?,
+ Some(format!("ihello<esc>:w {}<ret>", file.path().to_string_lossy()).as_ref()),
+ Some(&|app| {
+ assert!(!app.editor.is_err());
+
+ let mut docs: Vec<_> = app.editor.documents().collect();
+ assert_eq!(1, docs.len());
+
+ let doc = docs.pop().unwrap();
+ assert_eq!(Some(&file.path().to_path_buf()), doc.path());
+ }),
+ false,
+ )
+ .await?;
+
+ helpers::assert_file_has_content(file.as_file_mut(), &helpers::platform_line("hello"))?;
+
+ Ok(())
+}
+
+#[tokio::test]
+async fn test_write_scratch_no_path_fails() -> anyhow::Result<()> {
+ helpers::test_key_sequence_with_input_text(
+ None,
+ ("#[\n|]#", "ihello<esc>:w<ret>", "hello#[\n|]#"),
+ &|app| {
+ assert!(app.editor.is_err());
+
+ let mut docs: Vec<_> = app.editor.documents().collect();
+ assert_eq!(1, docs.len());
+
+ let doc = docs.pop().unwrap();
+ assert_eq!(None, doc.path());
+ },
+ false,
+ )
+ .await?;
+
+ Ok(())
+}
+
+#[tokio::test]
+async fn test_write_auto_format_fails_still_writes() -> anyhow::Result<()> {
+ let mut file = tempfile::Builder::new().suffix(".rs").tempfile()?;
+
+ let lang_conf = indoc! {r#"
+ [[language]]
+ name = "rust"
+ formatter = { command = "bash", args = [ "-c", "exit 1" ] }
+ "#};
+
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .with_input_text("#[l|]#et foo = 0;\n")
+ .with_lang_config(helpers::test_syntax_conf(Some(lang_conf.into())))
+ .build()?;
+
+ test_key_sequences(&mut app, vec![(Some(":w<ret>"), None)], false).await?;
+
+ // file still saves
+ helpers::assert_file_has_content(file.as_file_mut(), "let foo = 0;\n")?;
+
+ Ok(())
+}
+
+#[tokio::test]
+async fn test_write_new_path() -> anyhow::Result<()> {
+ let mut file1 = tempfile::NamedTempFile::new().unwrap();
+ let mut file2 = tempfile::NamedTempFile::new().unwrap();
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file1.path(), None)
+ .build()?;
+
+ test_key_sequences(
+ &mut app,
+ vec![
+ (
+ Some("ii can eat glass, it will not hurt me<ret><esc>:w<ret>"),
+ Some(&|app| {
+ let doc = doc!(app.editor);
+ assert!(!app.editor.is_err());
+ assert_eq!(file1.path(), doc.path().unwrap());
+ }),
+ ),
+ (
+ Some(&format!(":w {}<ret>", file2.path().to_string_lossy())),
+ Some(&|app| {
+ let doc = doc!(app.editor);
+ assert!(!app.editor.is_err());
+ assert_eq!(file2.path(), doc.path().unwrap());
+ assert!(app.editor.document_by_path(file1.path()).is_none());
+ }),
+ ),
+ ],
+ false,
+ )
+ .await?;
+
+ helpers::assert_file_has_content(
+ file1.as_file_mut(),
+ &helpers::platform_line("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"),
+ )?;
+
+ Ok(())
+}
+
+#[tokio::test]
async fn test_write_fail_new_path() -> anyhow::Result<()> {
let file = helpers::new_readonly_tempfile()?;
test_key_sequences(
- &mut Application::new(Args::default(), Config::default())?,
+ &mut AppBuilder::new().build()?,
vec![
(
None,