Skip to content

Commit

Permalink
Integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jpttrssn committed Aug 26, 2024
1 parent a876c04 commit 1c2284c
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ rustflags = ["--cfg", "tokio_unstable", "-C", "target-feature=-crt-static"]
[alias]
xtask = "run --package xtask --"
integration-test = "test --features integration --profile integration --workspace --test integration"
integration-test-lsp = "test --features integration-lsp --profile integration --workspace --test integration-lsp -- --test-threads=1"
integration-test-lsp = "test --features integration-lsp --profile integration --workspace --test integration-lsp"

8 changes: 8 additions & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ Contributors using MacOS might encounter `Too many open files (os error 24)`
failures while running integration tests. This can be resolved by increasing
the default value (e.g. to `10240` from `256`) by running `ulimit -n 10240`.

### Language Server tests

There are integration tests specific for language server integration that can be
run with `cargo integration-test-lsp` and have additional dependencies.

* [go](https://go.dev)
* [gopls](https://pkg.go.dev/golang.org/x/tools/gopls)

## Minimum Stable Rust Version (MSRV) Policy

Helix follows the MSRV of Firefox.
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ impl Application {
let language_id =
doc.language_id().map(ToOwned::to_owned).unwrap_or_default();

tokio::spawn(language_server.text_document_did_open(
let _ = helix_lsp::block_on(language_server.text_document_did_open(
url,
doc.version(),
doc.text(),
Expand Down
26 changes: 15 additions & 11 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use crate::{
args,
compositor::{self, Component, Compositor},
filter_picker_entry,
job::{Callback, OnSaveCallbackData},
job::Callback,
ui::{self, overlay::overlaid, Picker, PickerColumn, Popup, Prompt, PromptEvent},
};

Expand Down Expand Up @@ -3425,7 +3425,7 @@ pub fn format_callback(
}
}

pub async fn on_save_callback(
pub fn on_save_callback(
editor: &mut Editor,
doc_id: DocumentId,
view_id: ViewId,
Expand All @@ -3446,7 +3446,11 @@ pub async fn on_save_callback(
code_action_on_save_cfg
);
let doc = doc!(editor, &doc_id);
let code_actions = code_actions_on_save(doc, code_action_on_save_cfg.clone()).await;
// let code_actions =
// helix_lsp::block_on(code_actions_on_save(doc, code_action_on_save_cfg.clone()));
let code_actions = tokio::task::spawn_blocking(|| {
code_actions_on_save(doc, code_action_on_save_cfg.clone())
});

if code_actions.is_empty() {
log::debug!(
Expand All @@ -3470,16 +3474,21 @@ pub async fn on_save_callback(
}
}

log::debug!("CODEACTION APPLIED");

if editor.config().auto_format {
let doc = doc!(editor, &doc_id);
if let Some(fmt) = doc.auto_format() {
format_callback(doc.id(), doc.version(), view_id, fmt.await, editor);
let fmt_result = helix_lsp::block_on(fmt);
format_callback(doc.id(), doc.version(), view_id, fmt_result, editor);
}
log::debug!("CODEACTION FORMATTED");
}

if let Err(err) = editor.save::<PathBuf>(doc_id, path, force) {
editor.set_error(format!("Error saving: {}", err));
}
log::debug!("CODEACTION SAVED");
}

pub async fn make_on_save_callback(
Expand All @@ -3488,13 +3497,8 @@ pub async fn make_on_save_callback(
path: Option<PathBuf>,
force: bool,
) -> anyhow::Result<job::Callback> {
let call: job::Callback = Callback::OnSave(Box::new({
OnSaveCallbackData {
doc_id,
view_id,
path,
force,
}
let call = Callback::Editor(Box::new(move |editor| {
on_save_callback(editor, doc_id, view_id, path, force);
}));
Ok(call)
}
Expand Down
33 changes: 1 addition & 32 deletions helix-term/src/job.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use std::path::PathBuf;

use helix_event::status::StatusMessage;
use helix_event::{runtime_local, send_blocking};
use helix_view::{DocumentId, Editor, ViewId};
use helix_view::Editor;
use once_cell::sync::OnceCell;

use crate::commands::on_save_callback;
use crate::compositor::Compositor;

use futures_util::future::{BoxFuture, Future, FutureExt};
Expand All @@ -14,7 +11,6 @@ use tokio::sync::mpsc::{channel, Receiver, Sender};

pub type EditorCompositorCallback = Box<dyn FnOnce(&mut Editor, &mut Compositor) + Send>;
pub type EditorCallback = Box<dyn FnOnce(&mut Editor) + Send>;
pub type OnSaveCallback = Box<OnSaveCallbackData>;

runtime_local! {
static JOB_QUEUE: OnceCell<Sender<Callback>> = OnceCell::new();
Expand All @@ -39,7 +35,6 @@ pub fn dispatch_blocking(job: impl FnOnce(&mut Editor, &mut Compositor) + Send +
pub enum Callback {
EditorCompositor(EditorCompositorCallback),
Editor(EditorCallback),
OnSave(OnSaveCallback),
}

pub type JobFuture = BoxFuture<'static, anyhow::Result<Option<Callback>>>;
Expand All @@ -49,12 +44,6 @@ pub struct Job {
/// Do we need to wait for this job to finish before exiting?
pub wait: bool,
}
pub struct OnSaveCallbackData {
pub doc_id: DocumentId,
pub view_id: ViewId,
pub path: Option<PathBuf>,
pub force: bool,
}

pub struct Jobs {
/// jobs that need to complete before we exit.
Expand Down Expand Up @@ -121,16 +110,6 @@ impl Jobs {
Ok(Some(call)) => match call {
Callback::EditorCompositor(call) => call(editor, compositor),
Callback::Editor(call) => call(editor),
Callback::OnSave(callback_data) => {
on_save_callback(
editor,
callback_data.doc_id,
callback_data.view_id,
callback_data.path,
callback_data.force,
)
.await
}
},
Err(e) => {
editor.set_error(format!("Async job failed: {}", e));
Expand Down Expand Up @@ -174,16 +153,6 @@ impl Jobs {
call(editor, compositor.as_deref_mut().unwrap())
}
Callback::Editor(call) => call(editor),
Callback::OnSave(callback_data) => {
on_save_callback(
editor,
callback_data.doc_id,
callback_data.view_id,
callback_data.path,
callback_data.force,
)
.await
}
// skip callbacks for which we don't have the necessary references
_ => (),
}
Expand Down
18 changes: 18 additions & 0 deletions helix-term/tests/integration-lsp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[cfg(feature = "integration-lsp")]
mod test {
mod helpers;

use helix_term::config::Config;

use indoc::indoc;

use self::helpers::*;

#[tokio::test(flavor = "multi_thread")]
async fn hello_world() -> anyhow::Result<()> {
test(("#[\n|]#", "ihello world<esc>", "hello world#[|\n]#")).await?;
Ok(())
}

mod lsp;
}
8 changes: 4 additions & 4 deletions helix-term/tests/test/lsp/code_actions_on_save.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ fn assert_gopls(doc: Option<&Document>) {

if let Some(gopls) = ls {
if gopls.is_initialized() {
std::thread::sleep(std::time::Duration::from_millis(100));
initialized = true;
break;
}
}
assert!(false, "had to wait");
std::thread::sleep(std::time::Duration::from_millis(100));
}
assert!(ls.is_some(), "gopls language server not found");
Expand Down Expand Up @@ -87,7 +87,7 @@ async fn test_organize_imports_go() -> anyhow::Result<()> {
}

#[tokio::test(flavor = "multi_thread")]
async fn test_organize_imports_go_multi() -> anyhow::Result<()> {
async fn test_organize_imports_go_write_all_quit() -> anyhow::Result<()> {
let lang_conf = indoc! {r#"
[[language]]
name = "go"
Expand Down Expand Up @@ -135,9 +135,9 @@ async fn test_organize_imports_go_multi() -> anyhow::Result<()> {
assert_gopls(doc2);
}),
),
(Some(":wa<ret>"), None),
(Some(":wqa<ret>"), None),
],
false,
true,
)
.await?;

Expand Down

0 comments on commit 1c2284c

Please sign in to comment.