Skip to content

Commit

Permalink
refactor: test handlers in their implementation files
Browse files Browse the repository at this point in the history
  • Loading branch information
ribru17 committed Dec 2, 2024
1 parent e41dd52 commit 9f6df2e
Show file tree
Hide file tree
Showing 11 changed files with 931 additions and 816 deletions.
106 changes: 106 additions & 0 deletions src/handlers/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,109 @@ pub async fn completion(

Ok(Some(CompletionResponse::Array(completion_items)))
}

#[cfg(test)]
mod test {
use pretty_assertions::assert_eq;
use rstest::rstest;
use tower::{Service, ServiceExt};
use tower_lsp::lsp_types::{
request::Completion, CompletionItem, CompletionItemKind, CompletionParams,
CompletionResponse, PartialResultParams, Position, TextDocumentIdentifier,
TextDocumentPositionParams, WorkDoneProgressParams,
};

use crate::{
test_helpers::helpers::{
initialize_server, lsp_request_to_jsonrpc_request, lsp_response_to_jsonrpc_response,
TEST_URI,
},
SymbolInfo,
};

#[rstest]
#[case(
r#"((identifier) @constant
(#match? @cons "^[A-Z][A-Z\\d_]*$"))"#,
Position { line: 1, character: 14 },
&[SymbolInfo { label: String::from("identifier"), named: true }],
&["operator"],
&[("@constant", CompletionItemKind::VARIABLE)]
)]
#[case(
r#"((ident) @constant
(#match? @constant "^[A-Z][A-Z\\d_]*$"))"#,
Position { line: 0, character: 6 },
&[SymbolInfo { label: String::from("identifier"), named: true }],
&["operator"],
&[("identifier", CompletionItemKind::CLASS), ("operator: ", CompletionItemKind::FIELD)]
)]
#[case(
r"((constant) @constant
; @co
)
",
Position { line: 1, character: 4 },
&[SymbolInfo { label: String::from("constant"), named: true }],
&["operator"],
&[]
)]
#[tokio::test(flavor = "current_thread")]
async fn test_server_completions(
#[case] source: &str,
#[case] position: Position,
#[case] symbols: &[SymbolInfo],
#[case] fields: &[&str],
#[case] expected_completions: &[(&str, CompletionItemKind)],
) {
// Arrange
let mut service =
initialize_server(&[(TEST_URI.clone(), source, symbols.to_vec(), fields.to_vec())])
.await
.0;

// Act
let completions = service
.ready()
.await
.unwrap()
.call(lsp_request_to_jsonrpc_request::<Completion>(
CompletionParams {
context: None,
text_document_position: TextDocumentPositionParams {
position,
text_document: TextDocumentIdentifier {
uri: TEST_URI.clone(),
},
},
partial_result_params: PartialResultParams::default(),
work_done_progress_params: WorkDoneProgressParams::default(),
},
))
.await
.map_err(|e| format!("textDocument/completion call returned error: {e}"))
.unwrap();

// Assert
let actual_completions = if expected_completions.is_empty() {
None
} else {
Some(CompletionResponse::Array(
expected_completions
.iter()
.map(|c| CompletionItem {
label: c.0.to_string(),
kind: Some(c.1),
..Default::default()
})
.collect(),
))
};
assert_eq!(
completions,
Some(lsp_response_to_jsonrpc_response::<Completion>(
actual_completions
))
);
}
}
88 changes: 88 additions & 0 deletions src/handlers/did_change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,91 @@ pub async fn did_change(backend: &Backend, params: DidChangeTextDocumentParams)
}
}
}

