summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2023-03-09 15:09:03 -0500
committerGitHub <noreply@github.com>2023-03-09 15:09:03 -0500
commit47012bd931e785073e943b82dd397386b6ee7ca5 (patch)
tree82e2695413c72bd124f55a8bc5423c2b79d63f34 /cli
parent2f81e555d88e45a7ec9b5a5bc511fd3ea4d9c75f (diff)
refactor(tests/lsp): consolidate more into test LspClient and reduce verbosity (#18100)
Diffstat (limited to 'cli')
-rw-r--r--cli/bench/lsp.rs153
-rw-r--r--cli/bench/lsp_bench_standalone.rs47
-rw-r--r--cli/bench/main.rs2
-rw-r--r--cli/tests/integration/lsp_tests.rs6150
4 files changed, 2622 insertions, 3730 deletions
diff --git a/cli/bench/lsp.rs b/cli/bench/lsp.rs
index b0682e2e9..15f3ee762 100644
--- a/cli/bench/lsp.rs
+++ b/cli/bench/lsp.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
-use deno_core::error::AnyError;
use deno_core::serde::Deserialize;
use deno_core::serde_json;
use deno_core::serde_json::json;
@@ -10,7 +9,6 @@ use std::collections::HashMap;
use std::path::Path;
use std::time::Duration;
use test_util::lsp::LspClientBuilder;
-use test_util::lsp::LspResponseError;
use tower_lsp::lsp_types as lsp;
static FIXTURE_CODE_LENS_TS: &str = include_str!("testdata/code_lens.ts");
@@ -41,7 +39,7 @@ struct FixtureMessage {
/// A benchmark that opens a 8000+ line TypeScript document, adds a function to
/// the end of the document and does a level of hovering and gets quick fix
/// code actions.
-fn bench_big_file_edits(deno_exe: &Path) -> Result<Duration, AnyError> {
+fn bench_big_file_edits(deno_exe: &Path) -> Duration {
let mut client = LspClientBuilder::new().deno_exe(deno_exe).build();
client.initialize_default();
@@ -55,9 +53,9 @@ fn bench_big_file_edits(deno_exe: &Path) -> Result<Duration, AnyError> {
"text": FIXTURE_DB_TS
}
}),
- )?;
+ );
- let (id, method, _): (u64, String, Option<Value>) = client.read_request()?;
+ let (id, method, _): (u64, String, Option<Value>) = client.read_request();
assert_eq!(method, "workspace/configuration");
client.write_response(
@@ -65,58 +63,45 @@ fn bench_big_file_edits(deno_exe: &Path) -> Result<Duration, AnyError> {
json!({
"enable": true
}),
- )?;
+ );
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
let messages: Vec<FixtureMessage> =
- serde_json::from_slice(FIXTURE_DB_MESSAGES)?;
+ serde_json::from_slice(FIXTURE_DB_MESSAGES).unwrap();
for msg in messages {
match msg.fixture_type {
FixtureType::Action => {
- client.write_request::<_, _, Value>(
- "textDocument/codeAction",
- msg.params,
- )?;
+ client.write_request("textDocument/codeAction", msg.params);
}
FixtureType::Change => {
- client.write_notification("textDocument/didChange", msg.params)?;
+ client.write_notification("textDocument/didChange", msg.params);
}
FixtureType::Completion => {
- client.write_request::<_, _, Value>(
- "textDocument/completion",
- msg.params,
- )?;
+ client.write_request("textDocument/completion", msg.params);
}
FixtureType::Highlight => {
- client.write_request::<_, _, Value>(
- "textDocument/documentHighlight",
- msg.params,
- )?;
+ client.write_request("textDocument/documentHighlight", msg.params);
}
FixtureType::Hover => {
- client
- .write_request::<_, _, Value>("textDocument/hover", msg.params)?;
+ client.write_request("textDocument/hover", msg.params);
}
}
}
- let (_, response_error): (Option<Value>, Option<LspResponseError>) =
- client.write_request("shutdown", json!(null))?;
- assert!(response_error.is_none());
+ client.write_request("shutdown", json!(null));
+ client.write_notification("exit", json!(null));
- client.write_notification("exit", json!(null))?;
-
- Ok(client.duration())
+ client.duration()
}
-fn bench_code_lens(deno_exe: &Path) -> Result<Duration, AnyError> {
+fn bench_code_lens(deno_exe: &Path) -> Duration {
let mut client = LspClientBuilder::new().deno_exe(deno_exe).build();
client.initialize_default();
@@ -130,9 +115,9 @@ fn bench_code_lens(deno_exe: &Path) -> Result<Duration, AnyError> {
"text": FIXTURE_CODE_LENS_TS
}
}),
- )?;
+ );
- let (id, method, _): (u64, String, Option<Value>) = client.read_request()?;
+ let (id, method, _): (u64, String, Option<Value>) = client.read_request();
assert_eq!(method, "workspace/configuration");
client.write_response(
@@ -140,42 +125,33 @@ fn bench_code_lens(deno_exe: &Path) -> Result<Duration, AnyError> {
json!({
"enable": true
}),
- )?;
+ );
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Vec<lsp::CodeLens>>(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "file:///testdata/code_lens.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let res = maybe_res.unwrap();
+ let res = client.write_request_with_res_as::<Vec<lsp::CodeLens>>(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "file:///testdata/code_lens.ts"
+ }
+ }),
+ );
assert!(!res.is_empty());
for code_lens in res {
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, lsp::CodeLens>("codeLens/resolve", code_lens)
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
+ client.write_request("codeLens/resolve", code_lens);
}
- Ok(client.duration())
+ client.duration()
}
-fn bench_find_replace(deno_exe: &Path) -> Result<Duration, AnyError> {
+fn bench_find_replace(deno_exe: &Path) -> Duration {
let mut client = LspClientBuilder::new().deno_exe(deno_exe).build();
client.initialize_default();
@@ -190,17 +166,17 @@ fn bench_find_replace(deno_exe: &Path) -> Result<Duration, AnyError> {
"text": "console.log(\"000\");\n"
}
}),
- )?;
+ );
}
for _ in 0..10 {
- let (id, method, _) = client.read_request::<Value>()?;
+ let (id, method, _) = client.read_request::<Value>();
assert_eq!(method, "workspace/configuration");
- client.write_response(id, json!({ "enable": true }))?;
+ client.write_response(id, json!({ "enable": true }));
}
for _ in 0..3 {
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
}
@@ -228,12 +204,12 @@ fn bench_find_replace(deno_exe: &Path) -> Result<Duration, AnyError> {
text: "111".to_string(),
}],
},
- )?;
+ );
}
for i in 0..10 {
let file_name = format!("file:///a/file_{i}.ts");
- let (maybe_res, maybe_err) = client.write_request::<_, _, Value>(
+ client.write_request(
"textDocument/formatting",
lsp::DocumentFormattingParams {
text_document: lsp::TextDocumentIdentifier {
@@ -246,27 +222,22 @@ fn bench_find_replace(deno_exe: &Path) -> Result<Duration, AnyError> {
},
work_done_progress_params: Default::default(),
},
- )?;
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
+ );
}
for _ in 0..3 {
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
}
- let (_, response_error): (Option<Value>, Option<LspResponseError>) =
- client.write_request("shutdown", json!(null))?;
- assert!(response_error.is_none());
-
- client.write_notification("exit", json!(null))?;
+ client.write_request("shutdown", json!(null));
+ client.write_notification("exit", json!(null));
- Ok(client.duration())
+ client.duration()
}
/// A test that starts up the LSP, opens a single line document, and exits.
-fn bench_startup_shutdown(deno_exe: &Path) -> Result<Duration, AnyError> {
+fn bench_startup_shutdown(deno_exe: &Path) -> Duration {
let mut client = LspClientBuilder::new().deno_exe(deno_exe).build();
client.initialize_default();
@@ -280,9 +251,9 @@ fn bench_startup_shutdown(deno_exe: &Path) -> Result<Duration, AnyError> {
"text": "console.log(Deno.args);\n"
}
}),
- )?;
+ );
- let (id, method, _) = client.read_request::<Value>()?;
+ let (id, method, _) = client.read_request::<Value>();
assert_eq!(method, "workspace/configuration");
client.write_response(
@@ -290,33 +261,31 @@ fn bench_startup_shutdown(deno_exe: &Path) -> Result<Duration, AnyError> {
json!({
"enable": true
}),
- )?;
+ );
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _): (String, Option<Value>) = client.read_notification()?;
+ let (method, _): (String, Option<Value>) = client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
- let (_, response_error): (Option<Value>, Option<LspResponseError>) =
- client.write_request("shutdown", json!(null))?;
- assert!(response_error.is_none());
+ client.write_request("shutdown", json!(null));
- client.write_notification("exit", json!(null))?;
+ client.write_notification("exit", json!(null));
- Ok(client.duration())
+ client.duration()
}
/// Generate benchmarks for the LSP server.
-pub fn benchmarks(deno_exe: &Path) -> Result<HashMap<String, i64>, AnyError> {
+pub fn benchmarks(deno_exe: &Path) -> HashMap<String, i64> {
println!("-> Start benchmarking lsp");
let mut exec_times = HashMap::new();
println!(" - Simple Startup/Shutdown ");
let mut times = Vec::new();
for _ in 0..10 {
- times.push(bench_startup_shutdown(deno_exe)?);
+ times.push(bench_startup_shutdown(deno_exe));
}
let mean =
(times.iter().sum::<Duration>() / times.len() as u32).as_millis() as i64;
@@ -326,7 +295,7 @@ pub fn benchmarks(deno_exe: &Path) -> Result<HashMap<String, i64>, AnyError> {
println!(" - Big Document/Several Edits ");
let mut times = Vec::new();
for _ in 0..5 {
- times.push(bench_big_file_edits(deno_exe)?);
+ times.push(bench_big_file_edits(deno_exe));
}
let mean =
(times.iter().sum::<Duration>() / times.len() as u32).as_millis() as i64;
@@ -336,7 +305,7 @@ pub fn benchmarks(deno_exe: &Path) -> Result<HashMap<String, i64>, AnyError> {
println!(" - Find/Replace");
let mut times = Vec::new();
for _ in 0..10 {
- times.push(bench_find_replace(deno_exe)?);
+ times.push(bench_find_replace(deno_exe));
}
let mean =
(times.iter().sum::<Duration>() / times.len() as u32).as_millis() as i64;
@@ -346,7 +315,7 @@ pub fn benchmarks(deno_exe: &Path) -> Result<HashMap<String, i64>, AnyError> {
println!(" - Code Lens");
let mut times = Vec::new();
for _ in 0..10 {
- times.push(bench_code_lens(deno_exe)?);
+ times.push(bench_code_lens(deno_exe));
}
let mean =
(times.iter().sum::<Duration>() / times.len() as u32).as_millis() as i64;
@@ -355,5 +324,5 @@ pub fn benchmarks(deno_exe: &Path) -> Result<HashMap<String, i64>, AnyError> {
println!("<- End benchmarking lsp");
- Ok(exec_times)
+ exec_times
}
diff --git a/cli/bench/lsp_bench_standalone.rs b/cli/bench/lsp_bench_standalone.rs
index 888d959ac..60d5be2d1 100644
--- a/cli/bench/lsp_bench_standalone.rs
+++ b/cli/bench/lsp_bench_standalone.rs
@@ -14,34 +14,29 @@ fn incremental_change_wait(bench: &mut Bencher) {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": "file:///testdata/express-router.js",
- "languageId": "javascript",
- "version": 0,
- "text": include_str!("testdata/express-router.js")
- }
- }),
- )
- .unwrap();
+ client.write_notification(
+ "textDocument/didOpen",
+ json!({
+ "textDocument": {
+ "uri": "file:///testdata/express-router.js",
+ "languageId": "javascript",
+ "version": 0,
+ "text": include_str!("testdata/express-router.js")
+ }
+ }),
+ );
- let (id, method, _): (u64, String, Option<Value>) =
- client.read_request().unwrap();
+ let (id, method, _): (u64, String, Option<Value>) = client.read_request();
assert_eq!(method, "workspace/configuration");
- client
- .write_response(
- id,
- json!({
- "enable": true
- }),
- )
- .unwrap();
+ client.write_response(
+ id,
+ json!({
+ "enable": true
+ }),
+ );
let (method, _maybe_diag): (String, Option<Value>) =
- client.read_notification().unwrap();
+ client.read_notification();
assert_eq!(method, "textDocument/publishDiagnostics");
let mut document_version: u64 = 0;
@@ -61,7 +56,7 @@ fn incremental_change_wait(bench: &mut Bencher) {
{"text": text, "range":{"start":{"line":509,"character":10},"end":{"line":509,"character":16}}}
]
})
- ).unwrap();
+ );
wait_for_deno_lint_diagnostic(document_version, &mut client);
@@ -75,7 +70,7 @@ fn wait_for_deno_lint_diagnostic(
) {
loop {
let (method, maybe_diag): (String, Option<Value>) =
- client.read_notification().unwrap();
+ client.read_notification();
if method == "textDocument/publishDiagnostics" {
let d = maybe_diag.unwrap();
let msg = d.as_object().unwrap();
diff --git a/cli/bench/main.rs b/cli/bench/main.rs
index 747407945..3bf73e78d 100644
--- a/cli/bench/main.rs
+++ b/cli/bench/main.rs
@@ -472,7 +472,7 @@ async fn main() -> Result<()> {
}
if benchmarks.contains(&"lsp") {
- let lsp_exec_times = lsp::benchmarks(&deno_exe)?;
+ let lsp_exec_times = lsp::benchmarks(&deno_exe);
new_data.lsp_exec_time = lsp_exec_times;
}
diff --git a/cli/tests/integration/lsp_tests.rs b/cli/tests/integration/lsp_tests.rs
index 344ba0804..981488a67 100644
--- a/cli/tests/integration/lsp_tests.rs
+++ b/cli/tests/integration/lsp_tests.rs
@@ -2,181 +2,20 @@
use deno_ast::ModuleSpecifier;
use deno_core::serde::Deserialize;
-use deno_core::serde::Serialize;
use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::url::Url;
use pretty_assertions::assert_eq;
-use std::collections::HashSet;
use std::fs;
use std::process::Stdio;
use test_util::deno_cmd_with_deno_dir;
use test_util::env_vars_for_npm_tests;
-use test_util::lsp::LspClient;
use test_util::lsp::LspClientBuilder;
use test_util::testdata_path;
use test_util::TestContextBuilder;
use tower_lsp::lsp_types as lsp;
-fn did_open<V>(
- client: &mut LspClient,
- params: V,
-) -> Vec<lsp::PublishDiagnosticsParams>
-where
- V: Serialize,
-{
- client
- .write_notification("textDocument/didOpen", params)
- .unwrap();
-
- handle_configuration_request(
- client,
- json!([{
- "enable": true,
- "codeLens": {
- "test": true
- }
- }]),
- );
- read_diagnostics(client).0
-}
-
-fn handle_configuration_request(client: &mut LspClient, result: Value) {
- let (id, method, _) = client.read_request::<Value>().unwrap();
- assert_eq!(method, "workspace/configuration");
- client.write_response(id, result).unwrap();
-}
-
-fn read_diagnostics(client: &mut LspClient) -> CollectedDiagnostics {
- // diagnostics come in batches of three unless they're cancelled
- let mut diagnostics = vec![];
- for _ in 0..3 {
- let (method, response) = client
- .read_notification::<lsp::PublishDiagnosticsParams>()
- .unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- diagnostics.push(response.unwrap());
- }
- CollectedDiagnostics(diagnostics)
-}
-
-// todo(dsherret): get rid of this in favour of LspClient
-struct TestSession {
- client: LspClient,
- open_file_count: usize,
-}
-
-impl TestSession {
- pub fn from_client(client: LspClient) -> Self {
- Self {
- client,
- open_file_count: 0,
- }
- }
-
- pub fn did_open<V>(&mut self, params: V) -> CollectedDiagnostics
- where
- V: Serialize,
- {
- self
- .client
- .write_notification("textDocument/didOpen", params)
- .unwrap();
-
- let (id, method, _) = self.client.read_request::<Value>().unwrap();
- assert_eq!(method, "workspace/configuration");
- self
- .client
- .write_response(
- id,
- json!([{
- "enable": true,
- "codeLens": {
- "test": true
- }
- }]),
- )
- .unwrap();
-
- self.open_file_count += 1;
- self.read_diagnostics()
- }
-
- pub fn read_diagnostics(&mut self) -> CollectedDiagnostics {
- let mut all_diagnostics = Vec::new();
- for _ in 0..self.open_file_count {
- all_diagnostics.extend(read_diagnostics(&mut self.client).0);
- }
- CollectedDiagnostics(all_diagnostics)
- }
-
- pub fn shutdown_and_exit(&mut self) {
- self.client.shutdown();
- }
-}
-
-#[derive(Debug, Clone)]
-struct CollectedDiagnostics(Vec<lsp::PublishDiagnosticsParams>);
-
-impl CollectedDiagnostics {
- /// Gets the diagnostics that the editor will see after all the publishes.
- pub fn viewed(&self) -> Vec<lsp::Diagnostic> {
- self
- .viewed_messages()
- .into_iter()
- .flat_map(|m| m.diagnostics)
- .collect()
- }
-
- /// Gets the messages that the editor will see after all the publishes.
- pub fn viewed_messages(&self) -> Vec<lsp::PublishDiagnosticsParams> {
- // go over the publishes in reverse order in order to get
- // the final messages that will be shown in the editor
- let mut messages = Vec::new();
- let mut had_specifier = HashSet::new();
- for message in self.0.iter().rev() {
- if had_specifier.insert(message.uri.clone()) {
- messages.insert(0, message.clone());
- }
- }
- messages
- }
-
- pub fn with_source(&self, source: &str) -> lsp::PublishDiagnosticsParams {
- self
- .viewed_messages()
- .iter()
- .find(|p| {
- p.diagnostics
- .iter()
- .any(|d| d.source == Some(source.to_string()))
- })
- .map(ToOwned::to_owned)
- .unwrap()
- }
-
- pub fn with_file_and_source(
- &self,
- specifier: &str,
- source: &str,
- ) -> lsp::PublishDiagnosticsParams {
- let specifier = ModuleSpecifier::parse(specifier).unwrap();
- self
- .viewed_messages()
- .iter()
- .find(|p| {
- p.uri == specifier
- && p
- .diagnostics
- .iter()
- .any(|d| d.source == Some(source.to_string()))
- })
- .map(ToOwned::to_owned)
- .unwrap()
- }
-}
-
#[test]
fn lsp_startup_shutdown() {
let mut client = LspClientBuilder::new().build();
@@ -203,20 +42,16 @@ fn lsp_init_tsconfig() {
builder.set_config("lib.tsconfig.json");
});
- let diagnostics = did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "location.pathname;\n"
- }
- }),
- );
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "location.pathname;\n"
+ }
+ }));
- let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
- assert_eq!(diagnostics.count(), 0);
+ assert_eq!(diagnostics.viewed().len(), 0);
client.shutdown();
}
@@ -247,20 +82,16 @@ fn lsp_tsconfig_types() {
builder.set_config("types.tsconfig.json");
});
- let diagnostics = did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": Url::from_file_path(temp_dir.path().join("test.ts")).unwrap(),
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(a);\n"
- }
- }),
- );
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": Url::from_file_path(temp_dir.path().join("test.ts")).unwrap(),
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(a);\n"
+ }
+ }));
- let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
- assert_eq!(diagnostics.count(), 0);
+ assert_eq!(diagnostics.viewed().len(), 0);
client.shutdown();
}
@@ -273,25 +104,21 @@ fn lsp_tsconfig_bad_config_path() {
.set_config("bad_tsconfig.json")
.set_maybe_root_uri(None);
});
- let (method, maybe_params) = client.read_notification().unwrap();
+ let (method, maybe_params) = client.read_notification();
assert_eq!(method, "window/showMessage");
assert_eq!(maybe_params, Some(lsp::ShowMessageParams {
typ: lsp::MessageType::WARNING,
message: "The path to the configuration file (\"bad_tsconfig.json\") is not resolvable.".to_string()
}));
- let diagnostics = did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Deno.args);\n"
- }
- }),
- );
- let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
- assert_eq!(diagnostics.count(), 0);
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Deno.args);\n"
+ }
+ }));
+ assert_eq!(diagnostics.viewed().len(), 0);
}
#[test]
@@ -303,20 +130,16 @@ fn lsp_triple_slash_types() {
let mut client = context.new_lsp_command().build();
client.initialize_default();
- let diagnostics = did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": temp_dir.uri().join("test.ts").unwrap(),
- "languageId": "typescript",
- "version": 1,
- "text": "/// <reference types=\"./a.d.ts\" />\n\nconsole.log(a);\n"
- }
- }),
- );
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": temp_dir.uri().join("test.ts").unwrap(),
+ "languageId": "typescript",
+ "version": 1,
+ "text": "/// <reference types=\"./a.d.ts\" />\n\nconsole.log(a);\n"
+ }
+ }));
- let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
- assert_eq!(diagnostics.count(), 0);
+ assert_eq!(diagnostics.viewed().len(), 0);
client.shutdown();
}
@@ -341,36 +164,29 @@ fn lsp_import_map() {
let uri = Url::from_file_path(temp_dir.path().join("a.ts")).unwrap();
- let diagnostics = did_open(
- &mut client,
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": uri,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n"
+ }
+ }));
+
+ assert_eq!(diagnostics.viewed().len(), 0);
+
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": uri,
- "languageId": "typescript",
- "version": 1,
- "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n"
- }
+ "uri": uri
+ },
+ "position": { "line": 2, "character": 12 }
}),
);
-
- let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
- assert_eq!(diagnostics.count(), 0);
-
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": uri
- },
- "position": { "line": 2, "character": 12 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -382,7 +198,7 @@ fn lsp_import_map() {
"start": { "line": 2, "character": 12 },
"end": { "line": 2, "character": 13 }
}
- }))
+ })
);
client.shutdown();
}
@@ -394,21 +210,17 @@ fn lsp_import_map_data_url() {
client.initialize(|builder| {
builder.set_import_map("data:application/json;utf8,{\"imports\": { \"example\": \"https://deno.land/x/example/mod.ts\" }}");
});
- let diagnostics = did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import example from \"example\";\n"
- }
- }),
- );
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import example from \"example\";\n"
+ }
+ }));
- let mut diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
// This indicates that the import map is applied correctly.
- assert!(diagnostics.any(|diagnostic| diagnostic.code
+ assert!(diagnostics.viewed().iter().any(|diagnostic| diagnostic.code
== Some(lsp::NumberOrString::String("no-cache".to_string()))
&& diagnostic
.message
@@ -444,36 +256,29 @@ fn lsp_import_map_config_file() {
let uri = temp_dir.uri().join("a.ts").unwrap();
- let diagnostics = did_open(
- &mut client,
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": uri,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n"
+ }
+ }));
+
+ assert_eq!(diagnostics.viewed().len(), 0);
+
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": uri,
- "languageId": "typescript",
- "version": 1,
- "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n"
- }
+ "uri": uri
+ },
+ "position": { "line": 2, "character": 12 }
}),
);
-
- let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
- assert_eq!(diagnostics.count(), 0);
-
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": uri
- },
- "position": { "line": 2, "character": 12 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -485,7 +290,7 @@ fn lsp_import_map_config_file() {
"start": { "line": 2, "character": 12 },
"end": { "line": 2, "character": 13 }
}
- }))
+ })
);
client.shutdown();
}
@@ -512,36 +317,29 @@ fn lsp_import_map_embedded_in_config_file() {
let uri = temp_dir.uri().join("a.ts").unwrap();
- let diagnostics = did_open(
- &mut client,
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": uri,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n"
+ }
+ }));
+
+ assert_eq!(diagnostics.viewed().len(), 0);
+
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": uri,
- "languageId": "typescript",
- "version": 1,
- "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n"
- }
+ "uri": uri
+ },
+ "position": { "line": 2, "character": 12 }
}),
);
-
- let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics);
- assert_eq!(diagnostics.count(), 0);
-
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": uri
- },
- "position": { "line": 2, "character": 12 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -553,7 +351,7 @@ fn lsp_import_map_embedded_in_config_file() {
"start": { "line": 2, "character": 12 },
"end": { "line": 2, "character": 13 }
}
- }))
+ })
);
client.shutdown();
}
@@ -577,14 +375,11 @@ fn lsp_deno_task() {
builder.set_config("./deno.jsonc");
});
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>("deno/task", json!(null))
- .unwrap();
+ let res = client.write_request("deno/task", json!(null));
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([
+ res,
+ json!([
{
"name": "build",
"detail": "deno test"
@@ -592,7 +387,7 @@ fn lsp_deno_task() {
"name": "some:test",
"detail": "deno bundle mod.ts"
}
- ]))
+ ])
);
}
@@ -604,21 +399,15 @@ fn lsp_import_assertions() {
builder.set_import_map("data:application/json;utf8,{\"imports\": { \"example\": \"https://deno.land/x/example/mod.ts\" }}");
});
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": "file:///a/test.json",
- "languageId": "json",
- "version": 1,
- "text": "{\"a\":1}"
- }
- }),
- )
- .unwrap();
- handle_configuration_request(
- &mut client,
+ client.did_open_with_config(
+ json!({
+ "textDocument": {
+ "uri": "file:///a/test.json",
+ "languageId": "json",
+ "version": 1,
+ "text": "{\"a\":1}"
+ }
+ }),
json!([{
"enable": true,
"codeLens": {
@@ -627,17 +416,14 @@ fn lsp_import_assertions() {
}]),
);
- let diagnostics = CollectedDiagnostics(did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/a.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import a from \"./test.json\";\n\nconsole.log(a);\n"
- }
- }),
- ));
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/a.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import a from \"./test.json\";\n\nconsole.log(a);\n"
+ }
+ }));
assert_eq!(
json!(
@@ -659,7 +445,7 @@ fn lsp_import_assertions() {
])
);
- let (maybe_res, maybe_err) = client
+ let res = client
.write_request(
"textDocument/codeAction",
json!({
@@ -685,11 +471,10 @@ fn lsp_import_assertions() {
}
}),
)
- .unwrap();
- assert!(maybe_err.is_none());
+ ;
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Insert import assertion.",
"kind": "quickfix",
"diagnostics": [
@@ -717,7 +502,7 @@ fn lsp_import_assertions() {
]
}
}
- }]))
+ }])
);
client.shutdown();
}
@@ -746,37 +531,26 @@ fn lsp_import_map_import_completions() {
let uri = temp_dir.uri().join("a.ts").unwrap();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": uri,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import * as a from \"/~/b.ts\";\nimport * as b from \"\""
+ }
+ }));
+
+ let res = client.get_completion(
+ &uri,
+ (1, 20),
json!({
- "textDocument": {
- "uri": uri,
- "languageId": "typescript",
- "version": 1,
- "text": "import * as a from \"/~/b.ts\";\nimport * as b from \"\""
- }
+ "triggerKind": 2,
+ "triggerCharacter": "\""
}),
);
-
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": uri
- },
- "position": { "line": 1, "character": 20 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "\""
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ json!(res),
+ json!({
"isIncomplete": false,
"items": [
{
@@ -816,55 +590,39 @@ fn lsp_import_map_import_completions() {
"commitCharacters": ["\"", "'"],
}
]
- }))
+ })
);
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": uri,
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 1, "character": 20 },
- "end": { "line": 1, "character": 20 }
- },
- "text": "/~/"
- }
- ]
- }),
- )
- .unwrap();
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
-
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": uri
- },
- "position": { "line": 1, "character": 23 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "/"
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": uri,
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 1, "character": 20 },
+ "end": { "line": 1, "character": 20 }
+ },
+ "text": "/~/"
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ ]
+ }),
+ );
+
+ let res = client.get_completion(
+ uri,
+ (1, 23),
+ json!({
+ "triggerKind": 2,
+ "triggerCharacter": "/"
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ json!(res),
+ json!({
"isIncomplete": false,
"items": [
{
@@ -883,7 +641,7 @@ fn lsp_import_map_import_completions() {
"commitCharacters": ["\"", "'"],
}
]
- }))
+ })
);
client.shutdown();
@@ -893,32 +651,26 @@ fn lsp_import_map_import_completions() {
fn lsp_hover() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Deno.args);\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Deno.args);\n"
- }
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 19 }
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -931,7 +683,7 @@ fn lsp_hover() {
"start": { "line": 0, "character": 17 },
"end": { "line": 0, "character": 21 }
}
- }))
+ })
);
client.shutdown();
}
@@ -940,55 +692,43 @@ fn lsp_hover() {
fn lsp_hover_asset() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Date.now());\n"
+ }
+ }));
+ client.write_request(
+ "textDocument/definition",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Date.now());\n"
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 14 }
+ }),
+ );
+ client.write_request(
+ "deno/virtualTextDocument",
+ json!({
+ "textDocument": {
+ "uri": "deno:/asset/lib.deno.shared_globals.d.ts"
}
}),
);
- let (_, maybe_error) = client
- .write_request::<_, _, Value>(
- "textDocument/definition",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 14 }
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
- let (_, maybe_error) = client
- .write_request::<_, _, Value>(
- "deno/virtualTextDocument",
- json!({
- "textDocument": {
- "uri": "deno:/asset/lib.deno.shared_globals.d.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "deno:/asset/lib.es2015.symbol.wellknown.d.ts"
- },
- "position": { "line": 109, "character": 13 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "deno:/asset/lib.es2015.symbol.wellknown.d.ts"
+ },
+ "position": { "line": 109, "character": 13 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1000,7 +740,7 @@ fn lsp_hover_asset() {
"start": { "line": 109, "character": 10, },
"end": { "line": 109, "character": 14, }
}
- }))
+ })
);
client.shutdown();
}
@@ -1012,35 +752,28 @@ fn lsp_hover_disabled() {
client.initialize(|builder| {
builder.set_deno_enable(false);
});
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Date.now());\n"
- }
- }),
- )
- .unwrap();
-
- handle_configuration_request(&mut client, json!([{ "enable": false }]));
+ client.did_open_with_config(
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Date.now());\n"
+ }
+ }),
+ json!([{ "enable": false }]),
+ );
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 19 }
+ }),
+ );
+ assert_eq!(res, json!(null));
client.shutdown();
}
@@ -1051,14 +784,12 @@ fn lsp_inlay_hints() {
client.initialize(|builder| {
builder.enable_inlay_hints();
});
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": r#"function a(b: string) {
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": r#"function a(b: string) {
return b;
}
@@ -1078,26 +809,22 @@ fn lsp_inlay_hints() {
["a"].map((v) => v + v);
"#
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/inlayHint",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "range": {
+ "start": { "line": 0, "character": 0 },
+ "end": { "line": 19, "character": 0, }
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/inlayHint",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "range": {
- "start": { "line": 0, "character": 0 },
- "end": { "line": 19, "character": 0, }
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- json!(maybe_res),
+ res,
json!([
{
"position": { "line": 0, "character": 21 },
@@ -1157,14 +884,12 @@ fn lsp_inlay_hints() {
fn lsp_inlay_hints_not_enabled() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": r#"function a(b: string) {
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": r#"function a(b: string) {
return b;
}
@@ -1184,25 +909,21 @@ fn lsp_inlay_hints_not_enabled() {
["a"].map((v) => v + v);
"#
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/inlayHint",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "range": {
+ "start": { "line": 0, "character": 0 },
+ "end": { "line": 19, "character": 0, }
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/inlayHint",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "range": {
- "start": { "line": 0, "character": 0 },
- "end": { "line": 19, "character": 0, }
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(json!(maybe_res), json!(null));
+ assert_eq!(res, json!(null));
}
#[test]
@@ -1227,105 +948,81 @@ fn lsp_workspace_enable_paths() {
.set_deno_enable(false);
});
- handle_configuration_request(
- &mut client,
- json!([{
- "enable": false,
- "enablePaths": ["./worker"],
- }]),
- );
+ client.handle_configuration_request(json!([{
+ "enable": false,
+ "enablePaths": ["./worker"],
+ }]));
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": root_specifier.join("./file.ts").unwrap(),
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Date.now());\n"
+ }
+ }));
+
+ client.did_open(json!({
+ "textDocument": {
+ "uri": root_specifier.join("./other/file.ts").unwrap(),
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Date.now());\n"
+ }
+ }));
+
+ client.did_open(json!({
+ "textDocument": {
+ "uri": root_specifier.join("./worker/file.ts").unwrap(),
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Date.now());\n"
+ }
+ }));
+
+ client.did_open(json!({
+ "textDocument": {
+ "uri": root_specifier.join("./worker/subdir/file.ts").unwrap(),
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Date.now());\n"
+ }
+ }));
+
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
"uri": root_specifier.join("./file.ts").unwrap(),
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Date.now());\n"
- }
+ },
+ "position": { "line": 0, "character": 19 }
}),
);
+ assert_eq!(res, json!(null));
- did_open(
- &mut client,
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
"uri": root_specifier.join("./other/file.ts").unwrap(),
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Date.now());\n"
- }
+ },
+ "position": { "line": 0, "character": 19 }
}),
);
+ assert_eq!(res, json!(null));
- did_open(
- &mut client,
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
"uri": root_specifier.join("./worker/file.ts").unwrap(),
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Date.now());\n"
- }
- }),
- );
-
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": root_specifier.join("./worker/subdir/file.ts").unwrap(),
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Date.now());\n"
- }
+ },
+ "position": { "line": 0, "character": 19 }
}),
);
-
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": root_specifier.join("./file.ts").unwrap(),
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
-
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": root_specifier.join("./other/file.ts").unwrap(),
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
-
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": root_specifier.join("./worker/file.ts").unwrap(),
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1337,24 +1034,21 @@ fn lsp_workspace_enable_paths() {
"start": { "line": 0, "character": 17, },
"end": { "line": 0, "character": 20, }
}
- }))
+ })
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": root_specifier.join("./worker/subdir/file.ts").unwrap(),
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": root_specifier.join("./worker/subdir/file.ts").unwrap(),
+ },
+ "position": { "line": 0, "character": 19 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1366,7 +1060,7 @@ fn lsp_workspace_enable_paths() {
"start": { "line": 0, "character": 17, },
"end": { "line": 0, "character": 20, }
}
- }))
+ })
);
client.shutdown();
@@ -1376,32 +1070,26 @@ fn lsp_workspace_enable_paths() {
fn lsp_hover_unstable_disabled() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Deno.dlopen);\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Deno.dlopen);\n"
- }
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 19 }
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1412,7 +1100,7 @@ fn lsp_hover_unstable_disabled() {
"start": { "line": 0, "character": 17 },
"end": { "line": 0, "character": 23 }
}
- }))
+ })
);
client.shutdown();
}
@@ -1423,32 +1111,26 @@ fn lsp_hover_unstable_enabled() {
client.initialize(|builder| {
builder.set_unstable(true);
});
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Deno.ppid);\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Deno.ppid);\n"
- }
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 19 }
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents":[
{
"language":"typescript",
@@ -1461,7 +1143,7 @@ fn lsp_hover_unstable_enabled() {
"start":{ "line":0, "character":17 },
"end":{ "line":0, "character":21 }
}
- }))
+ })
);
client.shutdown();
}
@@ -1470,8 +1152,7 @@ fn lsp_hover_unstable_enabled() {
fn lsp_hover_change_mbc() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -1481,52 +1162,41 @@ fn lsp_hover_change_mbc() {
}
}),
);
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 1, "character": 11 },
- "end": {
- "line": 1,
- // the LSP uses utf16 encoded characters indexes, so
- // after the deno emoiji is character index 15
- "character": 15
- }
- },
- "text": ""
- }
- ]
- }),
- )
- .unwrap();
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 2, "character": 15 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 1, "character": 11 },
+ "end": {
+ "line": 1,
+ // the LSP uses utf16 encoded characters indexes, so
+ // after the deno emoiji is character index 15
+ "character": 15
+ }
+ },
+ "text": ""
+ }
+ ]
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 2, "character": 15 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1538,7 +1208,7 @@ fn lsp_hover_change_mbc() {
"start": { "line": 2, "character": 15, },
"end": { "line": 2, "character": 16, },
}
- }))
+ })
);
client.shutdown();
}
@@ -1556,65 +1226,36 @@ fn lsp_hover_closed_document() {
let mut client = context.new_lsp_command().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": b_specifier,
- "languageId": "typescript",
- "version": 1,
- "text": r#"export * from "./a.ts";"#
- }
- }),
- )
- .unwrap();
- let (id, method, _) = client.read_request::<Value>().unwrap();
- assert_eq!(method, "workspace/configuration");
- client
- .write_response(id, json!([{ "enable": true }]))
- .unwrap();
+ client.did_open(json!({
+ "textDocument": {
+ "uri": b_specifier,
+ "languageId": "typescript",
+ "version": 1,
+ "text": r#"export * from "./a.ts";"#
+ }
+ }));
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": c_specifier,
- "languageId": "typescript",
- "version": 1,
- "text": "import { a } from \"./b.ts\";\nconsole.log(a);\n",
- }
- }),
- )
- .unwrap();
- let (id, method, _) = client.read_request::<Value>().unwrap();
- assert_eq!(method, "workspace/configuration");
- client
- .write_response(id, json!([{ "enable": true }]))
- .unwrap();
+ client.did_open(json!({
+ "textDocument": {
+ "uri": c_specifier,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import { a } from \"./b.ts\";\nconsole.log(a);\n",
+ }
+ }));
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": c_specifier,
- },
- "position": { "line": 0, "character": 10 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": c_specifier,
+ },
+ "position": { "line": 0, "character": 10 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1626,33 +1267,28 @@ fn lsp_hover_closed_document() {
"start": { "line": 0, "character": 9 },
"end": { "line": 0, "character": 10 }
}
- }))
+ })
+ );
+ client.write_notification(
+ "textDocument/didClose",
+ json!({
+ "textDocument": {
+ "uri": b_specifier,
+ }
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": c_specifier,
+ },
+ "position": { "line": 0, "character": 10 }
+ }),
);
- client
- .write_notification(
- "textDocument/didClose",
- json!({
- "textDocument": {
- "uri": b_specifier,
- }
- }),
- )
- .unwrap();
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": c_specifier,
- },
- "position": { "line": 0, "character": 10 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1664,7 +1300,7 @@ fn lsp_hover_closed_document() {
"start": { "line": 0, "character": 9 },
"end": { "line": 0, "character": 10 }
}
- }))
+ })
);
client.shutdown();
}
@@ -1674,56 +1310,45 @@ fn lsp_hover_dependency() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file_01.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "export const a = \"a\";\n",
+ }
+ }));
+ client.did_open(
json!({
"textDocument": {
- "uri": "file:///a/file_01.ts",
+ "uri": "file:///a/file.ts",
"languageId": "typescript",
"version": 1,
- "text": "export const a = \"a\";\n",
+ "text": "import * as a from \"http://127.0.0.1:4545/xTypeScriptTypes.js\";\n// @deno-types=\"http://127.0.0.1:4545/type_definitions/foo.d.ts\"\nimport * as b from \"http://127.0.0.1:4545/type_definitions/foo.js\";\nimport * as c from \"http://127.0.0.1:4545/subdir/type_reference.js\";\nimport * as d from \"http://127.0.0.1:4545/subdir/mod1.ts\";\nimport * as e from \"data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=\";\nimport * as f from \"./file_01.ts\";\nimport * as g from \"http://localhost:4545/x/a/mod.ts\";\n\nconsole.log(a, b, c, d, e, f, g);\n"
}
}),
);
- did_open(
- &mut client,
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [],
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
"uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import * as a from \"http://127.0.0.1:4545/xTypeScriptTypes.js\";\n// @deno-types=\"http://127.0.0.1:4545/type_definitions/foo.d.ts\"\nimport * as b from \"http://127.0.0.1:4545/type_definitions/foo.js\";\nimport * as c from \"http://127.0.0.1:4545/subdir/type_reference.js\";\nimport * as d from \"http://127.0.0.1:4545/subdir/mod1.ts\";\nimport * as e from \"data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=\";\nimport * as f from \"./file_01.ts\";\nimport * as g from \"http://localhost:4545/x/a/mod.ts\";\n\nconsole.log(a, b, c, d, e, f, g);\n"
- }
+ },
+ "position": { "line": 0, "character": 28 }
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [],
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 0, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: http&#8203;://127.0.0.1:4545/xTypeScriptTypes.js\n\n**Types**: http&#8203;://127.0.0.1:4545/xTypeScriptTypes.d.ts\n"
@@ -1732,23 +1357,20 @@ fn lsp_hover_dependency() {
"start": { "line": 0, "character": 19 },
"end":{ "line": 0, "character": 62 }
}
- }))
+ })
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 3, "character": 28 }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 3, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: http&#8203;://127.0.0.1:4545/subdir/type_reference.js\n\n**Types**: http&#8203;://127.0.0.1:4545/subdir/type_reference.d.ts\n"
@@ -1757,23 +1379,20 @@ fn lsp_hover_dependency() {
"start": { "line": 3, "character": 19 },
"end":{ "line": 3, "character": 67 }
}
- }))
+ })
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 4, "character": 28 }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 4, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: http&#8203;://127.0.0.1:4545/subdir/mod1.ts\n"
@@ -1782,23 +1401,20 @@ fn lsp_hover_dependency() {
"start": { "line": 4, "character": 19 },
"end":{ "line": 4, "character": 57 }
}
- }))
+ })
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 5, "character": 28 }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 5, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: _(a data url)_\n"
@@ -1807,23 +1423,20 @@ fn lsp_hover_dependency() {
"start": { "line": 5, "character": 19 },
"end":{ "line": 5, "character": 132 }
}
- }))
+ })
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 6, "character": 28 }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 6, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: file&#8203;:///a/file_01.ts\n"
@@ -1832,7 +1445,7 @@ fn lsp_hover_dependency() {
"start": { "line": 6, "character": 19 },
"end":{ "line": 6, "character": 33 }
}
- }))
+ })
);
}
@@ -1842,43 +1455,34 @@ fn lsp_hover_dependency() {
fn lsp_hover_deps_preserved_when_invalid_parse() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file1.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "export type Foo = { bar(): string };\n"
- }
- }),
- );
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file1.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "export type Foo = { bar(): string };\n"
+ }
+ }));
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file2.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import { Foo } from './file1.ts'; declare const f: Foo; f\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": "file:///a/file2.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import { Foo } from './file1.ts'; declare const f: Foo; f\n"
- }
+ "uri": "file:///a/file2.ts"
+ },
+ "position": { "line": 0, "character": 56 }
}),
);
- let (maybe_res, maybe_error) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file2.ts"
- },
- "position": { "line": 0, "character": 56 }
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1890,43 +1494,38 @@ fn lsp_hover_deps_preserved_when_invalid_parse() {
"start": { "line": 0, "character": 56, },
"end": { "line": 0, "character": 57, }
}
- }))
+ })
+ );
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file2.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 0, "character": 57 },
+ "end": { "line": 0, "character": 58 }
+ },
+ "text": "."
+ }
+ ]
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file2.ts"
+ },
+ "position": { "line": 0, "character": 56 }
+ }),
);
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file2.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 0, "character": 57 },
- "end": { "line": 0, "character": 58 }
- },
- "text": "."
- }
- ]
- }),
- )
- .unwrap();
- let (maybe_res, maybe_error) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file2.ts"
- },
- "position": { "line": 0, "character": 56 }
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -1938,7 +1537,7 @@ fn lsp_hover_deps_preserved_when_invalid_parse() {
"start": { "line": 0, "character": 56, },
"end": { "line": 0, "character": 57, }
}
- }))
+ })
);
client.shutdown();
}
@@ -1948,8 +1547,7 @@ fn lsp_hover_typescript_types() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -1959,38 +1557,30 @@ fn lsp_hover_typescript_types() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [
- {
- "uri": "http://127.0.0.1:4545/xTypeScriptTypes.js",
- }
- ],
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 24 }
- }),
- )
- .unwrap();
- assert!(maybe_res.is_some());
- assert!(maybe_err.is_none());
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [
+ {
+ "uri": "http://127.0.0.1:4545/xTypeScriptTypes.js",
+ }
+ ],
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 24 }
+ }),
+ );
assert_eq!(
- json!(maybe_res.unwrap()),
+ res,
json!({
"contents": {
"kind": "markdown",
@@ -2009,43 +1599,36 @@ fn lsp_hover_typescript_types() {
fn lsp_hover_jsdoc_symbol_link() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/b.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "export function hello() {}\n"
+ }
+ }));
+ client.did_open(
json!({
"textDocument": {
- "uri": "file:///a/b.ts",
+ "uri": "file:///a/file.ts",
"languageId": "typescript",
"version": 1,
- "text": "export function hello() {}\n"
+ "text": "import { hello } from \"./b.ts\";\n\nhello();\n\nconst b = \"b\";\n\n/** JSDoc {@link hello} and {@linkcode b} */\nfunction a() {}\n"
}
}),
);
- did_open(
- &mut client,
+ let res = client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import { hello } from \"./b.ts\";\n\nhello();\n\nconst b = \"b\";\n\n/** JSDoc {@link hello} and {@linkcode b} */\nfunction a() {}\n"
- }
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 7, "character": 10 }
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 7, "character": 10 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": [
{
"language": "typescript",
@@ -2057,7 +1640,7 @@ fn lsp_hover_jsdoc_symbol_link() {
"start": { "line": 7, "character": 9 },
"end": { "line": 7, "character": 10 }
}
- }))
+ })
);
client.shutdown();
}
@@ -2066,8 +1649,7 @@ fn lsp_hover_jsdoc_symbol_link() {
fn lsp_goto_type_definition() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2077,21 +1659,18 @@ fn lsp_goto_type_definition() {
}
}),
);
- let (maybe_res, maybe_error) = client
- .write_request::<_, _, Value>(
- "textDocument/typeDefinition",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 12, "character": 1 }
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
+ let res = client.write_request(
+ "textDocument/typeDefinition",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 12, "character": 1 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([
+ res,
+ json!([
{
"targetUri": "file:///a/file.ts",
"targetRange": {
@@ -2103,7 +1682,7 @@ fn lsp_goto_type_definition() {
"end": { "line": 4, "character": 14 }
}
}
- ]))
+ ])
);
client.shutdown();
}
@@ -2112,8 +1691,7 @@ fn lsp_goto_type_definition() {
fn lsp_call_hierarchy() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2123,21 +1701,18 @@ fn lsp_call_hierarchy() {
}
}),
);
- let (maybe_res, maybe_error) = client
- .write_request(
- "textDocument/prepareCallHierarchy",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 5, "character": 3 }
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
+ let res = client.write_request(
+ "textDocument/prepareCallHierarchy",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 5, "character": 3 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"name": "baz",
"kind": 6,
"detail": "Bar",
@@ -2150,33 +1725,30 @@ fn lsp_call_hierarchy() {
"start": { "line": 5, "character": 2 },
"end": { "line": 5, "character": 5 }
}
- }]))
+ }])
);
- let (maybe_res, maybe_error) = client
- .write_request(
- "callHierarchy/incomingCalls",
- json!({
- "item": {
- "name": "baz",
- "kind": 6,
- "detail": "Bar",
- "uri": "file:///a/file.ts",
- "range": {
- "start": { "line": 5, "character": 2 },
- "end": { "line": 7, "character": 3 }
- },
- "selectionRange": {
- "start": { "line": 5, "character": 2 },
- "end": { "line": 5, "character": 5 }
- }
+ let res = client.write_request(
+ "callHierarchy/incomingCalls",
+ json!({
+ "item": {
+ "name": "baz",
+ "kind": 6,
+ "detail": "Bar",
+ "uri": "file:///a/file.ts",
+ "range": {
+ "start": { "line": 5, "character": 2 },
+ "end": { "line": 7, "character": 3 }
+ },
+ "selectionRange": {
+ "start": { "line": 5, "character": 2 },
+ "end": { "line": 5, "character": 5 }
}
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"from": {
"name": "main",
"kind": 12,
@@ -2197,33 +1769,30 @@ fn lsp_call_hierarchy() {
"end": { "line": 12, "character": 9 }
}
]
- }]))
+ }])
);
- let (maybe_res, maybe_error) = client
- .write_request(
- "callHierarchy/outgoingCalls",
- json!({
- "item": {
- "name": "baz",
- "kind": 6,
- "detail": "Bar",
- "uri": "file:///a/file.ts",
- "range": {
- "start": { "line": 5, "character": 2 },
- "end": { "line": 7, "character": 3 }
- },
- "selectionRange": {
- "start": { "line": 5, "character": 2 },
- "end": { "line": 5, "character": 5 }
- }
+ let res = client.write_request(
+ "callHierarchy/outgoingCalls",
+ json!({
+ "item": {
+ "name": "baz",
+ "kind": 6,
+ "detail": "Bar",
+ "uri": "file:///a/file.ts",
+ "range": {
+ "start": { "line": 5, "character": 2 },
+ "end": { "line": 7, "character": 3 }
+ },
+ "selectionRange": {
+ "start": { "line": 5, "character": 2 },
+ "end": { "line": 5, "character": 5 }
}
- }),
- )
- .unwrap();
- assert!(maybe_error.is_none());
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"to": {
"name": "foo",
"kind": 12,
@@ -2242,7 +1811,7 @@ fn lsp_call_hierarchy() {
"start": { "line": 6, "character": 11 },
"end": { "line": 6, "character": 14 }
}]
- }]))
+ }])
);
client.shutdown();
}
@@ -2254,116 +1823,95 @@ fn lsp_large_doc_changes() {
let large_file_text =
fs::read_to_string(testdata_path().join("lsp").join("large_file.txt"))
.unwrap();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "javascript",
+ "version": 1,
+ "text": large_file_text,
+ }
+ }));
+ client.write_notification(
+ "textDocument/didChange",
json!({
"textDocument": {
"uri": "file:///a/file.ts",
- "languageId": "javascript",
- "version": 1,
- "text": large_file_text,
- }
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 444, "character": 11 },
+ "end": { "line": 444, "character": 14 }
+ },
+ "text": "+++"
+ }
+ ]
+ }),
+ );
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 445, "character": 4 },
+ "end": { "line": 445, "character": 4 }
+ },
+ "text": "// "
+ }
+ ]
+ }),
+ );
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 477, "character": 4 },
+ "end": { "line": 477, "character": 9 }
+ },
+ "text": "error"
+ }
+ ]
+ }),
+ );
+ client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 421, "character": 30 }
+ }),
+ );
+ client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 444, "character": 6 }
+ }),
+ );
+ client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 461, "character": 34 }
}),
);
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 444, "character": 11 },
- "end": { "line": 444, "character": 14 }
- },
- "text": "+++"
- }
- ]
- }),
- )
- .unwrap();
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 445, "character": 4 },
- "end": { "line": 445, "character": 4 }
- },
- "text": "// "
- }
- ]
- }),
- )
- .unwrap();
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 477, "character": 4 },
- "end": { "line": 477, "character": 9 }
- },
- "text": "error"
- }
- ]
- }),
- )
- .unwrap();
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 421, "character": 30 }
- }),
- )
- .unwrap();
- assert!(maybe_res.is_some());
- assert!(maybe_err.is_none());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 444, "character": 6 }
- }),
- )
- .unwrap();
- assert!(maybe_res.is_some());
- assert!(maybe_err.is_none());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 461, "character": 34 }
- }),
- )
- .unwrap();
- assert!(maybe_res.is_some());
- assert!(maybe_err.is_none());
client.shutdown();
assert!(client.duration().as_millis() <= 15000);
@@ -2373,8 +1921,7 @@ fn lsp_large_doc_changes() {
fn lsp_document_symbol() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2384,20 +1931,17 @@ fn lsp_document_symbol() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/documentSymbol",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/documentSymbol",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"name": "bar",
"kind": 13,
"range": {
@@ -2567,7 +2111,7 @@ fn lsp_document_symbol() {
}
}]
}]
- ))
+ )
);
client.shutdown();
}
@@ -2576,8 +2120,7 @@ fn lsp_document_symbol() {
fn lsp_folding_range() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2587,20 +2130,17 @@ fn lsp_folding_range() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/foldingRange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/foldingRange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"startLine": 0,
"endLine": 12,
"kind": "region"
@@ -2617,7 +2157,7 @@ fn lsp_folding_range() {
}, {
"startLine": 6,
"endLine": 7
- }]))
+ }])
);
client.shutdown();
}
@@ -2626,8 +2166,7 @@ fn lsp_folding_range() {
fn lsp_rename() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2638,22 +2177,19 @@ fn lsp_rename() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/rename",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 4 },
- "newName": "variable_modified"
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/rename",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 4 },
+ "newName": "variable_modified"
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"documentChanges": [{
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2673,7 +2209,7 @@ fn lsp_rename() {
"newText": "variable_modified"
}]
}]
- }))
+ })
);
client.shutdown();
}
@@ -2682,8 +2218,7 @@ fn lsp_rename() {
fn lsp_selection_range() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2693,21 +2228,18 @@ fn lsp_selection_range() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/selectionRange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "positions": [{ "line": 2, "character": 8 }]
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/selectionRange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "positions": [{ "line": 2, "character": 8 }]
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"range": {
"start": { "line": 2, "character": 8 },
"end": { "line": 2, "character": 9 }
@@ -2754,7 +2286,7 @@ fn lsp_selection_range() {
}
}
}
- }]))
+ }])
);
client.shutdown();
}
@@ -2763,8 +2295,7 @@ fn lsp_selection_range() {
fn lsp_semantic_tokens() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2774,20 +2305,17 @@ fn lsp_semantic_tokens() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/semanticTokens/full",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/semanticTokens/full",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"data": [
0, 5, 6, 1, 1, 0, 9, 6, 8, 9, 0, 8, 6, 8, 9, 2, 15, 3, 10, 5, 0, 4, 1,
6, 1, 0, 12, 7, 2, 16, 1, 8, 1, 7, 41, 0, 4, 1, 6, 0, 0, 2, 5, 11, 16,
@@ -2795,32 +2323,29 @@ fn lsp_semantic_tokens() {
0, 1, 0, 15, 4, 2, 0, 1, 30, 1, 6, 9, 1, 2, 3, 11,1, 1, 9, 9, 9, 3, 0,
16, 3, 0, 0, 1, 17, 12, 11, 3, 0, 24, 3, 0, 0, 0, 4, 9, 9, 2
]
- }))
+ })
+ );
+ let res = client.write_request(
+ "textDocument/semanticTokens/range",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 0, "character": 0 },
+ "end": { "line": 6, "character": 0 }
+ }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/semanticTokens/range",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 0, "character": 0 },
- "end": { "line": 6, "character": 0 }
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"data": [
0, 5, 6, 1, 1, 0, 9, 6, 8, 9, 0, 8, 6, 8, 9, 2, 15, 3, 10, 5, 0, 4, 1,
6, 1, 0, 12, 7, 2, 16, 1, 8, 1, 7, 41, 0, 4, 1, 6, 0, 0, 2, 5, 11, 16,
1, 9, 1, 7, 40
]
- }))
+ })
);
client.shutdown();
}
@@ -2829,8 +2354,7 @@ fn lsp_semantic_tokens() {
fn lsp_code_lens() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2840,20 +2364,17 @@ fn lsp_code_lens() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"range": {
"start": { "line": 0, "character": 6 },
"end": { "line": 0, "character": 7 }
@@ -2871,27 +2392,24 @@ fn lsp_code_lens() {
"specifier": "file:///a/file.ts",
"source": "references"
}
- }]))
+ }])
+ );
+ let res = client.write_request(
+ "codeLens/resolve",
+ json!({
+ "range": {
+ "start": { "line": 0, "character": 6 },
+ "end": { "line": 0, "character": 7 }
+ },
+ "data": {
+ "specifier": "file:///a/file.ts",
+ "source": "references"
+ }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "codeLens/resolve",
- json!({
- "range": {
- "start": { "line": 0, "character": 6 },
- "end": { "line": 0, "character": 7 }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "references"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"range": {
"start": { "line": 0, "character": 6 },
"end": { "line": 0, "character": 7 }
@@ -2917,7 +2435,7 @@ fn lsp_code_lens() {
}]
]
}
- }))
+ })
);
client.shutdown();
}
@@ -2926,8 +2444,7 @@ fn lsp_code_lens() {
fn lsp_code_lens_impl() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -2937,20 +2454,17 @@ fn lsp_code_lens_impl() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([ {
+ res,
+ json!([ {
"range": {
"start": { "line": 0, "character": 10 },
"end": { "line": 0, "character": 11 }
@@ -3004,27 +2518,24 @@ fn lsp_code_lens_impl() {
"specifier": "file:///a/file.ts",
"source": "references"
}
- }]))
+ }])
+ );
+ let res = client.write_request(
+ "codeLens/resolve",
+ json!({
+ "range": {
+ "start": { "line": 0, "character": 10 },
+ "end": { "line": 0, "character": 11 }
+ },
+ "data": {
+ "specifier": "file:///a/file.ts",
+ "source": "implementations"
+ }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "codeLens/resolve",
- json!({
- "range": {
- "start": { "line": 0, "character": 10 },
- "end": { "line": 0, "character": 11 }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "implementations"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"range": {
"start": { "line": 0, "character": 10 },
"end": { "line": 0, "character": 11 }
@@ -3044,27 +2555,24 @@ fn lsp_code_lens_impl() {
}]
]
}
- }))
+ })
+ );
+ let res = client.write_request(
+ "codeLens/resolve",
+ json!({
+ "range": {
+ "start": { "line": 10, "character": 10 },
+ "end": { "line": 10, "character": 11 }
+ },
+ "data": {
+ "specifier": "file:///a/file.ts",
+ "source": "implementations"
+ }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "codeLens/resolve",
- json!({
- "range": {
- "start": { "line": 10, "character": 10 },
- "end": { "line": 10, "character": 11 }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "implementations"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"range": {
"start": { "line": 10, "character": 10 },
"end": { "line": 10, "character": 11 }
@@ -3073,7 +2581,7 @@ fn lsp_code_lens_impl() {
"title": "0 implementations",
"command": ""
}
- }))
+ })
);
client.shutdown();
}
@@ -3084,8 +2592,7 @@ fn lsp_code_lens_test() {
client.initialize(|builder| {
builder.disable_testing_api().set_code_lens(None);
});
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -3095,20 +2602,17 @@ fn lsp_code_lens_test() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"range": {
"start": { "line": 4, "character": 5 },
"end": { "line": 4, "character": 9 }
@@ -3332,7 +2836,7 @@ fn lsp_code_lens_test() {
{ "inspect": true }
]
}
- }]))
+ }])
);
client.shutdown();
}
@@ -3348,8 +2852,7 @@ fn lsp_code_lens_test_disabled() {
})));
});
client
- .write_notification(
- "textDocument/didOpen",
+ .did_open_with_config(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -3358,41 +2861,23 @@ fn lsp_code_lens_test_disabled() {
"text": "const { test } = Deno;\nconst { test: test2 } = Deno;\nconst test3 = Deno.test;\n\nDeno.test(\"test a\", () => {});\nDeno.test({\n name: \"test b\",\n fn() {},\n});\ntest({\n name: \"test c\",\n fn() {},\n});\ntest(\"test d\", () => {});\ntest2({\n name: \"test e\",\n fn() {},\n});\ntest2(\"test f\", () => {});\ntest3({\n name: \"test g\",\n fn() {},\n});\ntest3(\"test h\", () => {});\n"
}
}),
- )
- .unwrap();
-
- let (id, method, _) = client.read_request::<Value>().unwrap();
- assert_eq!(method, "workspace/configuration");
- client
- .write_response(
- id,
+ // diable test code lens
json!([{
"enable": true,
"codeLens": {
"test": false
}
}]),
- )
- .unwrap();
-
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (method, _) = client.read_notification::<Value>().unwrap();
- assert_eq!(method, "textDocument/publishDiagnostics");
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!([])));
+ );
+ let res = client.write_request(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
+ assert_eq!(res, json!([]));
client.shutdown();
}
@@ -3400,76 +2885,56 @@ fn lsp_code_lens_test_disabled() {
fn lsp_code_lens_non_doc_nav_tree() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Date.now());\n"
+ }
+ }));
+ client.write_request(
+ "textDocument/references",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Date.now());\n"
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 3 },
+ "context": {
+ "includeDeclaration": true
+ }
+ }),
+ );
+ client.write_request(
+ "deno/virtualTextDocument",
+ json!({
+ "textDocument": {
+ "uri": "deno:/asset/lib.deno.shared_globals.d.ts"
+ }
+ }),
+ );
+ let res = client.write_request_with_res_as::<Vec<lsp::CodeLens>>(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "deno:/asset/lib.deno.shared_globals.d.ts"
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/references",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 3 },
- "context": {
- "includeDeclaration": true
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/virtualTextDocument",
- json!({
- "textDocument": {
- "uri": "deno:/asset/lib.deno.shared_globals.d.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Vec<lsp::CodeLens>>(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "deno:/asset/lib.deno.shared_globals.d.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let res = maybe_res.unwrap();
assert!(res.len() > 50);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, lsp::CodeLens>(
- "codeLens/resolve",
- json!({
- "range": {
- "start": { "line": 416, "character": 12 },
- "end": { "line": 416, "character": 19 }
- },
- "data": {
- "specifier": "asset:///lib.deno.shared_globals.d.ts",
- "source": "references"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
+ client.write_request_with_res_as::<lsp::CodeLens>(
+ "codeLens/resolve",
+ json!({
+ "range": {
+ "start": { "line": 416, "character": 12 },
+ "end": { "line": 416, "character": 19 }
+ },
+ "data": {
+ "specifier": "asset:///lib.deno.shared_globals.d.ts",
+ "source": "references"
+ }
+ }),
+ );
client.shutdown();
}
@@ -3477,8 +2942,7 @@ fn lsp_code_lens_non_doc_nav_tree() {
fn lsp_nav_tree_updates() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -3488,20 +2952,17 @@ fn lsp_nav_tree_updates() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(Some(json!([ {
+ res,
+ json!([ {
"range": {
"start": { "line": 0, "character": 10 },
"end": { "line": 0, "character": 11 }
@@ -3555,42 +3016,37 @@ fn lsp_nav_tree_updates() {
"specifier": "file:///a/file.ts",
"source": "references"
}
- }])))
+ }])
);
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 10, "character": 0 },
- "end": { "line": 13, "character": 0 }
- },
- "text": ""
- }
- ]
- }),
- )
- .unwrap();
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeLens",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 10, "character": 0 },
+ "end": { "line": 13, "character": 0 }
+ },
+ "text": ""
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ ]
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/codeLens",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"range": {
"start": { "line": 0, "character": 10 },
"end": { "line": 0, "character": 11 }
@@ -3617,7 +3073,7 @@ fn lsp_nav_tree_updates() {
"specifier": "file:///a/file.ts",
"source": "references"
}
- }]))
+ }])
);
client.shutdown();
}
@@ -3626,8 +3082,7 @@ fn lsp_nav_tree_updates() {
fn lsp_signature_help() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -3637,26 +3092,23 @@ fn lsp_signature_help() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/signatureHelp",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "character": 4, "line": 9 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "(",
- "isRetrigger": false
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/signatureHelp",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "character": 4, "line": 9 },
+ "context": {
+ "triggerKind": 2,
+ "triggerCharacter": "(",
+ "isRetrigger": false
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"signatures": [
{
"label": "add(a: number, b: number): number",
@@ -3683,43 +3135,38 @@ fn lsp_signature_help() {
],
"activeSignature": 0,
"activeParameter": 0
- }))
+ })
+ );
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 9, "character": 4 },
+ "end": { "line": 9, "character": 4 }
+ },
+ "text": "123, "
+ }
+ ]
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/signatureHelp",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "character": 8, "line": 9 }
+ }),
);
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 9, "character": 4 },
- "end": { "line": 9, "character": 4 }
- },
- "text": "123, "
- }
- ]
- }),
- )
- .unwrap();
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/signatureHelp",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "character": 8, "line": 9 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"signatures": [
{
"label": "add(a: number, b: number): number",
@@ -3746,7 +3193,7 @@ fn lsp_signature_help() {
],
"activeSignature": 0,
"activeParameter": 1
- }))
+ })
);
client.shutdown();
}
@@ -3755,8 +3202,7 @@ fn lsp_signature_help() {
fn lsp_code_actions() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -3766,9 +3212,8 @@ fn lsp_code_actions() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeAction",
+ let res = client
+ .write_request( "textDocument/codeAction",
json!({
"textDocument": {
"uri": "file:///a/file.ts"
@@ -3793,11 +3238,10 @@ fn lsp_code_actions() {
}
}),
)
- .unwrap();
- assert!(maybe_err.is_none());
+ ;
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Add async modifier to containing function",
"kind": "quickfix",
"diagnostics": [{
@@ -3850,11 +3294,10 @@ fn lsp_code_actions() {
"specifier": "file:///a/file.ts",
"fixId": "fixAwaitInSyncFunction"
}
- }]))
+ }])
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "codeAction/resolve",
+ let res = client
+ .write_request( "codeAction/resolve",
json!({
"title": "Add all missing 'async' modifiers",
"kind": "quickfix",
@@ -3875,11 +3318,10 @@ fn lsp_code_actions() {
}
}),
)
- .unwrap();
- assert!(maybe_err.is_none());
+ ;
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"title": "Add all missing 'async' modifiers",
"kind": "quickfix",
"diagnostics": [
@@ -3938,7 +3380,7 @@ fn lsp_code_actions() {
"specifier": "file:///a/file.ts",
"fixId": "fixAwaitInSyncFunction"
}
- }))
+ })
);
client.shutdown();
}
@@ -3947,8 +3389,7 @@ fn lsp_code_actions() {
fn lsp_code_actions_deno_cache() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- let mut session = TestSession::from_client(client);
- let diagnostics = session.did_open(json!({
+ let diagnostics = client.did_open(json!({
"textDocument": {
"uri": "file:///a/file.ts",
"languageId": "typescript",
@@ -3975,10 +3416,9 @@ fn lsp_code_actions_deno_cache() {
})).unwrap()
);
- let (maybe_res, maybe_err) = session
- .client
- .write_request(
- "textDocument/codeAction",
+ let res =
+ client
+ .write_request( "textDocument/codeAction",
json!({
"textDocument": {
"uri": "file:///a/file.ts"
@@ -4005,11 +3445,10 @@ fn lsp_code_actions_deno_cache() {
}
}),
)
- .unwrap();
- assert!(maybe_err.is_none());
+ ;
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Cache \"https://deno.land/x/a/mod.ts\" and its dependencies.",
"kind": "quickfix",
"diagnostics": [{
@@ -4030,17 +3469,16 @@ fn lsp_code_actions_deno_cache() {
"command": "deno.cache",
"arguments": [["https://deno.land/x/a/mod.ts"]]
}
- }]))
+ }])
);
- session.shutdown_and_exit();
+ client.shutdown();
}
#[test]
fn lsp_code_actions_deno_cache_npm() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- let mut session = TestSession::from_client(client);
- let diagnostics = session.did_open(json!({
+ let diagnostics = client.did_open(json!({
"textDocument": {
"uri": "file:///a/file.ts",
"languageId": "typescript",
@@ -4068,39 +3506,35 @@ fn lsp_code_actions_deno_cache_npm() {
.unwrap()
);
- let (maybe_res, maybe_err) = session
- .client
- .write_request(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 0, "character": 18 },
- "end": { "line": 0, "character": 29 }
- },
- "context": {
- "diagnostics": [{
- "range": {
- "start": { "line": 0, "character": 18 },
- "end": { "line": 0, "character": 29 }
- },
- "severity": 1,
- "code": "no-cache-npm",
- "source": "deno",
- "message": "Uncached or missing npm package: \"chalk\".",
- "data": { "specifier": "npm:chalk" }
- }],
- "only": ["quickfix"]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeAction",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 0, "character": 18 },
+ "end": { "line": 0, "character": 29 }
+ },
+ "context": {
+ "diagnostics": [{
+ "range": {
+ "start": { "line": 0, "character": 18 },
+ "end": { "line": 0, "character": 29 }
+ },
+ "severity": 1,
+ "code": "no-cache-npm",
+ "source": "deno",
+ "message": "Uncached or missing npm package: \"chalk\".",
+ "data": { "specifier": "npm:chalk" }
+ }],
+ "only": ["quickfix"]
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Cache \"npm:chalk\" and its dependencies.",
"kind": "quickfix",
"diagnostics": [{
@@ -4119,17 +3553,16 @@ fn lsp_code_actions_deno_cache_npm() {
"command": "deno.cache",
"arguments": [["npm:chalk"]]
}
- }]))
+ }])
);
- session.shutdown_and_exit();
+ client.shutdown();
}
#[test]
fn lsp_code_actions_imports() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- let mut session = TestSession::from_client(client);
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file00.ts",
"languageId": "typescript",
@@ -4146,7 +3579,7 @@ export class MallardDuckConfig extends DuckConfig {
"#
}
}));
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file01.ts",
"languageId": "typescript",
@@ -4162,7 +3595,7 @@ export class DuckConfig {
"#
}
}));
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file02.ts",
"languageId": "typescript",
@@ -4175,47 +3608,43 @@ export class DuckConfig {
}
}));
- let (maybe_res, maybe_err) = session
- .client
- .write_request(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file00.ts"
- },
- "range": {
- "start": { "line": 0, "character": 0 },
- "end": { "line": 6, "character": 0 }
- },
- "context": {
- "diagnostics": [{
- "range": {
- "start": { "line": 0, "character": 50 },
- "end": { "line": 0, "character": 67 }
- },
- "severity": 1,
- "code": 2304,
- "source": "deno-ts",
- "message": "Cannot find name 'DuckConfigOptions'."
- }, {
- "range": {
- "start": { "line": 4, "character": 39 },
- "end": { "line": 4, "character": 49 }
- },
- "severity": 1,
- "code": 2304,
- "source": "deno-ts",
- "message": "Cannot find name 'DuckConfig'."
- }],
- "only": ["quickfix"]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeAction",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file00.ts"
+ },
+ "range": {
+ "start": { "line": 0, "character": 0 },
+ "end": { "line": 6, "character": 0 }
+ },
+ "context": {
+ "diagnostics": [{
+ "range": {
+ "start": { "line": 0, "character": 50 },
+ "end": { "line": 0, "character": 67 }
+ },
+ "severity": 1,
+ "code": 2304,
+ "source": "deno-ts",
+ "message": "Cannot find name 'DuckConfigOptions'."
+ }, {
+ "range": {
+ "start": { "line": 4, "character": 39 },
+ "end": { "line": 4, "character": 49 }
+ },
+ "severity": 1,
+ "code": 2304,
+ "source": "deno-ts",
+ "message": "Cannot find name 'DuckConfig'."
+ }],
+ "only": ["quickfix"]
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Add import from \"./file02.ts\"",
"kind": "quickfix",
"diagnostics": [{
@@ -4288,45 +3717,41 @@ export class DuckConfig {
}]
}]
}
- }]))
+ }])
+ );
+ let res = client.write_request(
+ "codeAction/resolve",
+ json!({
+ "title": "Add all missing imports",
+ "kind": "quickfix",
+ "diagnostics": [{
+ "range": {
+ "start": { "line": 0, "character": 50 },
+ "end": { "line": 0, "character": 67 }
+ },
+ "severity": 1,
+ "code": 2304,
+ "source": "deno-ts",
+ "message": "Cannot find name 'DuckConfigOptions'."
+ }, {
+ "range": {
+ "start": { "line": 4, "character": 39 },
+ "end": { "line": 4, "character": 49 }
+ },
+ "severity": 1,
+ "code": 2304,
+ "source": "deno-ts",
+ "message": "Cannot find name 'DuckConfig'."
+ }],
+ "data": {
+ "specifier": "file:///a/file00.ts",
+ "fixId": "fixMissingImport"
+ }
+ }),
);
- let (maybe_res, maybe_err) = session
- .client
- .write_request(
- "codeAction/resolve",
- json!({
- "title": "Add all missing imports",
- "kind": "quickfix",
- "diagnostics": [{
- "range": {
- "start": { "line": 0, "character": 50 },
- "end": { "line": 0, "character": 67 }
- },
- "severity": 1,
- "code": 2304,
- "source": "deno-ts",
- "message": "Cannot find name 'DuckConfigOptions'."
- }, {
- "range": {
- "start": { "line": 4, "character": 39 },
- "end": { "line": 4, "character": 49 }
- },
- "severity": 1,
- "code": 2304,
- "source": "deno-ts",
- "message": "Cannot find name 'DuckConfig'."
- }],
- "data": {
- "specifier": "file:///a/file00.ts",
- "fixId": "fixMissingImport"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"title": "Add all missing imports",
"kind": "quickfix",
"diagnostics": [{
@@ -4367,49 +3792,43 @@ export class DuckConfig {
"specifier": "file:///a/file00.ts",
"fixId": "fixMissingImport"
}
- }))
+ })
);
- session.shutdown_and_exit();
+ client.shutdown();
}
#[test]
fn lsp_code_actions_refactor() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "var x: { a?: number; b?: string } = {};\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/codeAction",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "var x: { a?: number; b?: string } = {};\n"
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 0, "character": 0 },
+ "end": { "line": 1, "character": 0 }
+ },
+ "context": {
+ "diagnostics": [],
+ "only": ["refactor"]
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 0, "character": 0 },
- "end": { "line": 1, "character": 0 }
- },
- "context": {
- "diagnostics": [],
- "only": ["refactor"]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Extract to function in module scope",
"kind": "refactor.extract.function",
"isPreferred": false,
@@ -4528,31 +3947,28 @@ fn lsp_code_actions_refactor() {
"refactorName": "Convert import",
"actionName": "Convert named imports to namespace import"
}
- }]))
+ }])
+ );
+ let res = client.write_request(
+ "codeAction/resolve",
+ json!({
+ "title": "Extract to interface",
+ "kind": "refactor.extract.interface",
+ "isPreferred": true,
+ "data": {
+ "specifier": "file:///a/file.ts",
+ "range": {
+ "start": { "line": 0, "character": 7 },
+ "end": { "line": 0, "character": 33 }
+ },
+ "refactorName": "Extract type",
+ "actionName": "Extract to interface"
+ }
+ }),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "codeAction/resolve",
- json!({
- "title": "Extract to interface",
- "kind": "refactor.extract.interface",
- "isPreferred": true,
- "data": {
- "specifier": "file:///a/file.ts",
- "range": {
- "start": { "line": 0, "character": 7 },
- "end": { "line": 0, "character": 33 }
- },
- "refactorName": "Extract type",
- "actionName": "Extract to interface"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"title": "Extract to interface",
"kind": "refactor.extract.interface",
"edit": {
@@ -4586,7 +4002,7 @@ fn lsp_code_actions_refactor() {
"refactorName": "Extract type",
"actionName": "Extract to interface"
}
- }))
+ })
);
client.shutdown();
}
@@ -4601,8 +4017,7 @@ fn lsp_code_actions_refactor_no_disabled_support() {
code_action.disabled_support = Some(false);
});
});
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -4612,28 +4027,25 @@ fn lsp_code_actions_refactor_no_disabled_support() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 0, "character": 0 },
- "end": { "line": 14, "character": 0 }
- },
- "context": {
- "diagnostics": [],
- "only": ["refactor"]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeAction",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 0, "character": 0 },
+ "end": { "line": 14, "character": 0 }
+ },
+ "context": {
+ "diagnostics": [],
+ "only": ["refactor"]
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Extract to function in module scope",
"kind": "refactor.extract.function",
"isPreferred": false,
@@ -4659,7 +4071,7 @@ fn lsp_code_actions_refactor_no_disabled_support() {
"refactorName": "Move to a new file",
"actionName": "Move to a new file"
}
- }]))
+ }])
);
client.shutdown();
}
@@ -4671,145 +4083,118 @@ fn lsp_code_actions_deadlock() {
let large_file_text =
fs::read_to_string(testdata_path().join("lsp").join("large_file.txt"))
.unwrap();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "javascript",
- "version": 1,
- "text": large_file_text,
+ client.did_open_raw(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "javascript",
+ "version": 1,
+ "text": large_file_text,
+ }
+ }));
+ client.handle_configuration_request(json!([{ "enable": true }]));
+ client.write_request(
+ "textDocument/semanticTokens/full",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
+ client.read_diagnostics();
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 444, "character": 11 },
+ "end": { "line": 444, "character": 14 }
+ },
+ "text": "+++"
}
- }),
- )
- .unwrap();
- let (id, method, _) = client.read_request::<Value>().unwrap();
- assert_eq!(method, "workspace/configuration");
- client
- .write_response(id, json!([{ "enable": true }]))
- .unwrap();
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/semanticTokens/full",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
+ ]
+ }),
+ );
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 445, "character": 4 },
+ "end": { "line": 445, "character": 4 }
+ },
+ "text": "// "
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- read_diagnostics(&mut client);
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 444, "character": 11 },
- "end": { "line": 444, "character": 14 }
- },
- "text": "+++"
- }
- ]
- }),
- )
- .unwrap();
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 445, "character": 4 },
- "end": { "line": 445, "character": 4 }
- },
- "text": "// "
- }
- ]
- }),
- )
- .unwrap();
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 477, "character": 4 },
- "end": { "line": 477, "character": 9 }
- },
- "text": "error"
- }
- ]
- }),
- )
- .unwrap();
+ ]
+ }),
+ );
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 477, "character": 4 },
+ "end": { "line": 477, "character": 9 }
+ },
+ "text": "error"
+ }
+ ]
+ }),
+ );
// diagnostics only trigger after changes have elapsed in a separate thread,
// so we need to delay the next messages a little bit to attempt to create a
// potential for a deadlock with the codeAction
std::thread::sleep(std::time::Duration::from_millis(50));
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 609, "character": 33, }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 441, "character": 33 },
- "end": { "line": 441, "character": 42 }
- },
- "context": {
- "diagnostics": [{
- "range": {
- "start": { "line": 441, "character": 33 },
- "end": { "line": 441, "character": 42 }
- },
- "severity": 1,
- "code": 7031,
- "source": "deno-ts",
- "message": "Binding element 'debugFlag' implicitly has an 'any' type."
- }],
- "only": [ "quickfix" ]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
+ client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 609, "character": 33, }
+ }),
+ );
+ client.write_request(
+ "textDocument/codeAction",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 441, "character": 33 },
+ "end": { "line": 441, "character": 42 }
+ },
+ "context": {
+ "diagnostics": [{
+ "range": {
+ "start": { "line": 441, "character": 33 },
+ "end": { "line": 441, "character": 42 }
+ },
+ "severity": 1,
+ "code": 7031,
+ "source": "deno-ts",
+ "message": "Binding element 'debugFlag' implicitly has an 'any' type."
+ }],
+ "only": [ "quickfix" ]
+ }
+ }),
+ );
- read_diagnostics(&mut client);
+ client.read_diagnostics();
client.shutdown();
}
@@ -4818,62 +4203,46 @@ fn lsp_code_actions_deadlock() {
fn lsp_completions() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "Deno."
+ }
+ }));
+
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (0, 5),
json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "Deno."
- }
+ "triggerKind": 2,
+ "triggerCharacter": "."
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 5 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "."
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert!(list.items.len() > 90);
- } else {
- panic!("unexpected response");
- }
- let (maybe_res, maybe_err) = client
- .write_request(
- "completionItem/resolve",
- json!({
- "label": "build",
- "kind": 6,
- "sortText": "1",
- "insertTextFormat": 1,
- "data": {
- "tsc": {
- "specifier": "file:///a/file.ts",
- "position": 5,
- "name": "build",
- "useCodeSnippet": false
- }
+ assert!(!list.is_incomplete);
+ assert!(list.items.len() > 90);
+
+ let res = client.write_request(
+ "completionItem/resolve",
+ json!({
+ "label": "build",
+ "kind": 6,
+ "sortText": "1",
+ "insertTextFormat": 1,
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/file.ts",
+ "position": 5,
+ "name": "build",
+ "useCodeSnippet": false
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"label": "build",
"kind": 6,
"detail": "const Deno.build: {\n target: string;\n arch: \"x86_64\" | \"aarch64\";\n os: \"darwin\" | \"linux\" | \"windows\" | \"freebsd\" | \"netbsd\" | \"aix\" | \"solaris\" | \"illumos\";\n vendor: string;\n env?: string | undefined;\n}",
@@ -4883,7 +4252,7 @@ fn lsp_completions() {
},
"sortText": "1",
"insertTextFormat": 1
- }))
+ })
);
client.shutdown();
}
@@ -4892,40 +4261,23 @@ fn lsp_completions() {
fn lsp_completions_private_fields() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": r#"class Foo { #myProperty = "value"; constructor() { this.# } }"#
- }
- }),
- );
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 57 },
- "context": {
- "triggerKind": 1
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert_eq!(list.items.len(), 1);
- let item = &list.items[0];
- assert_eq!(item.label, "#myProperty");
- assert!(!list.is_incomplete);
- } else {
- panic!("unexpected response");
- }
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": r#"class Foo { #myProperty = "value"; constructor() { this.# } }"#
+ }
+ }));
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (0, 57),
+ json!({ "triggerKind": 1 }),
+ );
+ assert_eq!(list.items.len(), 1);
+ let item = &list.items[0];
+ assert_eq!(item.label, "#myProperty");
+ assert!(!list.is_incomplete);
client.shutdown();
}
@@ -4933,8 +4285,7 @@ fn lsp_completions_private_fields() {
fn lsp_completions_optional() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -4944,25 +4295,17 @@ fn lsp_completions_optional() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 8, "character": 4 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "."
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.get_completion(
+ "file:///a/file.ts",
+ (8, 4),
+ json!({
+ "triggerKind": 2,
+ "triggerCharacter": "."
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ json!(res),
+ json!({
"isIncomplete": false,
"items": [
{
@@ -4982,32 +4325,29 @@ fn lsp_completions_optional() {
}
}
]
- }))
+ })
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "completionItem/resolve",
- json!({
- "label": "b?",
- "kind": 5,
- "sortText": "1",
- "filterText": "b",
- "insertText": "b",
- "data": {
- "tsc": {
- "specifier": "file:///a/file.ts",
- "position": 79,
- "name": "b",
- "useCodeSnippet": false
- }
+ let res = client.write_request(
+ "completionItem/resolve",
+ json!({
+ "label": "b?",
+ "kind": 5,
+ "sortText": "1",
+ "filterText": "b",
+ "insertText": "b",
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/file.ts",
+ "position": 79,
+ "name": "b",
+ "useCodeSnippet": false
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"label": "b?",
"kind": 5,
"detail": "(property) A.b?: string | undefined",
@@ -5018,7 +4358,7 @@ fn lsp_completions_optional() {
"sortText": "1",
"filterText": "b",
"insertText": "b"
- }))
+ })
);
client.shutdown();
}
@@ -5027,85 +4367,63 @@ fn lsp_completions_optional() {
fn lsp_completions_auto_import() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/b.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "export const foo = \"foo\";\n",
- }
- }),
- );
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/b.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "export const foo = \"foo\";\n",
+ }
+ }));
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "export {};\n\n",
+ }
+ }));
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (2, 0),
+ json!({ "triggerKind": 1 }),
+ );
+ assert!(!list.is_incomplete);
+ if !list.items.iter().any(|item| item.label == "foo") {
+ panic!("completions items missing 'foo' symbol");
+ }
+
+ let res = client.write_request(
+ "completionItem/resolve",
json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "export {};\n\n",
+ "label": "foo",
+ "kind": 6,
+ "sortText": "οΏΏ16",
+ "commitCharacters": [
+ ".",
+ ",",
+ ";",
+ "("
+ ],
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/file.ts",
+ "position": 12,
+ "name": "foo",
+ "source": "./b",
+ "data": {
+ "exportName": "foo",
+ "moduleSpecifier": "./b",
+ "fileName": "file:///a/b.ts"
+ },
+ "useCodeSnippet": false
+ }
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 2, "character": 0, },
- "context": {
- "triggerKind": 1,
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- if !list.items.iter().any(|item| item.label == "foo") {
- panic!("completions items missing 'foo' symbol");
- }
- } else {
- panic!("unexpected completion response");
- }
- let (maybe_res, maybe_err) = client
- .write_request(
- "completionItem/resolve",
- json!({
- "label": "foo",
- "kind": 6,
- "sortText": "οΏΏ16",
- "commitCharacters": [
- ".",
- ",",
- ";",
- "("
- ],
- "data": {
- "tsc": {
- "specifier": "file:///a/file.ts",
- "position": 12,
- "name": "foo",
- "source": "./b",
- "data": {
- "exportName": "foo",
- "moduleSpecifier": "./b",
- "fileName": "file:///a/b.ts"
- },
- "useCodeSnippet": false
- }
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"label": "foo",
"kind": 6,
"detail": "const foo: \"foo\"",
@@ -5123,7 +4441,7 @@ fn lsp_completions_auto_import() {
"newText": "import { foo } from \"./b.ts\";\n\n"
}
]
- }))
+ })
);
}
@@ -5131,8 +4449,7 @@ fn lsp_completions_auto_import() {
fn lsp_completions_snippet() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/a.tsx",
@@ -5142,87 +4459,71 @@ fn lsp_completions_snippet() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/a.tsx"
- },
- "position": { "line": 5, "character": 13, },
- "context": {
- "triggerKind": 1,
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert_eq!(
- json!(list),
- json!({
- "isIncomplete": false,
- "items": [
- {
- "label": "type",
- "kind": 5,
- "sortText": "11",
- "filterText": "type=\"$1\"",
- "insertText": "type=\"$1\"",
- "insertTextFormat": 2,
- "commitCharacters": [
- ".",
- ",",
- ";",
- "("
- ],
- "data": {
- "tsc": {
- "specifier": "file:///a/a.tsx",
- "position": 87,
- "name": "type",
- "useCodeSnippet": false
- }
+ let list = client.get_completion_list(
+ "file:///a/a.tsx",
+ (5, 13),
+ json!({ "triggerKind": 1 }),
+ );
+ assert!(!list.is_incomplete);
+ assert_eq!(
+ json!(list),
+ json!({
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "type",
+ "kind": 5,
+ "sortText": "11",
+ "filterText": "type=\"$1\"",
+ "insertText": "type=\"$1\"",
+ "insertTextFormat": 2,
+ "commitCharacters": [
+ ".",
+ ",",
+ ";",
+ "("
+ ],
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/a.tsx",
+ "position": 87,
+ "name": "type",
+ "useCodeSnippet": false
}
}
- ]
- })
- );
- } else {
- panic!("unexpected completion response");
- }
- let (maybe_res, maybe_err) = client
- .write_request(
- "completionItem/resolve",
- json!({
- "label": "type",
- "kind": 5,
- "sortText": "11",
- "filterText": "type=\"$1\"",
- "insertText": "type=\"$1\"",
- "insertTextFormat": 2,
- "commitCharacters": [
- ".",
- ",",
- ";",
- "("
- ],
- "data": {
- "tsc": {
- "specifier": "file:///a/a.tsx",
- "position": 87,
- "name": "type",
- "useCodeSnippet": false
- }
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ ]
+ })
+ );
+
+ let res = client.write_request(
+ "completionItem/resolve",
+ json!({
+ "label": "type",
+ "kind": 5,
+ "sortText": "11",
+ "filterText": "type=\"$1\"",
+ "insertText": "type=\"$1\"",
+ "insertTextFormat": 2,
+ "commitCharacters": [
+ ".",
+ ",",
+ ";",
+ "("
+ ],
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/a.tsx",
+ "position": 87,
+ "name": "type",
+ "useCodeSnippet": false
+ }
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"label": "type",
"kind": 5,
"detail": "(property) type: string",
@@ -5234,7 +4535,7 @@ fn lsp_completions_snippet() {
"filterText": "type=\"$1\"",
"insertText": "type=\"$1\"",
"insertTextFormat": 2
- }))
+ })
);
}
@@ -5247,8 +4548,7 @@ fn lsp_completions_no_snippet() {
doc.completion = None;
});
});
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/a.tsx",
@@ -5258,53 +4558,39 @@ fn lsp_completions_no_snippet() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/a.tsx"
- },
- "position": { "line": 5, "character": 13, },
- "context": {
- "triggerKind": 1,
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert_eq!(
- json!(list),
- json!({
- "isIncomplete": false,
- "items": [
- {
- "label": "type",
- "kind": 5,
- "sortText": "11",
- "commitCharacters": [
- ".",
- ",",
- ";",
- "("
- ],
- "data": {
- "tsc": {
- "specifier": "file:///a/a.tsx",
- "position": 87,
- "name": "type",
- "useCodeSnippet": false
- }
+ let list = client.get_completion_list(
+ "file:///a/a.tsx",
+ (5, 13),
+ json!({ "triggerKind": 1 }),
+ );
+ assert!(!list.is_incomplete);
+ assert_eq!(
+ json!(list),
+ json!({
+ "isIncomplete": false,
+ "items": [
+ {
+ "label": "type",
+ "kind": 5,
+ "sortText": "11",
+ "commitCharacters": [
+ ".",
+ ",",
+ ";",
+ "("
+ ],
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/a.tsx",
+ "position": 87,
+ "name": "type",
+ "useCodeSnippet": false
}
}
- ]
- })
- );
- } else {
- panic!("unexpected completion response");
- }
+ }
+ ]
+ })
+ );
}
#[test]
@@ -5312,8 +4598,7 @@ fn lsp_completions_npm() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -5323,96 +4608,76 @@ fn lsp_completions_npm() {
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [
- {
- "uri": "npm:@denotest/cjs-default-export",
- }, {
- "uri": "npm:chalk",
- }
- ]
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [
+ {
+ "uri": "npm:@denotest/cjs-default-export",
+ }, {
+ "uri": "npm:chalk",
+ }
+ ]
+ }),
+ );
// check importing a cjs default import
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 2, "character": 0 },
- "end": { "line": 2, "character": 0 }
- },
- "text": "cjsDefault."
- }
- ]
- }),
- )
- .unwrap();
- read_diagnostics(&mut client);
-
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 2, "character": 11 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "."
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 2, "character": 0 },
+ "end": { "line": 2, "character": 0 }
+ },
+ "text": "cjsDefault."
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert_eq!(list.items.len(), 3);
- assert!(list.items.iter().any(|i| i.label == "default"));
- assert!(list.items.iter().any(|i| i.label == "MyClass"));
- } else {
- panic!("unexpected response");
- }
- let (maybe_res, maybe_err) = client
- .write_request(
- "completionItem/resolve",
- json!({
- "label": "MyClass",
- "kind": 6,
- "sortText": "1",
- "insertTextFormat": 1,
- "data": {
- "tsc": {
- "specifier": "file:///a/file.ts",
- "position": 69,
- "name": "MyClass",
- "useCodeSnippet": false
- }
+ ]
+ }),
+ );
+ client.read_diagnostics();
+
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (2, 11),
+ json!({
+ "triggerKind": 2,
+ "triggerCharacter": "."
+ }),
+ );
+ assert!(!list.is_incomplete);
+ assert_eq!(list.items.len(), 3);
+ assert!(list.items.iter().any(|i| i.label == "default"));
+ assert!(list.items.iter().any(|i| i.label == "MyClass"));
+
+ let res = client.write_request(
+ "completionItem/resolve",
+ json!({
+ "label": "MyClass",
+ "kind": 6,
+ "sortText": "1",
+ "insertTextFormat": 1,
+ "data": {
+ "tsc": {
+ "specifier": "file:///a/file.ts",
+ "position": 69,
+ "name": "MyClass",
+ "useCodeSnippet": false
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"label": "MyClass",
"kind": 6,
"sortText": "1",
@@ -5425,55 +4690,41 @@ fn lsp_completions_npm() {
"useCodeSnippet": false
}
}
- }))
+ })
);
// now check chalk, which is esm
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 3
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 2, "character": 0 },
- "end": { "line": 2, "character": 11 }
- },
- "text": "chalk."
- }
- ]
- }),
- )
- .unwrap();
- read_diagnostics(&mut client);
-
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 2, "character": 6 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "."
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 3
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 2, "character": 0 },
+ "end": { "line": 2, "character": 11 }
+ },
+ "text": "chalk."
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert!(list.items.iter().any(|i| i.label == "green"));
- assert!(list.items.iter().any(|i| i.label == "red"));
- } else {
- panic!("unexpected response");
- }
+ ]
+ }),
+ );
+ client.read_diagnostics();
+
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (2, 6),
+ json!({
+ "triggerKind": 2,
+ "triggerCharacter": "."
+ }),
+ );
+ assert!(!list.is_incomplete);
+ assert!(list.items.iter().any(|i| i.label == "green"));
+ assert!(list.items.iter().any(|i| i.label == "red"));
client.shutdown();
}
@@ -5514,64 +4765,47 @@ fn lsp_npm_specifier_unopened_file() {
let main_url =
ModuleSpecifier::from_file_path(client.deno_dir().path().join("main.ts"))
.unwrap();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": main_url,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import { chalk } from './other.ts';\n\n",
+ }
+ }));
+
+ client.write_notification(
+ "textDocument/didChange",
json!({
"textDocument": {
"uri": main_url,
- "languageId": "typescript",
- "version": 1,
- "text": "import { chalk } from './other.ts';\n\n",
- }
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 2, "character": 0 },
+ "end": { "line": 2, "character": 0 }
+ },
+ "text": "chalk."
+ }
+ ]
}),
);
-
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": main_url,
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 2, "character": 0 },
- "end": { "line": 2, "character": 0 }
- },
- "text": "chalk."
- }
- ]
- }),
- )
- .unwrap();
- read_diagnostics(&mut client);
+ client.read_diagnostics();
// now ensure completions work
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": main_url
- },
- "position": { "line": 2, "character": 6 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "."
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert_eq!(list.items.len(), 63);
- assert!(list.items.iter().any(|i| i.label == "ansi256"));
- } else {
- panic!("unexpected response");
- }
+ let list = client.get_completion_list(
+ main_url,
+ (2, 6),
+ json!({
+ "triggerKind": 2,
+ "triggerCharacter": "."
+ }),
+ );
+ assert!(!list.is_incomplete);
+ assert_eq!(list.items.len(), 63);
+ assert!(list.items.iter().any(|i| i.label == "ansi256"));
}
#[test]
@@ -5579,17 +4813,14 @@ fn lsp_completions_node_specifier() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- let diagnostics = CollectedDiagnostics(did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import fs from 'node:non-existent';\n\n",
- }
- }),
- ));
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import fs from 'node:non-existent';\n\n",
+ }
+ }));
let non_existent_diagnostics = diagnostics
.with_file_and_source("file:///a/file.ts", "deno")
@@ -5616,27 +4847,25 @@ fn lsp_completions_node_specifier() {
);
// update to have fs import
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 0, "character": 16 },
- "end": { "line": 0, "character": 33 },
- },
- "text": "fs"
- }
- ]
- }),
- )
- .unwrap();
- let diagnostics = read_diagnostics(&mut client);
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 0, "character": 16 },
+ "end": { "line": 0, "character": 33 },
+ },
+ "text": "fs"
+ }
+ ]
+ }),
+ );
+ let diagnostics = client.read_diagnostics();
let diagnostics = diagnostics
.with_file_and_source("file:///a/file.ts", "deno")
.diagnostics
@@ -5650,28 +4879,25 @@ fn lsp_completions_node_specifier() {
.collect::<Vec<_>>();
// get the quick fixes
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 0, "character": 16 },
- "end": { "line": 0, "character": 18 },
- },
- "context": {
- "diagnostics": json!(diagnostics),
- "only": ["quickfix"]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ let res = client.write_request(
+ "textDocument/codeAction",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 0, "character": 16 },
+ "end": { "line": 0, "character": 18 },
+ },
+ "context": {
+ "diagnostics": json!(diagnostics),
+ "only": ["quickfix"]
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Update specifier to node:fs",
"kind": "quickfix",
"diagnostics": [
@@ -5702,32 +4928,30 @@ fn lsp_completions_node_specifier() {
]
}
}
- }]))
+ }])
);
// update to have node:fs import
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 3,
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 0, "character": 15 },
- "end": { "line": 0, "character": 19 },
- },
- "text": "\"node:fs\"",
- }
- ]
- }),
- )
- .unwrap();
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 3,
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 0, "character": 15 },
+ "end": { "line": 0, "character": 19 },
+ },
+ "text": "\"node:fs\"",
+ }
+ ]
+ }),
+ );
- let diagnostics = read_diagnostics(&mut client);
+ let diagnostics = client.read_diagnostics();
let cache_diagnostics = diagnostics
.with_file_and_source("file:///a/file.ts", "deno")
.diagnostics
@@ -5756,69 +4980,51 @@ fn lsp_completions_node_specifier() {
])
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [
- {
- "uri": "npm:@types/node",
- }
- ]
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
-
- client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 4
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 2, "character": 0 },
- "end": { "line": 2, "character": 0 }
- },
- "text": "fs."
- }
- ]
- }),
- )
- .unwrap();
- read_diagnostics(&mut client);
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [
+ {
+ "uri": "npm:@types/node",
+ }
+ ]
+ }),
+ );
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 2, "character": 3 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "."
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "version": 4
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 2, "character": 0 },
+ "end": { "line": 2, "character": 0 }
+ },
+ "text": "fs."
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert!(list.items.iter().any(|i| i.label == "writeFile"));
- assert!(list.items.iter().any(|i| i.label == "writeFileSync"));
- } else {
- panic!("unexpected response");
- }
+ ]
+ }),
+ );
+ client.read_diagnostics();
+
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (2, 3),
+ json!({
+ "triggerKind": 2,
+ "triggerCharacter": "."
+ }),
+ );
+ assert!(!list.is_incomplete);
+ assert!(list.items.iter().any(|i| i.label == "writeFile"));
+ assert!(list.items.iter().any(|i| i.label == "writeFileSync"));
client.shutdown();
}
@@ -5830,62 +5036,45 @@ fn lsp_completions_registry() {
client.initialize(|builder| {
builder.add_test_server_suggestions();
});
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import * as a from \"http://localhost:4545/x/a@\""
+ }
+ }));
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (0, 46),
json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import * as a from \"http://localhost:4545/x/a@\""
- }
+ "triggerKind": 2,
+ "triggerCharacter": "@"
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
+ assert!(!list.is_incomplete);
+ assert_eq!(list.items.len(), 3);
+
+ let res = client.write_request(
+ "completionItem/resolve",
+ json!({
+ "label": "v2.0.0",
+ "kind": 19,
+ "detail": "(version)",
+ "sortText": "0000000003",
+ "filterText": "http://localhost:4545/x/a@v2.0.0",
+ "textEdit": {
+ "range": {
+ "start": { "line": 0, "character": 20 },
+ "end": { "line": 0, "character": 46 }
},
- "position": { "line": 0, "character": 46 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "@"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert_eq!(list.items.len(), 3);
- } else {
- panic!("unexpected response");
- }
- let (maybe_res, maybe_err) = client
- .write_request(
- "completionItem/resolve",
- json!({
- "label": "v2.0.0",
- "kind": 19,
- "detail": "(version)",
- "sortText": "0000000003",
- "filterText": "http://localhost:4545/x/a@v2.0.0",
- "textEdit": {
- "range": {
- "start": { "line": 0, "character": 20 },
- "end": { "line": 0, "character": 46 }
- },
- "newText": "http://localhost:4545/x/a@v2.0.0"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ "newText": "http://localhost:4545/x/a@v2.0.0"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"label": "v2.0.0",
"kind": 19,
"detail": "(version)",
@@ -5898,7 +5087,7 @@ fn lsp_completions_registry() {
},
"newText": "http://localhost:4545/x/a@v2.0.0"
}
- }))
+ })
);
client.shutdown();
}
@@ -5910,36 +5099,25 @@ fn lsp_completions_registry_empty() {
client.initialize(|builder| {
builder.add_test_server_suggestions();
});
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import * as a from \"\""
+ }
+ }));
+ let res = client.get_completion(
+ "file:///a/file.ts",
+ (0, 20),
json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import * as a from \"\""
- }
+ "triggerKind": 2,
+ "triggerCharacter": "\""
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 20 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "\""
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ json!(res),
+ json!({
"isIncomplete": false,
"items": [{
"label": ".",
@@ -5969,7 +5147,7 @@ fn lsp_completions_registry_empty() {
},
"commitCharacters": ["\"", "'", "/"]
}]
- }))
+ })
);
client.shutdown();
}
@@ -5979,38 +5157,26 @@ fn lsp_auto_discover_registry() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import * as a from \"http://localhost:4545/x/a@\""
+ }
+ }));
+ client.get_completion(
+ "file:///a/file.ts",
+ (0, 46),
json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import * as a from \"http://localhost:4545/x/a@\""
- }
+ "triggerKind": 2,
+ "triggerCharacter": "@"
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 46 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "@"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (method, maybe_res) = client.read_notification().unwrap();
+ let (method, res) = client.read_notification();
assert_eq!(method, "deno/registryState");
assert_eq!(
- maybe_res,
+ res,
Some(json!({
"origin": "http://localhost:4545",
"suggestions": true,
@@ -6028,8 +5194,7 @@ fn lsp_cache_location() {
builder.set_cache(".cache").add_test_server_suggestions();
});
- let mut session = TestSession::from_client(client);
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file_01.ts",
"languageId": "typescript",
@@ -6038,7 +5203,7 @@ fn lsp_cache_location() {
}
}));
let diagnostics =
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file.ts",
"languageId": "typescript",
@@ -6047,36 +5212,27 @@ fn lsp_cache_location() {
}
}));
assert_eq!(diagnostics.viewed().len(), 7);
- let (maybe_res, maybe_err) = session
- .client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [],
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = session
- .client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 0, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [],
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 0, "character": 28 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: http&#8203;://127.0.0.1:4545/xTypeScriptTypes.js\n\n**Types**: http&#8203;://127.0.0.1:4545/xTypeScriptTypes.d.ts\n"
@@ -6085,24 +5241,20 @@ fn lsp_cache_location() {
"start": { "line": 0, "character": 19 },
"end": { "line": 0, "character": 62 }
}
- }))
+ })
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 7, "character": 28 }
+ }),
);
- let (maybe_res, maybe_err) = session
- .client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 7, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: http&#8203;://localhost:4545/x/a/mod.ts\n\n\n---\n\n**a**\n\nmod.ts"
@@ -6111,12 +5263,12 @@ fn lsp_cache_location() {
"start": { "line": 7, "character": 19 },
"end": { "line": 7, "character": 53 }
}
- }))
+ })
);
let cache_path = temp_dir.path().join(".cache");
assert!(cache_path.is_dir());
assert!(cache_path.join("gen").is_dir());
- session.shutdown_and_exit();
+ client.shutdown();
}
/// Sets the TLS root certificate on startup, which allows the LSP to connect to
@@ -6135,9 +5287,7 @@ fn lsp_tls_cert() {
.set_tls_certificate("");
});
- let mut session = TestSession::from_client(client);
-
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file_01.ts",
"languageId": "typescript",
@@ -6145,7 +5295,7 @@ fn lsp_tls_cert() {
"text": "export const a = \"a\";\n",
}
}));
- let diagnostics = session.did_open(json!({
+ let diagnostics = client.did_open(json!({
"textDocument": {
"uri": "file:///a/file.ts",
"languageId": "typescript",
@@ -6155,36 +5305,27 @@ fn lsp_tls_cert() {
}));
let diagnostics = diagnostics.viewed();
assert_eq!(diagnostics.len(), 7);
- let (maybe_res, maybe_err) = session
- .client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [],
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = session
- .client
- .write_request(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 0, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [],
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 0, "character": 28 }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: https&#8203;://localhost:5545/xTypeScriptTypes.js\n"
@@ -6193,24 +5334,20 @@ fn lsp_tls_cert() {
"start": { "line": 0, "character": 19 },
"end": { "line": 0, "character": 63 }
}
- }))
+ })
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ },
+ "position": { "line": 7, "character": 28 }
+ }),
);
- let (maybe_res, maybe_err) = session
- .client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- },
- "position": { "line": 7, "character": 28 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: http&#8203;://localhost:4545/x/a/mod.ts\n\n\n---\n\n**a**\n\nmod.ts"
@@ -6219,9 +5356,9 @@ fn lsp_tls_cert() {
"start": { "line": 7, "character": 19 },
"end": { "line": 7, "character": 53 }
}
- }))
+ })
);
- session.shutdown_and_exit();
+ client.shutdown();
}
#[test]
@@ -6229,8 +5366,7 @@ fn lsp_diagnostics_warn_redirect() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -6240,24 +5376,20 @@ fn lsp_diagnostics_warn_redirect() {
},
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [
- {
- "uri": "http://127.0.0.1:4545/x_deno_warning.js",
- }
- ],
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let diagnostics = read_diagnostics(&mut client);
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [
+ {
+ "uri": "http://127.0.0.1:4545/x_deno_warning.js",
+ }
+ ],
+ }),
+ );
+ let diagnostics = client.read_diagnostics();
assert_eq!(
diagnostics.with_source("deno"),
lsp::PublishDiagnosticsParams {
@@ -6310,8 +5442,7 @@ fn lsp_redirect_quick_fix() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -6321,48 +5452,39 @@ fn lsp_redirect_quick_fix() {
},
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.ts",
- },
- "uris": [
- {
- "uri": "http://127.0.0.1:4545/x_deno_warning.js",
- }
- ],
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let diagnostics = read_diagnostics(&mut client)
- .with_source("deno")
- .diagnostics;
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeAction",
- json!(json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 0, "character": 19 },
- "end": { "line": 0, "character": 60 }
- },
- "context": {
- "diagnostics": diagnostics,
- "only": ["quickfix"]
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.ts",
+ },
+ "uris": [
+ {
+ "uri": "http://127.0.0.1:4545/x_deno_warning.js",
}
- })),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ ],
+ }),
+ );
+ let diagnostics = client.read_diagnostics().with_source("deno").diagnostics;
+ let res = client.write_request(
+ "textDocument/codeAction",
+ json!(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 0, "character": 19 },
+ "end": { "line": 0, "character": 60 }
+ },
+ "context": {
+ "diagnostics": diagnostics,
+ "only": ["quickfix"]
+ }
+ })),
+ );
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Update specifier to its redirected specifier.",
"kind": "quickfix",
"diagnostics": [
@@ -6394,7 +5516,7 @@ fn lsp_redirect_quick_fix() {
]
}
}
- }]))
+ }])
);
client.shutdown();
}
@@ -6403,19 +5525,16 @@ fn lsp_redirect_quick_fix() {
fn lsp_diagnostics_deprecated() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- let diagnostics = did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "/** @deprecated */\nexport const a = \"a\";\n\na;\n",
- },
- }),
- );
+ let diagnostics = client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "/** @deprecated */\nexport const a = \"a\";\n\na;\n",
+ },
+ }));
assert_eq!(
- json!(diagnostics),
+ json!(diagnostics.0),
json!([
{
"uri": "file:///a/file.ts",
@@ -6452,10 +5571,8 @@ fn lsp_diagnostics_deprecated() {
fn lsp_diagnostics_deno_types() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
+ let diagnostics = client
+ .did_open(json!({
"textDocument": {
"uri": "file:///a/file.ts",
"languageId": "typescript",
@@ -6463,26 +5580,16 @@ fn lsp_diagnostics_deno_types() {
"text": "/// <reference types=\"https://example.com/a/b.d.ts\" />\n/// <reference path=\"https://example.com/a/c.ts\"\n\n// @deno-types=https://example.com/a/d.d.ts\nimport * as d from \"https://example.com/a/d.js\";\n\n// @deno-types=\"https://example.com/a/e.d.ts\"\nimport * as e from \"https://example.com/a/e.js\";\n\nconsole.log(d, e);\n"
}
}),
- )
- .unwrap();
- let (id, method, _) = client.read_request::<Value>().unwrap();
- assert_eq!(method, "workspace/configuration");
- client
- .write_response(id, json!([{ "enable": true }]))
- .unwrap();
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/documentSymbol",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- }
- }),
- )
- .unwrap();
- assert!(maybe_res.is_some());
- assert!(maybe_err.is_none());
- let diagnostics = read_diagnostics(&mut client);
+ );
+
+ client.write_request(
+ "textDocument/documentSymbol",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ }
+ }),
+ );
assert_eq!(diagnostics.viewed().len(), 5);
client.shutdown();
}
@@ -6491,8 +5598,7 @@ fn lsp_diagnostics_deno_types() {
fn lsp_diagnostics_refresh_dependents() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- let mut session = TestSession::from_client(client);
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file_00.ts",
"languageId": "typescript",
@@ -6500,7 +5606,7 @@ fn lsp_diagnostics_refresh_dependents() {
"text": "export const a = \"a\";\n",
},
}));
- session.did_open(json!({
+ client.did_open(json!({
"textDocument": {
"uri": "file:///a/file_01.ts",
"languageId": "typescript",
@@ -6508,7 +5614,7 @@ fn lsp_diagnostics_refresh_dependents() {
"text": "export * from \"./file_00.ts\";\n",
},
}));
- let diagnostics = session.did_open(json!({
+ let diagnostics = client.did_open(json!({
"textDocument": {
"uri": "file:///a/file_02.ts",
"languageId": "typescript",
@@ -6537,32 +5643,29 @@ fn lsp_diagnostics_refresh_dependents() {
);
// fix the code causing the diagnostic
- session
- .client
- .write_notification(
- "textDocument/didChange",
- json!({
- "textDocument": {
- "uri": "file:///a/file_00.ts",
- "version": 2
- },
- "contentChanges": [
- {
- "range": {
- "start": { "line": 1, "character": 0 },
- "end": { "line": 1, "character": 0 }
- },
- "text": "export const b = \"b\";\n"
- }
- ]
- }),
- )
- .unwrap();
- let diagnostics = session.read_diagnostics();
+ client.write_notification(
+ "textDocument/didChange",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file_00.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": { "line": 1, "character": 0 },
+ "end": { "line": 1, "character": 0 }
+ },
+ "text": "export const b = \"b\";\n"
+ }
+ ]
+ }),
+ );
+ let diagnostics = client.read_diagnostics();
assert_eq!(diagnostics.viewed().len(), 0); // no diagnostics now
- session.shutdown_and_exit();
- assert_eq!(session.client.queue_len(), 0);
+ client.shutdown();
+ assert_eq!(client.queue_len(), 0);
}
#[derive(Deserialize)]
@@ -6583,39 +5686,28 @@ struct PerformanceAverages {
fn lsp_performance() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console.log(Deno.args);\n"
+ }
+ }));
+ client.write_request(
+ "textDocument/hover",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console.log(Deno.args);\n"
- }
+ "uri": "file:///a/file.ts"
+ },
+ "position": { "line": 0, "character": 19 }
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 19 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, PerformanceAverages>("deno/performance", json!(null))
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(res) = maybe_res {
- assert_eq!(res.averages.len(), 13);
- } else {
- panic!("unexpected result");
- }
+ let res = client.write_request_with_res_as::<PerformanceAverages>(
+ "deno/performance",
+ json!(null),
+ );
+ assert_eq!(res.averages.len(), 13);
client.shutdown();
}
@@ -6623,33 +5715,27 @@ fn lsp_performance() {
fn lsp_format_no_changes() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console;\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/formatting",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console;\n"
+ "uri": "file:///a/file.ts"
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ assert_eq!(res, json!(null));
client.assert_no_notification("window/showMessage");
client.shutdown();
}
@@ -6658,33 +5744,27 @@ fn lsp_format_no_changes() {
fn lsp_format_error() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "console test test\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/formatting",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "console test test\n"
+ "uri": "file:///a/file.ts"
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ assert_eq!(res, json!(null));
client.shutdown();
}
@@ -6692,35 +5772,29 @@ fn lsp_format_error() {
fn lsp_format_mbc() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "const bar = 'πŸ‘πŸ‡ΊπŸ‡ΈπŸ˜ƒ'\nconsole.log('hello deno')\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/formatting",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "const bar = 'πŸ‘πŸ‡ΊπŸ‡ΈπŸ˜ƒ'\nconsole.log('hello deno')\n"
+ "uri": "file:///a/file.ts"
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"range": {
"start": { "line": 0, "character": 12 },
"end": { "line": 0, "character": 13 }
@@ -6744,7 +5818,7 @@ fn lsp_format_mbc() {
"end": { "line": 1, "character": 25 }
},
"newText": "\");"
- }]))
+ }])
);
client.shutdown();
}
@@ -6778,33 +5852,27 @@ fn lsp_format_exclude_with_config() {
});
let file_uri = temp_dir.uri().join("ignored.ts").unwrap();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": file_uri,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "function myFunc(){}"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/formatting",
json!({
"textDocument": {
- "uri": file_uri,
- "languageId": "typescript",
- "version": 1,
- "text": "function myFunc(){}"
+ "uri": file_uri
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": file_uri
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ assert_eq!(res, json!(null));
client.shutdown();
}
@@ -6837,33 +5905,27 @@ fn lsp_format_exclude_default_config() {
});
let file_uri = temp_dir.uri().join("ignored.ts").unwrap();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": file_uri,
+ "languageId": "typescript",
+ "version": 1,
+ "text": "function myFunc(){}"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/formatting",
json!({
"textDocument": {
- "uri": file_uri,
- "languageId": "typescript",
- "version": 1,
- "text": "function myFunc(){}"
+ "uri": file_uri
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": file_uri
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ assert_eq!(res, json!(null));
client.shutdown();
}
@@ -6871,41 +5933,33 @@ fn lsp_format_exclude_default_config() {
fn lsp_format_json() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
+ client.did_open(json!({
+ "textDocument": {
+ // Also test out using a non-json file extension here.
+ // What should matter is the language identifier.
+ "uri": "file:///a/file.lock",
+ "languageId": "json",
+ "version": 1,
+ "text": "{\"key\":\"value\"}"
+ }
+ }));
+
+ let res = client.write_request(
+ "textDocument/formatting",
+ json!({
"textDocument": {
- // Also test out using a non-json file extension here.
- // What should matter is the language identifier.
- "uri": "file:///a/file.lock",
- "languageId": "json",
- "version": 1,
- "text": "{\"key\":\"value\"}"
+ "uri": "file:///a/file.lock"
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
}
- }),
- )
- .unwrap();
-
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": "file:///a/file.lock"
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
+ }),
+ );
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([
+ res,
+ json!([
{
"range": {
"start": { "line": 0, "character": 1 },
@@ -6925,7 +5979,7 @@ fn lsp_format_json() {
},
"newText": " }\n"
}
- ]))
+ ])
);
client.shutdown();
}
@@ -6934,46 +5988,35 @@ fn lsp_format_json() {
fn lsp_json_no_diagnostics() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": "file:///a/file.json",
- "languageId": "json",
- "version": 1,
- "text": "{\"key\":\"value\"}"
- }
- }),
- )
- .unwrap();
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.json",
+ "languageId": "json",
+ "version": 1,
+ "text": "{\"key\":\"value\"}"
+ }
+ }));
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/semanticTokens/full",
- json!({
- "textDocument": {
- "uri": "file:///a/file.json"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ let res = client.write_request(
+ "textDocument/semanticTokens/full",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.json"
+ }
+ }),
+ );
+ assert_eq!(res, json!(null));
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.json"
- },
- "position": { "line": 0, "character": 3 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.json"
+ },
+ "position": { "line": 0, "character": 3 }
+ }),
+ );
+ assert_eq!(res, json!(null));
client.shutdown();
}
@@ -6982,39 +6025,31 @@ fn lsp_json_no_diagnostics() {
fn lsp_format_markdown() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": "file:///a/file.md",
- "languageId": "markdown",
- "version": 1,
- "text": "# Hello World"
- }
- }),
- )
- .unwrap();
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.md",
+ "languageId": "markdown",
+ "version": 1,
+ "text": "# Hello World"
+ }
+ }));
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": "file:///a/file.md"
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
+ let res = client.write_request(
+ "textDocument/formatting",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.md"
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
+ }
+ }),
+ );
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([
+ res,
+ json!([
{
"range": {
"start": { "line": 0, "character": 1 },
@@ -7028,7 +6063,7 @@ fn lsp_format_markdown() {
},
"newText": "\n"
}
- ]))
+ ])
);
client.shutdown();
}
@@ -7059,8 +6094,7 @@ fn lsp_format_with_config() {
});
client
- .write_notification(
- "textDocument/didOpen",
+ .did_open(
json!({
"textDocument": {
"uri": "file:///a/file.ts",
@@ -7069,29 +6103,25 @@ fn lsp_format_with_config() {
"text": "export async function someVeryLongFunctionName() {\nconst response = fetch(\"http://localhost:4545/some/non/existent/path.json\");\nconsole.log(response.text());\nconsole.log(\"finished!\")\n}"
}
}),
- )
- .unwrap();
+ );
// The options below should be ignored in favor of configuration from config file.
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/formatting",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "options": {
- "tabSize": 2,
- "insertSpaces": true
- }
- }),
- )
- .unwrap();
+ let res = client.write_request(
+ "textDocument/formatting",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "options": {
+ "tabSize": 2,
+ "insertSpaces": true
+ }
+ }),
+ );
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"range": {
"start": { "line": 1, "character": 0 },
"end": { "line": 1, "character": 0 }
@@ -7140,7 +6170,7 @@ fn lsp_format_with_config() {
},
"newText": "\n"
}]
- ))
+ )
);
client.shutdown();
}
@@ -7149,46 +6179,35 @@ fn lsp_format_with_config() {
fn lsp_markdown_no_diagnostics() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": "file:///a/file.md",
- "languageId": "markdown",
- "version": 1,
- "text": "# Hello World"
- }
- }),
- )
- .unwrap();
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.md",
+ "languageId": "markdown",
+ "version": 1,
+ "text": "# Hello World"
+ }
+ }));
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/semanticTokens/full",
- json!({
- "textDocument": {
- "uri": "file:///a/file.md"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ let res = client.write_request(
+ "textDocument/semanticTokens/full",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.md"
+ }
+ }),
+ );
+ assert_eq!(res, json!(null));
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.md"
- },
- "position": { "line": 0, "character": 3 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert_eq!(maybe_res, Some(json!(null)));
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.md"
+ },
+ "position": { "line": 0, "character": 3 }
+ }),
+ );
+ assert_eq!(res, json!(null));
client.shutdown();
}
@@ -7198,98 +6217,77 @@ fn lsp_configuration_did_change() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "import * as a from \"http://localhost:4545/x/a@\""
+ }
+ }));
+ client.write_notification(
+ "workspace/didChangeConfiguration",
json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "import * as a from \"http://localhost:4545/x/a@\""
- }
+ "settings": {}
}),
);
- client
- .write_notification(
- "workspace/didChangeConfiguration",
- json!({
- "settings": {}
- }),
- )
- .unwrap();
- let (id, method, _) = client.read_request::<Value>().unwrap();
+ let (id, method, _) = client.read_request::<Value>();
assert_eq!(method, "workspace/configuration");
- client
- .write_response(
- id,
- json!([{
- "enable": true,
- "codeLens": {
- "implementations": true,
- "references": true
- },
- "importMap": null,
- "lint": true,
- "suggest": {
- "autoImports": true,
- "completeFunctionCalls": false,
- "names": true,
- "paths": true,
- "imports": {
- "hosts": {
- "http://localhost:4545/": true
- }
+ client.write_response(
+ id,
+ json!([{
+ "enable": true,
+ "codeLens": {
+ "implementations": true,
+ "references": true
+ },
+ "importMap": null,
+ "lint": true,
+ "suggest": {
+ "autoImports": true,
+ "completeFunctionCalls": false,
+ "names": true,
+ "paths": true,
+ "imports": {
+ "hosts": {
+ "http://localhost:4545/": true
}
- },
- "unstable": false
- }]),
- )
- .unwrap();
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/completion",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "position": { "line": 0, "character": 46 },
- "context": {
- "triggerKind": 2,
- "triggerCharacter": "@"
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
- assert!(!list.is_incomplete);
- assert_eq!(list.items.len(), 3);
- } else {
- panic!("unexpected response");
- }
- let (maybe_res, maybe_err) = client
- .write_request(
- "completionItem/resolve",
- json!({
- "label": "v2.0.0",
- "kind": 19,
- "detail": "(version)",
- "sortText": "0000000003",
- "filterText": "http://localhost:4545/x/a@v2.0.0",
- "textEdit": {
- "range": {
- "start": { "line": 0, "character": 20 },
- "end": { "line": 0, "character": 46 }
- },
- "newText": "http://localhost:4545/x/a@v2.0.0"
}
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
+ },
+ "unstable": false
+ }]),
+ );
+ let list = client.get_completion_list(
+ "file:///a/file.ts",
+ (0, 46),
+ json!({
+ "triggerKind": 2,
+ "triggerCharacter": "@"
+ }),
+ );
+ assert!(!list.is_incomplete);
+ assert_eq!(list.items.len(), 3);
+
+ let res = client.write_request(
+ "completionItem/resolve",
+ json!({
+ "label": "v2.0.0",
+ "kind": 19,
+ "detail": "(version)",
+ "sortText": "0000000003",
+ "filterText": "http://localhost:4545/x/a@v2.0.0",
+ "textEdit": {
+ "range": {
+ "start": { "line": 0, "character": 20 },
+ "end": { "line": 0, "character": 46 }
+ },
+ "newText": "http://localhost:4545/x/a@v2.0.0"
+ }
+ }),
+ );
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"label": "v2.0.0",
"kind": 19,
"detail": "(version)",
@@ -7302,7 +6300,7 @@ fn lsp_configuration_did_change() {
},
"newText": "http://localhost:4545/x/a@v2.0.0"
}
- }))
+ })
);
client.shutdown();
}
@@ -7311,40 +6309,31 @@ fn lsp_configuration_did_change() {
fn lsp_workspace_symbol() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "export class A {\n fieldA: string;\n fieldB: string;\n}\n",
- }
- }),
- );
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "export class A {\n fieldA: string;\n fieldB: string;\n}\n",
+ }
+ }));
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file_01.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "export class B {\n fieldC: string;\n fieldD: string;\n}\n",
+ }
+ }));
+ let res = client.write_request(
+ "workspace/symbol",
json!({
- "textDocument": {
- "uri": "file:///a/file_01.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "export class B {\n fieldC: string;\n fieldD: string;\n}\n",
- }
+ "query": "field"
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "workspace/symbol",
- json!({
- "query": "field"
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([
+ res,
+ json!([
{
"name": "fieldA",
"kind": 8,
@@ -7390,7 +6379,7 @@ fn lsp_workspace_symbol() {
},
"containerName": "B"
}
- ]))
+ ])
);
client.shutdown();
}
@@ -7399,51 +6388,45 @@ fn lsp_workspace_symbol() {
fn lsp_code_actions_ignore_lint() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text": "let message = 'Hello, Deno!';\nconsole.log(message);\n"
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/codeAction",
json!({
"textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text": "let message = 'Hello, Deno!';\nconsole.log(message);\n"
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 1, "character": 5 },
+ "end": { "line": 1, "character": 12 }
+ },
+ "context": {
+ "diagnostics": [
+ {
+ "range": {
+ "start": { "line": 1, "character": 5 },
+ "end": { "line": 1, "character": 12 }
+ },
+ "severity": 1,
+ "code": "prefer-const",
+ "source": "deno-lint",
+ "message": "'message' is never reassigned\nUse 'const' instead",
+ "relatedInformation": []
+ }
+ ],
+ "only": ["quickfix"]
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 1, "character": 5 },
- "end": { "line": 1, "character": 12 }
- },
- "context": {
- "diagnostics": [
- {
- "range": {
- "start": { "line": 1, "character": 5 },
- "end": { "line": 1, "character": 12 }
- },
- "severity": 1,
- "code": "prefer-const",
- "source": "deno-lint",
- "message": "'message' is never reassigned\nUse 'const' instead",
- "relatedInformation": []
- }
- ],
- "only": ["quickfix"]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Disable prefer-const for this line",
"kind": "quickfix",
"diagnostics": [{
@@ -7518,7 +6501,7 @@ fn lsp_code_actions_ignore_lint() {
}]
}
}
- }]))
+ }])
);
client.shutdown();
}
@@ -7528,54 +6511,48 @@ fn lsp_code_actions_ignore_lint() {
fn lsp_code_actions_update_ignore_lint() {
let mut client = LspClientBuilder::new().build();
client.initialize_default();
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts",
- "languageId": "typescript",
- "version": 1,
- "text":
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts",
+ "languageId": "typescript",
+ "version": 1,
+ "text":
"#!/usr/bin/env -S deno run
// deno-lint-ignore-file camelcase
let snake_case = 'Hello, Deno!';
console.log(snake_case);
",
+ }
+ }));
+ let res = client.write_request(
+ "textDocument/codeAction",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.ts"
+ },
+ "range": {
+ "start": { "line": 3, "character": 5 },
+ "end": { "line": 3, "character": 15 }
+ },
+ "context": {
+ "diagnostics": [{
+ "range": {
+ "start": { "line": 3, "character": 5 },
+ "end": { "line": 3, "character": 15 }
+ },
+ "severity": 1,
+ "code": "prefer-const",
+ "source": "deno-lint",
+ "message": "'snake_case' is never reassigned\nUse 'const' instead",
+ "relatedInformation": []
+ }],
+ "only": ["quickfix"]
}
}),
);
- let (maybe_res, maybe_err) = client
- .write_request(
- "textDocument/codeAction",
- json!({
- "textDocument": {
- "uri": "file:///a/file.ts"
- },
- "range": {
- "start": { "line": 3, "character": 5 },
- "end": { "line": 3, "character": 15 }
- },
- "context": {
- "diagnostics": [{
- "range": {
- "start": { "line": 3, "character": 5 },
- "end": { "line": 3, "character": 15 }
- },
- "severity": 1,
- "code": "prefer-const",
- "source": "deno-lint",
- "message": "'snake_case' is never reassigned\nUse 'const' instead",
- "relatedInformation": []
- }],
- "only": ["quickfix"]
- }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!([{
+ res,
+ json!([{
"title": "Disable prefer-const for this line",
"kind": "quickfix",
"diagnostics": [{
@@ -7650,7 +6627,7 @@ console.log(snake_case);
}]
}
}
- }]))
+ }])
);
client.shutdown();
}
@@ -7679,9 +6656,7 @@ fn lsp_lint_with_config() {
builder.set_config("./deno.lint.jsonc");
});
- let mut session = TestSession::from_client(client);
-
- let diagnostics = session.did_open(json!({
+ let diagnostics = client.did_open(json!({
"textDocument": {
"uri": "file:///a/file.ts",
"languageId": "typescript",
@@ -7695,7 +6670,7 @@ fn lsp_lint_with_config() {
diagnostics[0].code,
Some(lsp::NumberOrString::String("ban-untagged-todo".to_string()))
);
- session.shutdown_and_exit();
+ client.shutdown();
}
#[test]
@@ -7724,8 +6699,7 @@ fn lsp_lint_exclude_with_config() {
builder.set_config("./deno.lint.jsonc");
});
- let diagnostics = did_open(
- &mut client,
+ let diagnostics = client.did_open(
json!({
"textDocument": {
"uri": ModuleSpecifier::from_file_path(temp_dir.path().join("ignored.ts")).unwrap().to_string(),
@@ -7735,10 +6709,7 @@ fn lsp_lint_exclude_with_config() {
}
}),
);
- let diagnostics = diagnostics
- .into_iter()
- .flat_map(|x| x.diagnostics)
- .collect::<Vec<_>>();
+ let diagnostics = diagnostics.viewed();
assert_eq!(diagnostics, Vec::new());
client.shutdown();
}
@@ -7748,14 +6719,12 @@ fn lsp_jsx_import_source_pragma() {
let context = TestContextBuilder::new().use_http_server().build();
let mut client = context.new_lsp_command().build();
client.initialize_default();
- did_open(
- &mut client,
- json!({
- "textDocument": {
- "uri": "file:///a/file.tsx",
- "languageId": "typescriptreact",
- "version": 1,
- "text":
+ client.did_open(json!({
+ "textDocument": {
+ "uri": "file:///a/file.tsx",
+ "languageId": "typescriptreact",
+ "version": 1,
+ "text":
"/** @jsxImportSource http://localhost:4545/jsx */
function A() {
@@ -7766,39 +6735,31 @@ export function B() {
return <A></A>;
}
",
- }
+ }
+ }));
+ client.write_request(
+ "deno/cache",
+ json!({
+ "referrer": {
+ "uri": "file:///a/file.tsx",
+ },
+ "uris": [{
+ "uri": "http://127.0.0.1:4545/jsx/jsx-runtime",
+ }],
+ }),
+ );
+ let res = client.write_request(
+ "textDocument/hover",
+ json!({
+ "textDocument": {
+ "uri": "file:///a/file.tsx"
+ },
+ "position": { "line": 0, "character": 25 }
}),
);
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "deno/cache",
- json!({
- "referrer": {
- "uri": "file:///a/file.tsx",
- },
- "uris": [{
- "uri": "http://127.0.0.1:4545/jsx/jsx-runtime",
- }],
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, Value>(
- "textDocument/hover",
- json!({
- "textDocument": {
- "uri": "file:///a/file.tsx"
- },
- "position": { "line": 0, "character": 25 }
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
assert_eq!(
- maybe_res,
- Some(json!({
+ res,
+ json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: http&#8203;://localhost:4545/jsx/jsx-runtime\n",
@@ -7807,7 +6768,7 @@ export function B() {
"start": { "line": 0, "character": 21 },
"end": { "line": 0, "character": 46 }
}
- }))
+ })
);
client.shutdown();
}
@@ -7870,80 +6831,53 @@ Deno.test({
let mut client = context.new_lsp_command().build();
client.initialize_default();
- client
- .write_notification(
- "textDocument/didOpen",
- json!({
- "textDocument": {
- "uri": specifier,
- "languageId": "typescript",
- "version": 1,
- "text": contents,
- }
- }),
- )
- .unwrap();
+ client.did_open(json!({
+ "textDocument": {
+ "uri": specifier,
+ "languageId": "typescript",
+ "version": 1,
+ "text": contents,
+ }
+ }));
- handle_configuration_request(
- &mut client,
- json!([{
- "enable": true,
- "codeLens": {
- "test": true
+ let notification =
+ client.read_notification_with_method::<Value>("deno/testModule");
+ let params: TestModuleNotificationParams =
+ serde_json::from_value(notification.unwrap()).unwrap();
+ assert_eq!(params.text_document.uri, specifier);
+ assert_eq!(params.kind, TestModuleNotificationKind::Replace);
+ assert_eq!(params.label, "test.ts");
+ assert_eq!(params.tests.len(), 1);
+ let test = &params.tests[0];
+ assert_eq!(test.label, "test a");
+ assert!(test.steps.is_none());
+ assert_eq!(
+ test.range,
+ Some(lsp::Range {
+ start: lsp::Position {
+ line: 1,
+ character: 5,
+ },
+ end: lsp::Position {
+ line: 1,
+ character: 9,
}
- }]),
+ })
);
- for _ in 0..4 {
- let result = client.read_notification::<Value>();
- assert!(result.is_ok());
- let (method, notification) = result.unwrap();
- if method.as_str() == "deno/testModule" {
- let params: TestModuleNotificationParams =
- serde_json::from_value(notification.unwrap()).unwrap();
- assert_eq!(params.text_document.uri, specifier);
- assert_eq!(params.kind, TestModuleNotificationKind::Replace);
- assert_eq!(params.label, "test.ts");
- assert_eq!(params.tests.len(), 1);
- let test = &params.tests[0];
- assert_eq!(test.label, "test a");
- assert!(test.steps.is_none());
- assert_eq!(
- test.range,
- Some(lsp::Range {
- start: lsp::Position {
- line: 1,
- character: 5,
- },
- end: lsp::Position {
- line: 1,
- character: 9,
- }
- })
- );
- }
- }
-
- let (maybe_res, maybe_err) = client
- .write_request::<_, _, TestRunResponseParams>(
- "deno/testRun",
- json!({
- "id": 1,
- "kind": "run",
- }),
- )
- .unwrap();
- assert!(maybe_err.is_none());
- assert!(maybe_res.is_some());
- let res = maybe_res.unwrap();
+ let res = client.write_request_with_res_as::<TestRunResponseParams>(
+ "deno/testRun",
+ json!({
+ "id": 1,
+ "kind": "run",
+ }),
+ );
assert_eq!(res.enqueued.len(), 1);
assert_eq!(res.enqueued[0].text_document.uri, specifier);
assert_eq!(res.enqueued[0].ids.len(), 1);
let id = res.enqueued[0].ids[0].clone();
- let res = client.read_notification::<Value>();
- assert!(res.is_ok());
- let (method, notification) = res.unwrap();
+ let (method, notification) = client.read_notification::<Value>();
assert_eq!(method, "deno/testRunProgress");
assert_eq!(
notification,
@@ -7961,9 +6895,7 @@ Deno.test({
}))
);
- let res = client.read_notification::<Value>();
- assert!(res.is_ok());
- let (method, notification) = res.unwrap();
+ let (method, notification) = client.read_notification::<Value>();
assert_eq!(method, "deno/testRunProgress");
let notification_value = notification
.as_ref()
@@ -7999,9 +6931,7 @@ Deno.test({
}))
);
- let res = client.read_notification::<Value>();
- assert!(res.is_ok());
- let (method, notification) = res.unwrap();
+ let (method, notification) = client.read_notification::<Value>();
assert_eq!(method, "deno/testRunProgress");
let notification = notification.unwrap();
let obj = notification.as_object().unwrap();
@@ -8020,9 +6950,7 @@ Deno.test({
);
assert!(message.contains_key("duration"));
- let res = client.read_notification::<Value>();
- assert!(res.is_ok());
- let (method, notification) = res.unwrap();
+ let (method, notification) = client.read_notification::<Value>();
assert_eq!(method, "deno/testRunProgress");
assert_eq!(
notification,