summaryrefslogtreecommitdiff
path: root/cli/lsp/language_server.rs
diff options
context:
space:
mode:
authorKitson Kelly <me@kitsonkelly.com>2021-05-18 06:45:13 +1000
committerGitHub <noreply@github.com>2021-05-18 06:45:13 +1000
commit27e7bb090e9d771c8f3e4ddba4dd956a4a56855b (patch)
tree82cb99c1406fc94850bc3d5d66f8db40300860de /cli/lsp/language_server.rs
parentaecdbba2c25d08d771a4e4fbeb62cac60015a3bd (diff)
refactor: share test harness for lsp between bench and integration (#10659)
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r--cli/lsp/language_server.rs2395
1 files changed, 0 insertions, 2395 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index 1be65d0fe..9f5a7c84a 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -2608,2398 +2608,3 @@ impl Inner {
Ok(contents)
}
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::lsp::performance::PerformanceAverage;
- use lspower::jsonrpc;
- use lspower::ExitedError;
- use lspower::LspService;
- use std::fs;
- use std::task::Poll;
- use std::time::Instant;
- use tempfile::TempDir;
- use tower_test::mock::Spawn;
-
- enum LspResponse<V>
- where
- V: FnOnce(Value),
- {
- None,
- Delay(u64),
- RequestAny,
- Request(u64, Value),
- RequestAssert(V),
- RequestFixture(u64, String),
- }
-
- enum LspFixture {
- None,
- Path(&'static str),
- Value(Value),
- }
-
- type LspTestHarnessRequest = (LspFixture, LspResponse<fn(Value)>);
-
- struct LspTestHarness {
- requests: Vec<LspTestHarnessRequest>,
- service: Spawn<LspService>,
- }
-
- impl LspTestHarness {
- pub fn new(requests: Vec<LspTestHarnessRequest>) -> Self {
- let (service, _) = LspService::new(LanguageServer::new);
- let service = Spawn::new(service);
- Self { requests, service }
- }
-
- async fn run(&mut self) {
- for (value_or_str, expected) in self.requests.iter() {
- assert_eq!(self.service.poll_ready(), Poll::Ready(Ok(())));
- let fixtures_path = test_util::root_path().join("cli/tests/lsp");
- assert!(fixtures_path.is_dir());
- let response: Result<Option<jsonrpc::Outgoing>, ExitedError> =
- match value_or_str {
- LspFixture::None => Ok(None),
- LspFixture::Path(req_path_str) => {
- let req_path = fixtures_path.join(req_path_str);
- let req_str = fs::read_to_string(req_path).unwrap();
- let req: jsonrpc::Incoming =
- serde_json::from_str(&req_str).unwrap();
- self.service.call(req).await
- }
- LspFixture::Value(value) => {
- let req: jsonrpc::Incoming =
- serde_json::from_value(value.clone()).unwrap();
- self.service.call(req).await
- }
- };
- match response {
- Ok(result) => match expected {
- LspResponse::None => assert_eq!(result, None),
- LspResponse::Delay(millis) => {
- tokio::time::sleep(tokio::time::Duration::from_millis(*millis))
- .await
- }
- LspResponse::RequestAny => match result {
- Some(jsonrpc::Outgoing::Response(_)) => (),
- _ => panic!("unexpected result: {:?}", result),
- },
- LspResponse::Request(id, value) => match result {
- Some(jsonrpc::Outgoing::Response(resp)) => assert_eq!(
- resp,
- jsonrpc::Response::ok(jsonrpc::Id::Number(*id), value.clone())
- ),
- _ => panic!("unexpected result: {:?}", result),
- },
- LspResponse::RequestAssert(assert) => match result {
- Some(jsonrpc::Outgoing::Response(resp)) => assert(json!(resp)),
- _ => panic!("unexpected result: {:?}", result),
- },
- LspResponse::RequestFixture(id, res_path_str) => {
- let res_path = fixtures_path.join(res_path_str);
- let res_str = fs::read_to_string(res_path).unwrap();
- match result {
- Some(jsonrpc::Outgoing::Response(resp)) => assert_eq!(
- resp,
- jsonrpc::Response::ok(
- jsonrpc::Id::Number(*id),
- serde_json::from_str(&res_str).unwrap()
- )
- ),
- _ => panic!("unexpected result: {:?}", result),
- }
- }
- },
- Err(err) => panic!("Error result: {}", err),
- }
- }
- }
- }
-
- #[tokio::test]
- async fn test_startup_shutdown() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_hover() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("hover_request.json"),
- LspResponse::Request(
- 2,
- json!({
- "contents": [
- {
- "language": "typescript",
- "value": "const Deno.args: string[]"
- },
- "Returns the script arguments to the program. If for example we run a\nprogram:\n\ndeno run --allow-read https://deno.land/std/examples/cat.ts /etc/passwd\n\nThen `Deno.args` will contain:\n\n[ \"/etc/passwd\" ]"
- ],
- "range": {
- "start": {
- "line": 0,
- "character": 17
- },
- "end": {
- "line": 0,
- "character": 21
- }
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_hover_asset() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_asset.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("definition_request_asset.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("virtual_text_document_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("hover_request_asset.json"),
- LspResponse::Request(
- 5,
- json!({
- "contents": [
- {
- "language": "typescript",
- "value": "interface Date",
- },
- "Enables basic storage and retrieval of dates and times."
- ],
- "range": {
- "start": {
- "line": 109,
- "character": 10,
- },
- "end": {
- "line": 109,
- "character": 14,
- }
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_hover_disabled() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request_disabled.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("hover_request.json"),
- LspResponse::Request(2, json!(null)),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_hover_unstable_disabled() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_unstable.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("hover_request.json"),
- LspResponse::Request(
- 2,
- json!({
- "contents": [
- {
- "language": "typescript",
- "value": "any"
- }
- ],
- "range": {
- "start": {
- "line": 0,
- "character": 17
- },
- "end": {
- "line": 0,
- "character": 27
- }
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_hover_unstable_enabled() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request_unstable.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_unstable.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("hover_request.json"),
- LspResponse::Request(
- 2,
- json!({
- "contents": [
- {
- "language": "typescript",
- "value": "function Deno.openPlugin(filename: string): number"
- },
- "**UNSTABLE**: new API, yet to be vetted.\n\nOpen and initialize a plugin.\n\n```ts\nconst rid = Deno.openPlugin(\"./path/to/some/plugin.so\");\nconst opId = Deno.core.ops()[\"some_op\"];\nconst response = Deno.core.dispatch(opId, new Uint8Array([1,2,3,4]));\nconsole.log(`Response from plugin ${response}`);\n```\n\nRequires `allow-plugin` permission.\n\nThe plugin system is not stable and will change in the future, hence the\nlack of docs. For now take a look at the example\nhttps://github.com/denoland/deno/tree/main/test_plugin"
- ],
- "range": {
- "start": {
- "line": 0,
- "character": 17
- },
- "end": {
- "line": 0,
- "character": 27
- }
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_hover_change_mbc() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_mbc.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_change_notification_mbc.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("hover_request_mbc.json"),
- LspResponse::Request(
- 2,
- json!({
- "contents": [
- {
- "language": "typescript",
- "value": "const b: \"🦕😃\"",
- },
- "",
- ],
- "range": {
- "start": {
- "line": 2,
- "character": 15,
- },
- "end": {
- "line": 2,
- "character": 16,
- },
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[derive(Deserialize)]
- struct HoverResponse {
- pub result: Option<Hover>,
- }
-
- #[tokio::test]
- async fn test_hover_closed_document() {
- let temp_dir = TempDir::new()
- .expect("could not create temp dir")
- .into_path();
- let a_path = temp_dir.join("a.ts");
- fs::write(a_path, r#"export const a = "a";"#)
- .expect("could not write file");
- let b_path = temp_dir.join("b.ts");
- fs::write(&b_path, r#"export * from "./a.ts";"#)
- .expect("could not write file");
- let b_specifier =
- Url::from_file_path(b_path).expect("could not convert path");
- let c_path = temp_dir.join("c.ts");
- fs::write(&c_path, "import { a } from \"./b.ts\";\nconsole.log(a);\n")
- .expect("could not write file");
- let c_specifier =
- Url::from_file_path(c_path).expect("could not convert path");
-
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Value(json!({
- "jsonrpc": "2.0",
- "method": "textDocument/didOpen",
- "params": {
- "textDocument": {
- "uri": b_specifier,
- "languageId": "typescript",
- "version": 1,
- "text": r#"export * from "./a.ts";"#
- }
- }
- })),
- LspResponse::None,
- ),
- (
- LspFixture::Value(json!({
- "jsonrpc": "2.0",
- "method": "textDocument/didOpen",
- "params": {
- "textDocument": {
- "uri": c_specifier,
- "languageId": "typescript",
- "version": 1,
- "text": "import { a } from \"./b.ts\";\nconsole.log(a);\n",
- }
- }
- })),
- LspResponse::None,
- ),
- (
- LspFixture::Value(json!({
- "jsonrpc": "2.0",
- "id": 2,
- "method": "textDocument/hover",
- "params": {
- "textDocument": {
- "uri": c_specifier,
- },
- "position": {
- "line": 0,
- "character": 10
- }
- }
- })),
- LspResponse::RequestAssert(|value| {
- let resp: HoverResponse = serde_json::from_value(value).unwrap();
- if let Some(hover) = resp.result {
- assert_eq!(
- hover,
- Hover {
- contents: HoverContents::Array(vec![
- MarkedString::LanguageString(LanguageString {
- language: "typescript".to_string(),
- value: "(alias) const a: \"a\"\nimport a".to_string()
- }),
- MarkedString::String("".to_string()),
- ]),
- range: Some(Range {
- start: Position {
- line: 0,
- character: 9,
- },
- end: Position {
- line: 0,
- character: 10,
- }
- }),
- }
- );
- } else {
- panic!("no response");
- }
- }),
- ),
- (
- LspFixture::Value(json!({
- "jsonrpc": "2.0",
- "method": "textDocument/didClose",
- "params": {
- "textDocument": {
- "uri": b_specifier,
- }
- }
- })),
- LspResponse::None,
- ),
- (
- LspFixture::Value(json!({
- "jsonrpc": "2.0",
- "id": 4,
- "method": "textDocument/hover",
- "params": {
- "textDocument": {
- "uri": c_specifier,
- },
- "position": {
- "line": 0,
- "character": 10
- }
- }
- })),
- LspResponse::RequestAssert(|value| {
- let resp: HoverResponse = serde_json::from_value(value).unwrap();
- if let Some(hover) = resp.result {
- assert_eq!(
- hover,
- Hover {
- contents: HoverContents::Array(vec![
- MarkedString::LanguageString(LanguageString {
- language: "typescript".to_string(),
- value: "(alias) const a: \"a\"\nimport a".to_string()
- }),
- MarkedString::String("".to_string()),
- ]),
- range: Some(Range {
- start: Position {
- line: 0,
- character: 9,
- },
- end: Position {
- line: 0,
- character: 10,
- }
- }),
- }
- );
- } else {
- panic!("no response");
- }
- }),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_call_hierarchy() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("prepare_call_hierarchy_did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("prepare_call_hierarchy_request.json"),
- LspResponse::Request(
- 2,
- json!([
- {
- "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
- }
- }
- }
- ]),
- ),
- ),
- (
- LspFixture::Path("incoming_calls_request.json"),
- LspResponse::Request(
- 4,
- json!([
- {
- "from": {
- "name": "main",
- "kind": 12,
- "detail": "",
- "uri": "file:///a/file.ts",
- "range": {
- "start": {
- "line": 10,
- "character": 0
- },
- "end": {
- "line": 13,
- "character": 1
- }
- },
- "selectionRange": {
- "start": {
- "line": 10,
- "character": 9
- },
- "end": {
- "line": 10,
- "character": 13
- }
- }
- },
- "fromRanges": [
- {
- "start": {
- "line": 12,
- "character": 6
- },
- "end": {
- "line": 12,
- "character": 9
- }
- }
- ]
- }
- ]),
- ),
- ),
- (
- LspFixture::Path("outgoing_calls_request.json"),
- LspResponse::Request(
- 5,
- json!([
- {
- "to": {
- "name": "foo",
- "kind": 12,
- "detail": "",
- "uri": "file:///a/file.ts",
- "range": {
- "start": {
- "line": 0,
- "character": 0
- },
- "end": {
- "line": 2,
- "character": 1
- }
- },
- "selectionRange": {
- "start": {
- "line": 0,
- "character": 9
- },
- "end": {
- "line": 0,
- "character": 12
- }
- }
- },
- "fromRanges": [
- {
- "start": {
- "line": 6,
- "character": 11
- },
- "end": {
- "line": 6,
- "character": 14
- }
- }
- ]
- }
- ]),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_format_mbc() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_mbc_fmt.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("formatting_request_mbc_fmt.json"),
- LspResponse::Request(
- 2,
- json!([
- {
- "range": {
- "start": {
- "line": 0,
- "character": 12
- },
- "end": {
- "line": 0,
- "character": 13,
- }
- },
- "newText": "\""
- },
- {
- "range": {
- "start": {
- "line": 0,
- "character": 21
- },
- "end": {
- "line": 0,
- "character": 22
- }
- },
- "newText": "\";"
- },
- {
- "range": {
- "start": {
- "line": 1,
- "character": 12,
- },
- "end": {
- "line": 1,
- "character": 13,
- }
- },
- "newText": "\""
- },
- {
- "range": {
- "start": {
- "line": 1,
- "character": 23,
- },
- "end": {
- "line": 1,
- "character": 25,
- }
- },
- "newText": "\");"
- }
- ]),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- #[ignore] // TODO(ry) Re-enable. Flaky on ubuntu-latest-xl.
- async fn test_large_doc_change() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_large.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_change_notification_large.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_change_notification_large_02.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_change_notification_large_03.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("hover_request_large_01.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("hover_request_large_02.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("hover_request_large_03.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- let time = Instant::now();
- harness.run().await;
- assert!(
- time.elapsed().as_millis() <= 10000,
- "the execution time exceeded 10000ms"
- );
- }
-
- #[tokio::test]
- async fn test_document_symbol() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("document_symbol_did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("document_symbol_request.json"),
- LspResponse::Request(
- 2,
- json!([
- {
- "name": "bar",
- "kind": 13,
- "range": {
- "start": {
- "line": 17,
- "character": 4
- },
- "end": {
- "line": 17,
- "character": 26
- }
- },
- "selectionRange": {
- "start": {
- "line": 17,
- "character": 4
- },
- "end": {
- "line": 17,
- "character": 7
- }
- }
- },
- {
- "name": "Bar",
- "kind": 5,
- "range": {
- "start": {
- "line": 4,
- "character": 0
- },
- "end": {
- "line": 13,
- "character": 1
- }
- },
- "selectionRange": {
- "start": {
- "line": 4,
- "character": 6
- },
- "end": {
- "line": 4,
- "character": 9
- }
- },
- "children": [
- {
- "name": "constructor",
- "kind": 9,
- "range": {
- "start": {
- "line": 5,
- "character": 2
- },
- "end": {
- "line": 5,
- "character": 35
- }
- },
- "selectionRange": {
- "start": {
- "line": 5,
- "character": 2
- },
- "end": {
- "line": 5,
- "character": 35
- }
- }
- },
- {
- "name": "baz",
- "kind": 6,
- "tags": [
- 1
- ],
- "range": {
- "start": {
- "line": 8,
- "character": 2
- },
- "end": {
- "line": 8,
- "character": 25
- }
- },
- "selectionRange": {
- "start": {
- "line": 8,
- "character": 2
- },
- "end": {
- "line": 8,
- "character": 5
- }
- }
- },
- {
- "name": "foo",
- "kind": 6,
- "range": {
- "start": {
- "line": 6,
- "character": 2
- },
- "end": {
- "line": 6,
- "character": 24
- }
- },
- "selectionRange": {
- "start": {
- "line": 6,
- "character": 2
- },
- "end": {
- "line": 6,
- "character": 5
- }
- }
- },
- {
- "name": "getStaticBar",
- "kind": 6,
- "range": {
- "start": {
- "line": 12,
- "character": 2
- },
- "end": {
- "line": 12,
- "character": 57
- }
- },
- "selectionRange": {
- "start": {
- "line": 12,
- "character": 17
- },
- "end": {
- "line": 12,
- "character": 29
- }
- }
- },
- {
- "name": "staticBar",
- "kind": 7,
- "range": {
- "start": {
- "line": 11,
- "character": 2
- },
- "end": {
- "line": 11,
- "character": 32
- }
- },
- "selectionRange": {
- "start": {
- "line": 11,
- "character": 9
- },
- "end": {
- "line": 11,
- "character": 18
- }
- }
- },
- {
- "name": "value",
- "kind": 7,
- "range": {
- "start": {
- "line": 9,
- "character": 2
- },
- "end": {
- "line": 9,
- "character": 35
- }
- },
- "selectionRange": {
- "start": {
- "line": 9,
- "character": 6
- },
- "end": {
- "line": 9,
- "character": 11
- }
- }
- },
- {
- "name": "value",
- "kind": 7,
- "range": {
- "start": {
- "line": 10,
- "character": 2
- },
- "end": {
- "line": 10,
- "character": 42
- }
- },
- "selectionRange": {
- "start": {
- "line": 10,
- "character": 6
- },
- "end": {
- "line": 10,
- "character": 11
- }
- }
- },
- {
- "name": "x",
- "kind": 7,
- "range": {
- "start": {
- "line": 5,
- "character": 14
- },
- "end": {
- "line": 5,
- "character": 30
- }
- },
- "selectionRange": {
- "start": {
- "line": 5,
- "character": 21
- },
- "end": {
- "line": 5,
- "character": 22
- }
- }
- }
- ]
- },
- {
- "name": "IFoo",
- "kind": 11,
- "range": {
- "start": {
- "line": 0,
- "character": 0
- },
- "end": {
- "line": 2,
- "character": 1
- }
- },
- "selectionRange": {
- "start": {
- "line": 0,
- "character": 10
- },
- "end": {
- "line": 0,
- "character": 14
- }
- },
- "children": [
- {
- "name": "foo",
- "kind": 6,
- "range": {
- "start": {
- "line": 1,
- "character": 2
- },
- "end": {
- "line": 1,
- "character": 17
- }
- },
- "selectionRange": {
- "start": {
- "line": 1,
- "character": 2
- },
- "end": {
- "line": 1,
- "character": 5
- }
- }
- }
- ]
- },
- {
- "name": "Values",
- "kind": 10,
- "range": {
- "start": {
- "line": 15,
- "character": 0
- },
- "end": {
- "line": 15,
- "character": 30
- }
- },
- "selectionRange": {
- "start": {
- "line": 15,
- "character": 5
- },
- "end": {
- "line": 15,
- "character": 11
- }
- },
- "children": [
- {
- "name": "value1",
- "kind": 13,
- "range": {
- "start": {
- "line": 15,
- "character": 14
- },
- "end": {
- "line": 15,
- "character": 20
- }
- },
- "selectionRange": {
- "start": {
- "line": 15,
- "character": 14
- },
- "end": {
- "line": 15,
- "character": 20
- }
- }
- },
- {
- "name": "value2",
- "kind": 13,
- "range": {
- "start": {
- "line": 15,
- "character": 22
- },
- "end": {
- "line": 15,
- "character": 28
- }
- },
- "selectionRange": {
- "start": {
- "line": 15,
- "character": 22
- },
- "end": {
- "line": 15,
- "character": 28
- }
- }
- }
- ]
- }
- ]),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_folding_range() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("folding_range_did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("folding_range_request.json"),
- LspResponse::Request(
- 2,
- json!([
- {
- "startLine": 0,
- "endLine": 12,
- "kind": "region"
- },
- {
- "startLine": 1,
- "endLine": 3,
- "kind": "comment"
- },
- {
- "startLine": 4,
- "endLine": 10
- },
- {
- "startLine": 5,
- "endLine": 9
- },
- {
- "startLine": 6,
- "endLine": 7
- }
- ]),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_rename() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("rename_did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("rename_request.json"),
- LspResponse::Request(
- 2,
- json!({
- "documentChanges": [{
- "textDocument": {
- "uri": "file:///a/file.ts",
- "version": 1,
- },
- "edits": [{
- "range": {
- "start": {
- "line": 0,
- "character": 4
- },
- "end": {
- "line": 0,
- "character": 12
- }
- },
- "newText": "variable_modified"
- }, {
- "range": {
- "start": {
- "line": 1,
- "character": 12
- },
- "end": {
- "line": 1,
- "character": 20
- }
- },
- "newText": "variable_modified"
- }]
- }]
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_selection_range() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("selection_range_did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("selection_range_request.json"),
- LspResponse::Request(
- 2,
- json!([{
- "range": {
- "start": {
- "line": 2,
- "character": 8
- },
- "end": {
- "line": 2,
- "character": 9
- }
- },
- "parent": {
- "range": {
- "start": {
- "line": 2,
- "character": 8
- },
- "end": {
- "line": 2,
- "character": 15
- }
- },
- "parent": {
- "range": {
- "start": {
- "line": 2,
- "character": 4
- },
- "end": {
- "line": 4,
- "character": 5
- }
- },
- "parent": {
- "range": {
- "start": {
- "line": 1,
- "character": 13
- },
- "end": {
- "line": 6,
- "character": 2
- }
- },
- "parent": {
- "range": {
- "start": {
- "line": 1,
- "character": 2
- },
- "end": {
- "line": 6,
- "character": 3
- }
- },
- "parent": {
- "range": {
- "start": {
- "line": 0,
- "character": 11
- },
- "end": {
- "line": 7,
- "character": 0
- }
- },
- "parent": {
- "range": {
- "start": {
- "line": 0,
- "character": 0
- },
- "end": {
- "line": 7,
- "character": 1
- }
- }
- }
- }
- }
- }
- }
- }
- }]),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- #[rustfmt::skip]
- async fn test_semantic_tokens() {
- let mut harness = LspTestHarness::new(vec![
- (LspFixture::Path("initialize_request.json"), LspResponse::RequestAny),
- (LspFixture::Path("initialized_notification.json"), LspResponse::None),
- (
- LspFixture::Path("semantic_tokens_did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("semantic_tokens_full_request.json"),
- LspResponse::Request(
- 2,
- 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 ,3, 10 ,4, 2, 1, 1, 11 ,1, 9, 9, 1, 2, 3, 11 ,1, 3, 6, 3, 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]
- }),
- ),
- ),
- (
- LspFixture::Path("semantic_tokens_range_request.json"),
- LspResponse::Request(
- 4,
- 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]
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (LspFixture::Path("exit_notification.json"), LspResponse::None),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_code_lens_request() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_cl_references.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("code_lens_request.json"),
- LspResponse::Request(
- 2,
- json!([
- {
- "range": {
- "start": {
- "line": 0,
- "character": 6,
- },
- "end": {
- "line": 0,
- "character": 7,
- }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "references",
- },
- },
- {
- "range": {
- "start": {
- "line": 1,
- "character": 2,
- },
- "end": {
- "line": 1,
- "character": 3,
- }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "references",
- }
- }
- ]),
- ),
- ),
- (
- LspFixture::Path("code_lens_resolve_request.json"),
- LspResponse::Request(
- 4,
- json!({
- "range": {
- "start": {
- "line": 0,
- "character": 6,
- },
- "end": {
- "line": 0,
- "character": 7,
- }
- },
- "command": {
- "title": "1 reference",
- "command": "deno.showReferences",
- "arguments": [
- "file:///a/file.ts",
- {
- "line": 0,
- "character": 6,
- },
- [
- {
- "uri": "file:///a/file.ts",
- "range": {
- "start": {
- "line": 12,
- "character": 14,
- },
- "end": {
- "line": 12,
- "character": 15,
- }
- }
- }
- ],
- ]
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_signature_help() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("signature_help_did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("signature_help_request_01.json"),
- LspResponse::Request(
- 1,
- json!({
- "signatures": [
- {
- "label": "add(a: number, b: number): number",
- "documentation": "Adds two numbers.",
- "parameters": [
- {
- "label": "a: number",
- "documentation": "This is a first number."
- },
- {
- "label": "b: number",
- "documentation": "This is a second number."
- }
- ]
- }
- ],
- "activeSignature": 0,
- "activeParameter": 0
- }),
- ),
- ),
- (
- LspFixture::Path("signature_help_did_change_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("signature_help_request_02.json"),
- LspResponse::Request(
- 2,
- json!({
- "signatures": [
- {
- "label": "add(a: number, b: number): number",
- "documentation": "Adds two numbers.",
- "parameters": [
- {
- "label": "a: number",
- "documentation": "This is a first number."
- },
- {
- "label": "b: number",
- "documentation": "This is a second number."
- }
- ]
- }
- ],
- "activeSignature": 0,
- "activeParameter": 1
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_code_lens_impl_request() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_cl_impl.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("code_lens_request.json"),
- LspResponse::Request(
- 2,
- json!([
- {
- "range": {
- "start": {
- "line": 0,
- "character": 10,
- },
- "end": {
- "line": 0,
- "character": 11,
- }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "implementations",
- },
- },
- {
- "range": {
- "start": {
- "line": 0,
- "character": 10,
- },
- "end": {
- "line": 0,
- "character": 11,
- }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "references",
- },
- },
- {
- "range": {
- "start": {
- "line": 4,
- "character": 6,
- },
- "end": {
- "line": 4,
- "character": 7,
- }
- },
- "data": {
- "specifier": "file:///a/file.ts",
- "source": "references",
- },
- },
- ]),
- ),
- ),
- (
- LspFixture::Path("code_lens_resolve_request_impl.json"),
- LspResponse::Request(
- 4,
- json!({
- "range": {
- "start": {
- "line": 0,
- "character": 10,
- },
- "end": {
- "line": 0,
- "character": 11,
- }
- },
- "command": {
- "title": "1 implementation",
- "command": "deno.showReferences",
- "arguments": [
- "file:///a/file.ts",
- {
- "line": 0,
- "character": 10,
- },
- [
- {
- "uri": "file:///a/file.ts",
- "range": {
- "start": {
- "line": 4,
- "character": 6,
- },
- "end": {
- "line": 4,
- "character": 7,
- }
- }
- }
- ],
- ]
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[derive(Deserialize)]
- struct CodeLensResponse {
- pub result: Option<Vec<CodeLens>>,
- }
-
- #[derive(Deserialize)]
- struct CodeLensResolveResponse {
- pub result: CodeLens,
- }
-
- #[tokio::test]
- async fn test_code_lens_non_doc_nav_tree() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_asset.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("references_request_asset.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("virtual_text_document_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("code_lens_request_asset.json"),
- LspResponse::RequestAssert(|value| {
- let resp: CodeLensResponse = serde_json::from_value(value).unwrap();
- let lenses = resp.result.unwrap();
- assert!(lenses.len() > 50);
- }),
- ),
- (
- LspFixture::Path("code_lens_resolve_request_asset.json"),
- LspResponse::RequestAssert(|value| {
- let resp: CodeLensResolveResponse =
- serde_json::from_value(value).unwrap();
- assert!(resp.result.command.is_some());
- }),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_code_actions() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_code_action.json"),
- LspResponse::None,
- ),
- (LspFixture::None, LspResponse::Delay(20000)),
- (
- LspFixture::Path("code_action_request.json"),
- LspResponse::RequestFixture(2, "code_action_response.json".to_string()),
- ),
- (
- LspFixture::Path("code_action_resolve_request.json"),
- LspResponse::RequestFixture(
- 4,
- "code_action_resolve_request_response.json".to_string(),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_code_actions_deno_cache() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_cache.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("code_action_request_cache.json"),
- LspResponse::RequestFixture(
- 2,
- "code_action_response_cache.json".to_string(),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[derive(Deserialize)]
- struct CompletionResult {
- pub result: Option<CompletionResponse>,
- }
-
- #[tokio::test]
- async fn test_completions() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_completions.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("completion_request.json"),
- LspResponse::RequestAssert(|value| {
- let response: CompletionResult =
- serde_json::from_value(value).unwrap();
- let result = response.result.unwrap();
- match result {
- CompletionResponse::List(list) => {
- // there should be at least 90 completions for `Deno.`
- assert!(list.items.len() > 90);
- }
- _ => panic!("unexpected result"),
- }
- }),
- ),
- (
- LspFixture::Path("completion_resolve_request.json"),
- LspResponse::Request(
- 4,
- json!({
- "label": "build",
- "kind": 6,
- "detail": "const Deno.build: {\n target: string;\n arch: \"x86_64\" | \"aarch64\";\n os: \"darwin\" | \"linux\" | \"windows\";\n vendor: string;\n env?: string | undefined;\n}",
- "documentation": {
- "kind": "markdown",
- "value": "Build related information."
- },
- "sortText": "1",
- "insertTextFormat": 1,
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_completions_optional() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_completion_optional.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("completion_request_optional.json"),
- LspResponse::Request(
- 2,
- json!({
- "isIncomplete": false,
- "items": [
- {
- "label": "b?",
- "kind": 5,
- "sortText": "1",
- "filterText": "b",
- "insertText": "b",
- "data": {
- "tsc": {
- "specifier": "file:///a/file.ts",
- "position": 79,
- "name": "b",
- "useCodeSnippet": false
- }
- }
- }
- ]
- }),
- ),
- ),
- (
- LspFixture::Path("completion_resolve_request_optional.json"),
- LspResponse::Request(
- 4,
- json!({
- "label": "b?",
- "kind": 5,
- "detail": "(property) A.b?: string | undefined",
- "documentation": {
- "kind": "markdown",
- "value": ""
- },
- "sortText": "1",
- "filterText": "b",
- "insertText": "b"
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_completions_registry() {
- let _g = test_util::http_server();
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request_registry.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_completion_registry.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("completion_request_registry.json"),
- LspResponse::RequestAssert(|value| {
- let response: CompletionResult =
- serde_json::from_value(value).unwrap();
- let result = response.result.unwrap();
- if let CompletionResponse::List(list) = result {
- assert_eq!(list.items.len(), 3);
- } else {
- panic!("unexpected result");
- }
- }),
- ),
- (
- LspFixture::Path("completion_resolve_request_registry.json"),
- LspResponse::Request(
- 4,
- 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"
- }
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[tokio::test]
- async fn test_completion_registry_empty_specifier() {
- let _g = test_util::http_server();
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request_registry.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification_completion_registry_02.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("completion_request_registry_02.json"),
- LspResponse::Request(
- 2,
- json!({
- "isIncomplete": false,
- "items": [
- {
- "label": ".",
- "kind": 19,
- "detail": "(local)",
- "sortText": "1",
- "insertText": "."
- },
- {
- "label": "..",
- "kind": 19,
- "detail": "(local)",
- "sortText": "1",
- "insertText": ".."
- },
- {
- "label": "http://localhost:4545",
- "kind": 19,
- "detail": "(registry)",
- "sortText": "2",
- "textEdit": {
- "range": {
- "start": {
- "line": 0,
- "character": 20
- },
- "end": {
- "line": 0,
- "character": 20
- }
- },
- "newText": "http://localhost:4545"
- }
- }
- ]
- }),
- ),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-
- #[derive(Deserialize)]
- struct PerformanceAverages {
- averages: Vec<PerformanceAverage>,
- }
- #[derive(Deserialize)]
- struct PerformanceResponse {
- result: PerformanceAverages,
- }
-
- #[tokio::test]
- async fn test_deno_performance_request() {
- let mut harness = LspTestHarness::new(vec![
- (
- LspFixture::Path("initialize_request.json"),
- LspResponse::RequestAny,
- ),
- (
- LspFixture::Path("initialized_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("did_open_notification.json"),
- LspResponse::None,
- ),
- (
- LspFixture::Path("hover_request.json"),
- LspResponse::Request(
- 2,
- json!({
- "contents": [
- {
- "language": "typescript",
- "value": "const Deno.args: string[]"
- },
- "Returns the script arguments to the program. If for example we run a\nprogram:\n\ndeno run --allow-read https://deno.land/std/examples/cat.ts /etc/passwd\n\nThen `Deno.args` will contain:\n\n[ \"/etc/passwd\" ]"
- ],
- "range": {
- "start": {
- "line": 0,
- "character": 17
- },
- "end": {
- "line": 0,
- "character": 21
- }
- }
- }),
- ),
- ),
- (
- LspFixture::Path("performance_request.json"),
- LspResponse::RequestAssert(|value| {
- let resp: PerformanceResponse =
- serde_json::from_value(value).unwrap();
- // the len can be variable since some of the parts of the language
- // server run in separate threads and may not add to performance by
- // the time the results are checked.
- assert!(resp.result.averages.len() >= 6);
- }),
- ),
- (
- LspFixture::Path("shutdown_request.json"),
- LspResponse::Request(3, json!(null)),
- ),
- (
- LspFixture::Path("exit_notification.json"),
- LspResponse::None,
- ),
- ]);
- harness.run().await;
- }
-}