#[cfg(test)]
mod test {
use pretty_assertions::assert_eq;
use rstest::rstest;
use tower::{Service, ServiceExt};
use tower_lsp::lsp_types::{
notification::DidChangeTextDocument, DidChangeTextDocumentParams,
TextDocumentContentChangeEvent, VersionedTextDocumentIdentifier,
};

use crate::test_helpers::helpers::{
initialize_server, lsp_notification_to_jsonrpc_request, TestEdit, TEST_URI,
};

#[rstest]
#[case(
r#"(node_name) @hello
";" @semicolon"#,
r#"(identifier) @goodbye
";" @punctuation.delimiter"#,
&[
TestEdit::new("goodbye", (0, 13), (0, 18)),
TestEdit::new("identifier", (0, 1), (0, 10)),
TestEdit::new("punctuation.delimiter", (1, 5), (1, 14)),
]
)]
#[case(
r#"; Some comment with emojis 🚀🛳️🫡
(node_name) @hello
";" @semicolon"#,
r#"; Some comment with emojis 🚀🛳️🫡
(identifier) @goodbye
";" @punctuation.delimiter"#,
&[
TestEdit::new("goodbye", (1, 13), (1, 18)),
TestEdit::new("identifier", (1, 1), (1, 10)),
TestEdit::new("punctuation.delimiter", (2, 5), (2, 14)),
]
)]
#[tokio::test(flavor = "current_thread")]
async fn test_server_did_change(
#[case] original: &str,
#[case] expected: &str,
#[case] edits: &[TestEdit],
) {
// Arrange
let mut service =
initialize_server(&[(TEST_URI.clone(), original, Vec::new(), Vec::new())])
.await
.0;

// Act
service
.ready()
.await
.unwrap()
.call(
lsp_notification_to_jsonrpc_request::<DidChangeTextDocument>(
DidChangeTextDocumentParams {
text_document: VersionedTextDocumentIdentifier {
uri: TEST_URI.clone(),
version: 1,
},
content_changes: edits
.iter()
.map(Into::<TextDocumentContentChangeEvent>::into)
.collect(),
},
),
)
.await
.unwrap();

// Assert
let doc = service.inner().document_map.get(&TEST_URI);
let tree = service.inner().cst_map.get(&TEST_URI);
assert!(doc.is_some());
let doc = doc.unwrap();
assert_eq!(doc.to_string(), expected);
assert!(tree.is_some());
let tree = tree.unwrap();
assert_eq!(
tree.root_node().utf8_text(expected.as_bytes()).unwrap(),
expected
);
}
}
64 changes: 64 additions & 0 deletions src/handlers/did_change_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,67 @@ pub async fn did_change_configuration(backend: &Backend, params: DidChangeConfig
options.parser_aliases = changed_options.parser_aliases;
options.language_retrieval_patterns = changed_options.language_retrieval_patterns;
}

#[cfg(test)]
mod test {
use pretty_assertions::assert_eq;
use std::collections::BTreeMap;
use tower::{Service, ServiceExt};
use tower_lsp::lsp_types::{
notification::DidChangeConfiguration, DidChangeConfigurationParams,
};

use crate::{
test_helpers::helpers::{initialize_server, lsp_notification_to_jsonrpc_request},
Options,
};

#[tokio::test(flavor = "current_thread")]
async fn test_server_did_change_configuration() {
// Arrange
let mut service = initialize_server(&[]).await.0;

// Act
service
.ready()
.await
.unwrap()
.call(
lsp_notification_to_jsonrpc_request::<DidChangeConfiguration>(
DidChangeConfigurationParams {
settings: serde_json::from_str(
r#"
{
"parser_aliases": {
"ecma": "javascript",
"jsx": "javascript",
"foolang": "barlang"
}
}
"#,
)
.unwrap(),
},
),
)
.await
.unwrap();

// Assert
let options = service.inner().options.read();
assert!(options.is_ok());
let options = options.unwrap();
assert_eq!(
*options,
Options {
parser_aliases: Some(BTreeMap::from([
("ecma".to_string(), "javascript".to_string()),
("jsx".to_string(), "javascript".to_string()),
("foolang".to_string(), "barlang".to_string())
])),
parser_install_directories: None,
language_retrieval_patterns: None
}
);
}
}
51 changes: 51 additions & 0 deletions src/handlers/did_open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,54 @@ pub async fn did_open(backend: &Backend, params: DidOpenTextDocumentParams) {
.await;
}
}

#[cfg(test)]
mod test {
use pretty_assertions::assert_eq;
use tower::{Service, ServiceExt};
use tower_lsp::lsp_types::{
notification::DidOpenTextDocument, DidOpenTextDocumentParams, TextDocumentItem,
};

use crate::test_helpers::helpers::{
initialize_server, lsp_notification_to_jsonrpc_request, TEST_URI,
};

#[tokio::test(flavor = "current_thread")]
async fn test_server_did_open_document() {
// Arrange
let mut service = initialize_server(&[]).await.0;
let source = r#""[" @cap"#;

// Act
service
.ready()
.await
.unwrap()
.call(lsp_notification_to_jsonrpc_request::<DidOpenTextDocument>(
DidOpenTextDocumentParams {
text_document: TextDocumentItem {
uri: TEST_URI.clone(),
language_id: String::from("query"),
version: 0,
text: String::from(source),
},
},
))
.await
.unwrap();

// Assert
let doc_rope = service.inner().document_map.get(&TEST_URI);
assert!(doc_rope.is_some());
let doc_rope = doc_rope.unwrap();
assert_eq!(doc_rope.to_string(), source);
let tree = service.inner().cst_map.get(&TEST_URI);
assert!(tree.is_some());
let tree = tree.unwrap();
assert_eq!(
tree.root_node().utf8_text(source.as_bytes()).unwrap(),
doc_rope.to_string()
);
}
}
Loading

0 comments on commit 9f6df2e

Please sign in to comment.