@@ -5,7 +5,6 @@ use crossterm::event::{Event, KeyEvent};
55use helix_core::{test, Selection, Transaction};
66use helix_term::{application::Application, args::Args, config::Config};
77use helix_view::{doc, input::parse_macro};
8−use tokio::time::timeout;
98use tokio_stream::wrappers::UnboundedReceiverStream;
109
1110#[derive(Clone, Debug)]
@@ -32,35 +31,48 @@ impl<S: Into<String>> From<(S, S, S)> for TestCase {
3231 }
3332}
3433
34+#[inline]
3535pub async fn test_key_sequence(
3636 app: &mut Application,
3737 in_keys: &str,
3838 test_fn: Option<&dyn Fn(&Application)>,
39+ timeout: Option<Duration>,
3940) -> anyhow::Result<()> {
41+ test_key_sequences(app, vec![(in_keys, test_fn)], timeout).await
42+}
43+
44+pub async fn test_key_sequences(
45+ app: &mut Application,
46+ inputs: Vec<(&str, Option<&dyn Fn(&Application)>)>,
47+ timeout: Option<Duration>,
48+) -> anyhow::Result<()> {
49+ let timeout = timeout.unwrap_or(Duration::from_millis(500));
4050 let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
51+ let mut rx_stream = UnboundedReceiverStream::new(rx);
4152
42− for key_event in parse_macro(&in_keys)?.into_iter() {
43− tx.send(Ok(Event::Key(KeyEvent::from(key_event))))?;
44− }
53+ for (in_keys, test_fn) in inputs {
54+ for key_event in parse_macro(&in_keys)?.into_iter() {
55+ tx.send(Ok(Event::Key(KeyEvent::from(key_event))))?;
56+ }
4557
46− let mut rx_stream = UnboundedReceiverStream::new(rx);
47− let event_loop = app.event_loop(&mut rx_stream);
48− let result = timeout(Duration::from_millis(500), event_loop).await;
58+ let event_loop = app.event_loop(&mut rx_stream);
59+ let result = tokio::time::timeout(timeout, event_loop).await;
4960
50− if result.is_ok() {
51− bail!("application exited before test function could run");
52− }
61+ if result.is_ok() {
62+ bail!("application exited before test function could run");
63+ }
5364
54− if let Some(test) = test_fn {
55− test(app);
56− };
65+ if let Some(test) = test_fn {
66+ test(app);
67+ };
68+ }
5769
5870 for key_event in parse_macro("<esc>:q!<ret>")?.into_iter() {
5971 tx.send(Ok(Event::Key(KeyEvent::from(key_event))))?;
6072 }
6173
6274 let event_loop = app.event_loop(&mut rx_stream);
63− timeout(Duration::from_millis(5000), event_loop).await?;
75+ tokio::time::timeout(timeout, event_loop).await?;
6476 app.close().await?;
6577
6678 Ok(())
@@ -70,6 +82,7 @@ pub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(
7082 app: Option<Application>,
7183 test_case: T,
7284 test_fn: &dyn Fn(&Application),
85+ timeout: Option<Duration>,
7386) -> anyhow::Result<()> {
7487 let test_case = test_case.into();
7588 let mut app =
@@ -87,7 +100,7 @@ pub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(
87100 view.id,
88101 );
89102
90− test_key_sequence(&mut app, &test_case.in_keys, Some(test_fn)).await
103+ test_key_sequence(&mut app, &test_case.in_keys, Some(test_fn), timeout).await
91104}
92105
93106/// Use this for very simple test cases where there is one input
@@ -97,20 +110,26 @@ pub async fn test_key_sequence_text_result<T: Into<TestCase>>(
97110 args: Args,
98111 config: Config,
99112 test_case: T,
113+ timeout: Option<Duration>,
100114) -> anyhow::Result<()> {
101115 let test_case = test_case.into();
102116 let app = Application::new(args, config).unwrap();
103117
104− test_key_sequence_with_input_text(Some(app), test_case.clone(), &|app| {
105− let doc = doc!(app.editor);
106− assert_eq!(&test_case.out_text, doc.text());
107−
108− let mut selections: Vec<_> = doc.selections().values().cloned().collect();
109− assert_eq!(1, selections.len());
110−
111− let sel = selections.pop().unwrap();
112− assert_eq!(test_case.out_selection, sel);
113− })
118+ test_key_sequence_with_input_text(
119+ Some(app),
120+ test_case.clone(),
121+ &|app| {
122+ let doc = doc!(app.editor);
123+ assert_eq!(&test_case.out_text, doc.text());
124+
125+ let mut selections: Vec<_> = doc.selections().values().cloned().collect();
126+ assert_eq!(1, selections.len());
127+
128+ let sel = selections.pop().unwrap();
129+ assert_eq!(test_case.out_selection, sel);
130+ },
131+ timeout,
132+ )
114133 .await
115134}
116135