1#![deny(missing_debug_implementations)]
6#![deny(missing_docs)]
7#![forbid(unsafe_code)]
8
9pub extern crate lsp;
10
11mod client;
12mod codec;
13pub mod jsonrpc;
14mod server;
15mod service;
16mod transport;
17
18pub use self::{
19 client::{CancellationToken, Client, TokenCanceller},
20 service::{ExitedError, LspService, MessageStream},
21 transport::Server,
22};
23pub use async_trait::async_trait;
24use auto_impl::auto_impl;
25use lspower_macros::rpc;
26
27#[rpc]
34#[async_trait]
35#[auto_impl(Arc, Box)]
36pub trait LanguageServer: Send + Sync + 'static {
37 #[rpc(name = "initialize")]
44 async fn initialize(&self, params: lsp::InitializeParams) -> crate::jsonrpc::Result<lsp::InitializeResult>;
45
46 #[rpc(name = "initialized")]
54 async fn initialized(&self, _params: lsp::InitializedParams) {
55 }
56
57 #[rpc(name = "shutdown")]
68 async fn shutdown(&self) -> crate::jsonrpc::Result<()>;
69
70 #[rpc(name = "workspace/didChangeWorkspaceFolders")]
85 async fn did_change_workspace_folders(&self, _params: lsp::DidChangeWorkspaceFoldersParams) {
86 log::warn!("Got a workspace/didChangeWorkspaceFolders notification, but it is not implemented");
87 }
88
89 #[rpc(name = "workspace/didChangeConfiguration")]
94 async fn did_change_configuration(&self, _params: lsp::DidChangeConfigurationParams) {
95 log::warn!("Got a workspace/didChangeConfiguration notification, but it is not implemented");
96 }
97
98 #[rpc(name = "workspace/didChangeWatchedFiles")]
108 async fn did_change_watched_files(&self, _params: lsp::DidChangeWatchedFilesParams) {
109 log::warn!("Got a workspace/didChangeWatchedFiles notification, but it is not implemented");
110 }
111
112 #[rpc(name = "workspace/symbol")]
117 async fn symbol(
118 &self,
119 _params: lsp::WorkspaceSymbolParams,
120 ) -> crate::jsonrpc::Result<Option<Vec<lsp::SymbolInformation>>> {
121 log::error!("Got a workspace/symbol request, but it is not implemented");
122 Err(crate::jsonrpc::Error::method_not_found())
123 }
124
125 #[rpc(name = "workspace/executeCommand")]
133 async fn execute_command(
134 &self,
135 _params: lsp::ExecuteCommandParams,
136 ) -> crate::jsonrpc::Result<Option<serde_json::Value>> {
137 log::error!("Got a workspace/executeCommand request, but it is not implemented");
138 Err(crate::jsonrpc::Error::method_not_found())
139 }
140
141 #[rpc(name = "textDocument/didOpen")]
150 async fn did_open(&self, _params: lsp::DidOpenTextDocumentParams) {
151 log::warn!("Got a textDocument/didOpen notification, but it is not implemented");
152 }
153
154 #[rpc(name = "textDocument/didChange")]
162 async fn did_change(&self, _params: lsp::DidChangeTextDocumentParams) {
163 log::warn!("Got a textDocument/didChange notification, but it is not implemented");
164 }
165
166 #[rpc(name = "textDocument/willSave")]
171 async fn will_save(&self, _params: lsp::WillSaveTextDocumentParams) {
172 log::warn!("Got a textDocument/willSave notification, but it is not implemented");
173 }
174
175 #[rpc(name = "textDocument/willSaveWaitUntil")]
184 async fn will_save_wait_until(
185 &self,
186 _params: lsp::WillSaveTextDocumentParams,
187 ) -> crate::jsonrpc::Result<Option<Vec<lsp::TextEdit>>> {
188 log::error!("Got a textDocument/willSaveWaitUntil request, but it is not implemented");
189 Err(crate::jsonrpc::Error::method_not_found())
190 }
191
192 #[rpc(name = "textDocument/didSave")]
197 async fn did_save(&self, _params: lsp::DidSaveTextDocumentParams) {
198 log::warn!("Got a textDocument/didSave notification, but it is not implemented");
199 }
200
201 #[rpc(name = "textDocument/didClose")]
209 async fn did_close(&self, _params: lsp::DidCloseTextDocumentParams) {
210 log::warn!("Got a textDocument/didClose notification, but it is not implemented");
211 }
212
213 #[rpc(name = "textDocument/completion")]
222 async fn completion(
223 &self,
224 _params: lsp::CompletionParams,
225 ) -> crate::jsonrpc::Result<Option<lsp::CompletionResponse>> {
226 log::error!("Got a textDocument/completion request, but it is not implemented");
227 Err(crate::jsonrpc::Error::method_not_found())
228 }
229
230 #[rpc(name = "completionItem/resolve")]
235 async fn completion_resolve(&self, _params: lsp::CompletionItem) -> crate::jsonrpc::Result<lsp::CompletionItem> {
236 log::error!("Got a completionItem/resolve request, but it is not implemented");
237 Err(crate::jsonrpc::Error::method_not_found())
238 }
239
240 #[rpc(name = "textDocument/hover")]
248 async fn hover(&self, _params: lsp::HoverParams) -> crate::jsonrpc::Result<Option<lsp::Hover>> {
249 log::error!("Got a textDocument/hover request, but it is not implemented");
250 Err(crate::jsonrpc::Error::method_not_found())
251 }
252
253 #[rpc(name = "textDocument/signatureHelp")]
258 async fn signature_help(
259 &self,
260 _params: lsp::SignatureHelpParams,
261 ) -> crate::jsonrpc::Result<Option<lsp::SignatureHelp>> {
262 log::error!("Got a textDocument/signatureHelp request, but it is not implemented");
263 Err(crate::jsonrpc::Error::method_not_found())
264 }
265
266 #[rpc(name = "textDocument/declaration")]
286 async fn goto_declaration(
287 &self,
288 _params: lsp::request::GotoDeclarationParams,
289 ) -> crate::jsonrpc::Result<Option<lsp::request::GotoDeclarationResponse>> {
290 log::error!("Got a textDocument/declaration request, but it is not implemented");
291 Err(crate::jsonrpc::Error::method_not_found())
292 }
293
294 #[rpc(name = "textDocument/definition")]
312 async fn goto_definition(
313 &self,
314 _params: lsp::GotoDefinitionParams,
315 ) -> crate::jsonrpc::Result<Option<lsp::GotoDefinitionResponse>> {
316 log::error!("Got a textDocument/definition request, but it is not implemented");
317 Err(crate::jsonrpc::Error::method_not_found())
318 }
319
320 #[rpc(name = "textDocument/typeDefinition")]
340 async fn goto_type_definition(
341 &self,
342 _params: lsp::request::GotoTypeDefinitionParams,
343 ) -> crate::jsonrpc::Result<Option<lsp::request::GotoTypeDefinitionResponse>> {
344 log::error!("Got a textDocument/typeDefinition request, but it is not implemented");
345 Err(crate::jsonrpc::Error::method_not_found())
346 }
347
348 #[rpc(name = "textDocument/implementation")]
368 async fn goto_implementation(
369 &self,
370 _params: lsp::request::GotoImplementationParams,
371 ) -> crate::jsonrpc::Result<Option<lsp::request::GotoImplementationResponse>> {
372 log::error!("Got a textDocument/implementation request, but it is not implemented");
373 Err(crate::jsonrpc::Error::method_not_found())
374 }
375
376 #[rpc(name = "textDocument/references")]
381 async fn references(&self, _params: lsp::ReferenceParams) -> crate::jsonrpc::Result<Option<Vec<lsp::Location>>> {
382 log::error!("Got a textDocument/references request, but it is not implemented");
383 Err(crate::jsonrpc::Error::method_not_found())
384 }
385
386 #[rpc(name = "textDocument/documentHighlight")]
397 async fn document_highlight(
398 &self,
399 _params: lsp::DocumentHighlightParams,
400 ) -> crate::jsonrpc::Result<Option<Vec<lsp::DocumentHighlight>>> {
401 log::error!("Got a textDocument/documentHighlight request, but it is not implemented");
402 Err(crate::jsonrpc::Error::method_not_found())
403 }
404
405 #[rpc(name = "textDocument/documentSymbol")]
420 async fn document_symbol(
421 &self,
422 _params: lsp::DocumentSymbolParams,
423 ) -> crate::jsonrpc::Result<Option<lsp::DocumentSymbolResponse>> {
424 log::error!("Got a textDocument/documentSymbol request, but it is not implemented");
425 Err(crate::jsonrpc::Error::method_not_found())
426 }
427
428 #[rpc(name = "textDocument/codeAction")]
460 async fn code_action(
461 &self,
462 _params: lsp::CodeActionParams,
463 ) -> crate::jsonrpc::Result<Option<lsp::CodeActionResponse>> {
464 log::error!("Got a textDocument/codeAction request, but it is not implemented");
465 Err(crate::jsonrpc::Error::method_not_found())
466 }
467
468 #[rpc(name = "textDocument/codeLens")]
473 async fn code_lens(&self, _params: lsp::CodeLensParams) -> crate::jsonrpc::Result<Option<Vec<lsp::CodeLens>>> {
474 log::error!("Got a textDocument/codeLens request, but it is not implemented");
475 Err(crate::jsonrpc::Error::method_not_found())
476 }
477
478 #[rpc(name = "codeLens/resolve")]
483 async fn code_lens_resolve(&self, _params: lsp::CodeLens) -> crate::jsonrpc::Result<lsp::CodeLens> {
484 log::error!("Got a codeLens/resolve request, but it is not implemented");
485 Err(crate::jsonrpc::Error::method_not_found())
486 }
487
488 #[rpc(name = "textDocument/documentLink")]
508 async fn document_link(
509 &self,
510 _params: lsp::DocumentLinkParams,
511 ) -> crate::jsonrpc::Result<Option<Vec<lsp::DocumentLink>>> {
512 log::error!("Got a textDocument/documentLink request, but it is not implemented");
513 Err(crate::jsonrpc::Error::method_not_found())
514 }
515
516 #[rpc(name = "documentLink/resolve")]
524 async fn document_link_resolve(&self, _params: lsp::DocumentLink) -> crate::jsonrpc::Result<lsp::DocumentLink> {
525 log::error!("Got a documentLink/resolve request, but it is not implemented");
526 Err(crate::jsonrpc::Error::method_not_found())
527 }
528
529 #[rpc(name = "textDocument/documentColor")]
544 async fn document_color(
545 &self,
546 _params: lsp::DocumentColorParams,
547 ) -> crate::jsonrpc::Result<Vec<lsp::ColorInformation>> {
548 log::error!("Got a textDocument/documentColor request, but it is not implemented");
549 Err(crate::jsonrpc::Error::method_not_found())
550 }
551
552 #[rpc(name = "textDocument/colorPresentation")]
569 async fn color_presentation(
570 &self,
571 _params: lsp::ColorPresentationParams,
572 ) -> crate::jsonrpc::Result<Vec<lsp::ColorPresentation>> {
573 log::error!("Got a textDocument/colorPresentation request, but it is not implemented");
574 Err(crate::jsonrpc::Error::method_not_found())
575 }
576
577 #[rpc(name = "textDocument/formatting")]
582 async fn formatting(
583 &self,
584 _params: lsp::DocumentFormattingParams,
585 ) -> crate::jsonrpc::Result<Option<Vec<lsp::TextEdit>>> {
586 log::error!("Got a textDocument/formatting request, but it is not implemented");
587 Err(crate::jsonrpc::Error::method_not_found())
588 }
589
590 #[rpc(name = "textDocument/rangeFormatting")]
595 async fn range_formatting(
596 &self,
597 _params: lsp::DocumentRangeFormattingParams,
598 ) -> crate::jsonrpc::Result<Option<Vec<lsp::TextEdit>>> {
599 log::error!("Got a textDocument/rangeFormatting request, but it is not implemented");
600 Err(crate::jsonrpc::Error::method_not_found())
601 }
602
603 #[rpc(name = "textDocument/onTypeFormatting")]
608 async fn on_type_formatting(
609 &self,
610 _params: lsp::DocumentOnTypeFormattingParams,
611 ) -> crate::jsonrpc::Result<Option<Vec<lsp::TextEdit>>> {
612 log::error!("Got a textDocument/onTypeFormatting request, but it is not implemented");
613 Err(crate::jsonrpc::Error::method_not_found())
614 }
615
616 #[rpc(name = "textDocument/rename")]
622 async fn rename(&self, _params: lsp::RenameParams) -> crate::jsonrpc::Result<Option<lsp::WorkspaceEdit>> {
623 log::error!("Got a textDocument/rename request, but it is not implemented");
624 Err(crate::jsonrpc::Error::method_not_found())
625 }
626
627 #[rpc(name = "textDocument/prepareRename")]
636 async fn prepare_rename(
637 &self,
638 _params: lsp::TextDocumentPositionParams,
639 ) -> crate::jsonrpc::Result<Option<lsp::PrepareRenameResponse>> {
640 log::error!("Got a textDocument/prepareRename request, but it is not implemented");
641 Err(crate::jsonrpc::Error::method_not_found())
642 }
643
644 #[rpc(name = "textDocument/foldingRange")]
653 async fn folding_range(
654 &self,
655 _params: lsp::FoldingRangeParams,
656 ) -> crate::jsonrpc::Result<Option<Vec<lsp::FoldingRange>>> {
657 log::error!("Got a textDocument/foldingRange request, but it is not implemented");
658 Err(crate::jsonrpc::Error::method_not_found())
659 }
660
661 #[rpc(name = "textDocument/selectionRange")]
674 async fn selection_range(
675 &self,
676 _params: lsp::SelectionRangeParams,
677 ) -> crate::jsonrpc::Result<Option<Vec<lsp::SelectionRange>>> {
678 log::error!("Got a textDocument/selectionRange request, but it is not implemented");
679 Err(crate::jsonrpc::Error::method_not_found())
680 }
681
682 #[rpc(name = "callHierarchy/incomingCalls")]
684 async fn incoming_calls(
685 &self,
686 _params: lsp::CallHierarchyIncomingCallsParams,
687 ) -> crate::jsonrpc::Result<Option<Vec<lsp::CallHierarchyIncomingCall>>> {
688 log::error!("Got a callHierarchy/incomingCalls request, but it is not implemented");
689 Err(crate::jsonrpc::Error::method_not_found())
690 }
691
692 #[rpc(name = "callHierarchy/outgoingCalls")]
694 async fn outgoing_calls(
695 &self,
696 _params: lsp::CallHierarchyOutgoingCallsParams,
697 ) -> crate::jsonrpc::Result<Option<Vec<lsp::CallHierarchyOutgoingCall>>> {
698 log::error!("Got a callHierarchy/outgoingCalls request, but it is not implemented");
699 Err(crate::jsonrpc::Error::method_not_found())
700 }
701
702 #[rpc(name = "textDocument/prepareCallHierarchy")]
704 async fn prepare_call_hierarchy(
705 &self,
706 _params: lsp::CallHierarchyPrepareParams,
707 ) -> crate::jsonrpc::Result<Option<Vec<lsp::CallHierarchyItem>>> {
708 log::error!("Got a textDocument/prepareCallHierarchy request, but it is not implemented");
709 Err(crate::jsonrpc::Error::method_not_found())
710 }
711
712 #[rpc(name = "textDocument/semanticTokens/full")]
714 async fn semantic_tokens_full(
715 &self,
716 _params: lsp::SemanticTokensParams,
717 ) -> crate::jsonrpc::Result<Option<lsp::SemanticTokensResult>> {
718 log::error!("Got a textDocument/semanticTokens/full request, but it is not implemented");
719 Err(crate::jsonrpc::Error::method_not_found())
720 }
721
722 #[rpc(name = "textDocument/semanticTokens/full/delta")]
724 async fn semantic_tokens_full_delta(
725 &self,
726 _params: lsp::SemanticTokensDeltaParams,
727 ) -> crate::jsonrpc::Result<Option<lsp::SemanticTokensFullDeltaResult>> {
728 log::error!("Got a textDocument/semanticTokens/full/delta request, but it is not implemented");
729 Err(crate::jsonrpc::Error::method_not_found())
730 }
731
732 #[rpc(name = "textDocument/semanticTokens/range")]
734 async fn semantic_tokens_range(
735 &self,
736 _params: lsp::SemanticTokensRangeParams,
737 ) -> crate::jsonrpc::Result<Option<lsp::SemanticTokensRangeResult>> {
738 log::error!("Got a textDocument/semanticTokens/range request, but it is not implemented");
739 Err(crate::jsonrpc::Error::method_not_found())
740 }
741
742 #[rpc(name = "workspace/semanticTokens/refresh")]
744 async fn semantic_tokens_refresh(&self) -> crate::jsonrpc::Result<()> {
745 log::error!("Got a workspace/semanticTokens/refresh request, but it is not implemented");
746 Err(crate::jsonrpc::Error::method_not_found())
747 }
748
749 #[rpc(name = "codeAction/resolve")]
751 async fn code_action_resolve(&self, _params: lsp::CodeAction) -> crate::jsonrpc::Result<lsp::CodeAction> {
752 log::error!("Got a codeAction/resolve request, but it is not implemented");
753 Err(crate::jsonrpc::Error::method_not_found())
754 }
755
756 async fn request_else(
759 &self,
760 method: &str,
761 _params: Option<serde_json::Value>,
762 ) -> crate::jsonrpc::Result<Option<serde_json::Value>> {
763 log::error!(
764 "Got a {} request, but LanguageServer::request_else is not implemented",
765 method
766 );
767 Err(crate::jsonrpc::Error::method_not_found())
768 }
769}
770
771#[cfg(test)]
772mod tests {
773 use super::*;
774 use crate::jsonrpc::{Id, Incoming, Outgoing, Response};
775 use serde_json::json;
776 use std::task::Poll;
777 use tower_test::mock::Spawn;
778
779 #[derive(Debug, Default)]
780 struct Mock;
781
782 #[async_trait]
783 impl crate::LanguageServer for Mock {
784 async fn initialize(&self, _: lsp::InitializeParams) -> crate::jsonrpc::Result<lsp::InitializeResult> {
785 Ok(lsp::InitializeResult::default())
786 }
787
788 async fn shutdown(&self) -> crate::jsonrpc::Result<()> {
789 Ok(())
790 }
791 }
792
793 mod helper {
794 use super::*;
795 use crate::jsonrpc::Incoming;
796 use serde::{de::DeserializeOwned, Serialize};
797 use serde_json::json;
798 use std::task::Poll;
799 use tower_test::mock::Spawn;
800
801 pub(super) async fn initialize(service: &mut Spawn<LspService>) {
802 let params = serde_json::from_value::<lsp::InitializeParams>(json!({ "capabilities": {} })).unwrap();
803 let request: Incoming = request("initialize", params).unwrap();
804 let response =
805 serde_json::from_value(json!({ "jsonrpc": "2.0", "result": { "capabilities": {} }, "id": 1 })).unwrap();
806 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
807 assert_eq!(service.call(request.clone()).await, Ok(Some(response)));
808 }
809
810 pub(super) fn request<I: Serialize, O: DeserializeOwned>(
811 method: &str,
812 params: I,
813 ) -> Result<O, serde_json::Error> {
814 serde_json::from_value(json!({
815 "jsonrpc": "2.0",
816 "method": method,
817 "params": params,
818 "id": 1,
819 }))
820 }
821 }
822
823 #[tokio::test]
824 async fn initialize() {
825 let (service, _) = LspService::new(|_| Mock::default());
826 let mut service = Spawn::new(service);
827
828 helper::initialize(&mut service).await;
829 }
830
831 #[tokio::test]
832 async fn initialized() {
833 let (service, _) = LspService::new(|_| Mock::default());
834 let mut service = Spawn::new(service);
835
836 helper::initialize(&mut service).await;
837
838 let params = lsp::InitializedParams {};
839 let request: Incoming = helper::request("initialized", params).unwrap();
840 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
841 assert_eq!(service.call(request.clone()).await, Ok(None));
842 }
843
844 #[tokio::test]
845 async fn shutdown() {
846 let (service, _) = LspService::new(|_| Mock::default());
847 let mut service = Spawn::new(service);
848
849 helper::initialize(&mut service).await;
850
851 let request: Incoming = helper::request("shutdown", ()).unwrap();
852 let response = Response::ok(Id::Number(1), json!(null));
853 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
854 assert_eq!(
855 service.call(request.clone()).await,
856 Ok(Some(Outgoing::Response(response)))
857 );
858 }
859
860 mod call_hierarchy {
861 use super::*;
862 use crate::jsonrpc::{Error, Id, Incoming, Outgoing, Response};
863 use std::task::Poll;
864 use tower_test::mock::Spawn;
865
866 #[tokio::test]
867 async fn incoming_calls() {
868 let (service, _) = LspService::new(|_| Mock::default());
869 let mut service = Spawn::new(service);
870
871 super::helper::initialize(&mut service).await;
872
873 let params = lsp::CallHierarchyIncomingCallsParams {
874 item: lsp::CallHierarchyItem {
875 name: Default::default(),
876 kind: lsp::SymbolKind::NULL,
877 tags: Default::default(),
878 detail: Default::default(),
879 uri: lsp::Url::parse("inmemory::///test").unwrap(),
880 range: Default::default(),
881 selection_range: Default::default(),
882 data: Default::default(),
883 },
884 work_done_progress_params: Default::default(),
885 partial_result_params: Default::default(),
886 };
887 let request: Incoming = helper::request("callHierarchy/incomingCalls", params).unwrap();
888 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
889 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
890 assert_eq!(
891 service.call(request.clone()).await,
892 Ok(Some(Outgoing::Response(response)))
893 );
894 }
895
896 #[tokio::test]
897 async fn outgoing_calls() {
898 let (service, _) = LspService::new(|_| Mock::default());
899 let mut service = Spawn::new(service);
900
901 super::helper::initialize(&mut service).await;
902
903 let params = lsp::CallHierarchyOutgoingCallsParams {
904 item: lsp::CallHierarchyItem {
905 name: Default::default(),
906 kind: lsp::SymbolKind::NULL,
907 tags: Default::default(),
908 detail: Default::default(),
909 uri: lsp::Url::parse("inmemory::///test").unwrap(),
910 range: Default::default(),
911 selection_range: Default::default(),
912 data: Default::default(),
913 },
914 work_done_progress_params: Default::default(),
915 partial_result_params: Default::default(),
916 };
917 let request: Incoming = helper::request("callHierarchy/outgoingCalls", params).unwrap();
918 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
919 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
920 assert_eq!(
921 service.call(request.clone()).await,
922 Ok(Some(Outgoing::Response(response)))
923 );
924 }
925 }
926
927 mod code_action {
928 use super::*;
929 use crate::jsonrpc::{Error, Id, Incoming, Outgoing, Response};
930 use std::task::Poll;
931 use tower_test::mock::Spawn;
932
933 #[tokio::test]
934 async fn resolve() {
935 let (service, _) = LspService::new(|_| Mock::default());
936 let mut service = Spawn::new(service);
937
938 super::helper::initialize(&mut service).await;
939
940 let params = lsp::CodeAction::default();
941 let request: Incoming = helper::request("codeAction/resolve", params).unwrap();
942 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
943 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
944 assert_eq!(
945 service.call(request.clone()).await,
946 Ok(Some(Outgoing::Response(response)))
947 );
948 }
949 }
950
951 mod completion_item {
952 use super::*;
953 use crate::jsonrpc::{Error, Id, Incoming, Outgoing, Response};
954 use std::task::Poll;
955 use tower_test::mock::Spawn;
956
957 #[tokio::test]
958 async fn resolve() {
959 let (service, _) = LspService::new(|_| Mock::default());
960 let mut service = Spawn::new(service);
961
962 super::helper::initialize(&mut service).await;
963
964 let params = lsp::CompletionItem::default();
965 let request: Incoming = helper::request("completionItem/resolve", params).unwrap();
966 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
967 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
968 assert_eq!(
969 service.call(request.clone()).await,
970 Ok(Some(Outgoing::Response(response)))
971 );
972 }
973 }
974
975 mod text_document {
976 use super::*;
977 use crate::jsonrpc::{Error, Id, Incoming, Outgoing, Response};
978 use std::task::Poll;
979 use tower_test::mock::Spawn;
980
981 mod semantic_tokens {
982 use super::*;
983 use crate::jsonrpc::{Error, Id, Incoming, Outgoing, Response};
984 use std::task::Poll;
985 use tower_test::mock::Spawn;
986
987 mod full {
988 use super::*;
989 use crate::jsonrpc::{Error, Id, Incoming, Outgoing, Response};
990 use std::task::Poll;
991 use tower_test::mock::Spawn;
992
993 #[tokio::test]
994 async fn delta() {
995 let (service, _) = LspService::new(|_| Mock::default());
996 let mut service = Spawn::new(service);
997
998 super::helper::initialize(&mut service).await;
999
1000 let params = lsp::SemanticTokensDeltaParams {
1001 work_done_progress_params: Default::default(),
1002 partial_result_params: Default::default(),
1003 text_document: lsp::TextDocumentIdentifier {
1004 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1005 },
1006 previous_result_id: Default::default(),
1007 };
1008 let request: Incoming = helper::request("textDocument/semanticTokens/full", params).unwrap();
1009 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1010 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1011 assert_eq!(
1012 service.call(request.clone()).await,
1013 Ok(Some(Outgoing::Response(response)))
1014 );
1015 }
1016 }
1017
1018 #[tokio::test]
1019 async fn full() {
1020 let (service, _) = LspService::new(|_| Mock::default());
1021 let mut service = Spawn::new(service);
1022
1023 super::helper::initialize(&mut service).await;
1024
1025 let params = lsp::SemanticTokensParams {
1026 work_done_progress_params: Default::default(),
1027 partial_result_params: Default::default(),
1028 text_document: lsp::TextDocumentIdentifier {
1029 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1030 },
1031 };
1032 let request: Incoming = helper::request("textDocument/semanticTokens/full", params).unwrap();
1033 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1034 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1035 assert_eq!(
1036 service.call(request.clone()).await,
1037 Ok(Some(Outgoing::Response(response)))
1038 );
1039 }
1040
1041 #[tokio::test]
1042 async fn range() {
1043 let (service, _) = LspService::new(|_| Mock::default());
1044 let mut service = Spawn::new(service);
1045
1046 super::helper::initialize(&mut service).await;
1047
1048 let params = lsp::SemanticTokensRangeParams {
1049 work_done_progress_params: Default::default(),
1050 partial_result_params: Default::default(),
1051 text_document: lsp::TextDocumentIdentifier {
1052 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1053 },
1054 range: Default::default(),
1055 };
1056 let request: Incoming = helper::request("textDocument/semanticTokens/range", params).unwrap();
1057 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1058 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1059 assert_eq!(
1060 service.call(request.clone()).await,
1061 Ok(Some(Outgoing::Response(response)))
1062 );
1063 }
1064
1065 #[tokio::test]
1066 async fn refresh() {
1067 let (service, _) = LspService::new(|_| Mock::default());
1068 let mut service = Spawn::new(service);
1069
1070 super::helper::initialize(&mut service).await;
1071
1072 let request: Incoming = helper::request("textDocument/semanticTokens/refresh", ()).unwrap();
1073 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1074 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1075 assert_eq!(
1076 service.call(request.clone()).await,
1077 Ok(Some(Outgoing::Response(response)))
1078 );
1079 }
1080 }
1081
1082 #[tokio::test]
1083 async fn code_action() {
1084 let (service, _) = LspService::new(|_| Mock::default());
1085 let mut service = Spawn::new(service);
1086
1087 super::helper::initialize(&mut service).await;
1088
1089 let params = lsp::CodeActionParams {
1090 text_document: lsp::TextDocumentIdentifier {
1091 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1092 },
1093 range: Default::default(),
1094 context: Default::default(),
1095 work_done_progress_params: Default::default(),
1096 partial_result_params: Default::default(),
1097 };
1098 let request: Incoming = helper::request("textDocument/codeAction", params).unwrap();
1099 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1100 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1101 assert_eq!(
1102 service.call(request.clone()).await,
1103 Ok(Some(Outgoing::Response(response)))
1104 );
1105 }
1106
1107 #[tokio::test]
1108 async fn code_lens() {
1109 let (service, _) = LspService::new(|_| Mock::default());
1110 let mut service = Spawn::new(service);
1111
1112 super::helper::initialize(&mut service).await;
1113
1114 let params = lsp::CodeLensParams {
1115 text_document: lsp::TextDocumentIdentifier {
1116 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1117 },
1118 work_done_progress_params: Default::default(),
1119 partial_result_params: Default::default(),
1120 };
1121 let request: Incoming = helper::request("textDocument/codeLens", params).unwrap();
1122 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1123 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1124 assert_eq!(
1125 service.call(request.clone()).await,
1126 Ok(Some(Outgoing::Response(response)))
1127 );
1128 }
1129
1130 #[tokio::test]
1131 async fn code_lens_resolve() {
1132 let (service, _) = LspService::new(|_| Mock::default());
1133 let mut service = Spawn::new(service);
1134
1135 super::helper::initialize(&mut service).await;
1136
1137 let params = lsp::CodeLens {
1138 range: Default::default(),
1139 command: Default::default(),
1140 data: Default::default(),
1141 };
1142 let request: Incoming = helper::request("textDocument/codeLensResolve", params).unwrap();
1143 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1144 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1145 assert_eq!(
1146 service.call(request.clone()).await,
1147 Ok(Some(Outgoing::Response(response)))
1148 );
1149 }
1150
1151 #[tokio::test]
1152 async fn color_presentation() {
1153 let (service, _) = LspService::new(|_| Mock::default());
1154 let mut service = Spawn::new(service);
1155
1156 super::helper::initialize(&mut service).await;
1157
1158 let params = lsp::ColorPresentationParams {
1159 text_document: lsp::TextDocumentIdentifier {
1160 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1161 },
1162 color: lsp::Color {
1163 red: Default::default(),
1164 green: Default::default(),
1165 blue: Default::default(),
1166 alpha: Default::default(),
1167 },
1168 range: Default::default(),
1169 work_done_progress_params: Default::default(),
1170 partial_result_params: Default::default(),
1171 };
1172 let request: Incoming = helper::request("textDocument/colorPresentation", params).unwrap();
1173 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1174 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1175 assert_eq!(
1176 service.call(request.clone()).await,
1177 Ok(Some(Outgoing::Response(response)))
1178 );
1179 }
1180
1181 #[tokio::test]
1182 async fn completion() {
1183 let (service, _) = LspService::new(|_| Mock::default());
1184 let mut service = Spawn::new(service);
1185
1186 super::helper::initialize(&mut service).await;
1187
1188 let params = lsp::CompletionParams {
1189 text_document_position: lsp::TextDocumentPositionParams {
1190 text_document: lsp::TextDocumentIdentifier {
1191 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1192 },
1193 position: Default::default(),
1194 },
1195 work_done_progress_params: Default::default(),
1196 partial_result_params: Default::default(),
1197 context: Default::default(),
1198 };
1199 let request: Incoming = helper::request("textDocument/completion", params).unwrap();
1200 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1201 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1202 assert_eq!(
1203 service.call(request.clone()).await,
1204 Ok(Some(Outgoing::Response(response)))
1205 );
1206 }
1207
1208 #[tokio::test]
1209 async fn declaration() {
1210 let (service, _) = LspService::new(|_| Mock::default());
1211 let mut service = Spawn::new(service);
1212
1213 super::helper::initialize(&mut service).await;
1214
1215 let params = lsp::request::GotoDeclarationParams {
1216 text_document_position_params: lsp::TextDocumentPositionParams {
1217 text_document: lsp::TextDocumentIdentifier {
1218 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1219 },
1220 position: Default::default(),
1221 },
1222 work_done_progress_params: Default::default(),
1223 partial_result_params: Default::default(),
1224 };
1225 let request: Incoming = helper::request("textDocument/declaration", params).unwrap();
1226 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1227 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1228 assert_eq!(
1229 service.call(request.clone()).await,
1230 Ok(Some(Outgoing::Response(response)))
1231 );
1232 }
1233
1234 #[tokio::test]
1235 async fn definition() {
1236 let (service, _) = LspService::new(|_| Mock::default());
1237 let mut service = Spawn::new(service);
1238
1239 super::helper::initialize(&mut service).await;
1240
1241 let params = lsp::GotoDefinitionParams {
1242 text_document_position_params: lsp::TextDocumentPositionParams {
1243 text_document: lsp::TextDocumentIdentifier {
1244 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1245 },
1246 position: Default::default(),
1247 },
1248 work_done_progress_params: Default::default(),
1249 partial_result_params: Default::default(),
1250 };
1251 let request: Incoming = helper::request("textDocument/definition", params).unwrap();
1252 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1253 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1254 assert_eq!(
1255 service.call(request.clone()).await,
1256 Ok(Some(Outgoing::Response(response)))
1257 );
1258 }
1259
1260 #[tokio::test]
1261 async fn did_change() {
1262 let (service, _) = LspService::new(|_| Mock::default());
1263 let mut service = Spawn::new(service);
1264
1265 super::helper::initialize(&mut service).await;
1266
1267 let params = lsp::DidChangeTextDocumentParams {
1268 text_document: lsp::VersionedTextDocumentIdentifier {
1269 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1270 version: Default::default(),
1271 },
1272 content_changes: Default::default(),
1273 };
1274 let request: Incoming = helper::request("textDocument/didChange", params).unwrap();
1275 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1276 assert_eq!(service.call(request.clone()).await, Ok(None));
1277 }
1278
1279 #[tokio::test]
1280 async fn did_close() {
1281 let (service, _) = LspService::new(|_| Mock::default());
1282 let mut service = Spawn::new(service);
1283
1284 super::helper::initialize(&mut service).await;
1285
1286 let params = lsp::DidCloseTextDocumentParams {
1287 text_document: lsp::TextDocumentIdentifier {
1288 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1289 },
1290 };
1291 let request: Incoming = helper::request("textDocument/didClose", params).unwrap();
1292 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1293 assert_eq!(service.call(request.clone()).await, Ok(None));
1294 }
1295
1296 #[tokio::test]
1297 async fn did_open() {
1298 let (service, _) = LspService::new(|_| Mock::default());
1299 let mut service = Spawn::new(service);
1300
1301 super::helper::initialize(&mut service).await;
1302
1303 let params = lsp::DidOpenTextDocumentParams {
1304 text_document: lsp::TextDocumentItem {
1305 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1306 language_id: Default::default(),
1307 version: Default::default(),
1308 text: Default::default(),
1309 },
1310 };
1311 let request: Incoming = helper::request("textDocument/didOpen", params).unwrap();
1312 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1313 assert_eq!(service.call(request.clone()).await, Ok(None));
1314 }
1315
1316 #[tokio::test]
1317 async fn did_save() {
1318 let (service, _) = LspService::new(|_| Mock::default());
1319 let mut service = Spawn::new(service);
1320
1321 super::helper::initialize(&mut service).await;
1322
1323 let params = lsp::DidSaveTextDocumentParams {
1324 text_document: lsp::TextDocumentIdentifier {
1325 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1326 },
1327 text: Default::default(),
1328 };
1329 let request: Incoming = helper::request("textDocument/didSave", params).unwrap();
1330 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1331 assert_eq!(service.call(request.clone()).await, Ok(None));
1332 }
1333
1334 #[tokio::test]
1335 async fn document_color() {
1336 let (service, _) = LspService::new(|_| Mock::default());
1337 let mut service = Spawn::new(service);
1338
1339 super::helper::initialize(&mut service).await;
1340
1341 let params = lsp::DocumentColorParams {
1342 text_document: lsp::TextDocumentIdentifier {
1343 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1344 },
1345 work_done_progress_params: Default::default(),
1346 partial_result_params: Default::default(),
1347 };
1348 let request: Incoming = helper::request("textDocument/documentColor", params).unwrap();
1349 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1350 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1351 assert_eq!(
1352 service.call(request.clone()).await,
1353 Ok(Some(Outgoing::Response(response)))
1354 );
1355 }
1356
1357 #[tokio::test]
1358 async fn document_highlight() {
1359 let (service, _) = LspService::new(|_| Mock::default());
1360 let mut service = Spawn::new(service);
1361
1362 super::helper::initialize(&mut service).await;
1363
1364 let params = lsp::DocumentHighlightParams {
1365 text_document_position_params: lsp::TextDocumentPositionParams {
1366 text_document: lsp::TextDocumentIdentifier {
1367 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1368 },
1369 position: Default::default(),
1370 },
1371 work_done_progress_params: Default::default(),
1372 partial_result_params: Default::default(),
1373 };
1374 let request: Incoming = helper::request("textDocument/documentHighlight", params).unwrap();
1375 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1376 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1377 assert_eq!(
1378 service.call(request.clone()).await,
1379 Ok(Some(Outgoing::Response(response)))
1380 );
1381 }
1382
1383 #[tokio::test]
1384 async fn document_link() {
1385 let (service, _) = LspService::new(|_| Mock::default());
1386 let mut service = Spawn::new(service);
1387
1388 super::helper::initialize(&mut service).await;
1389
1390 let params = lsp::DocumentLinkParams {
1391 text_document: lsp::TextDocumentIdentifier {
1392 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1393 },
1394 work_done_progress_params: Default::default(),
1395 partial_result_params: Default::default(),
1396 };
1397 let request: Incoming = helper::request("textDocument/documentLink", params).unwrap();
1398 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1399 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1400 assert_eq!(
1401 service.call(request.clone()).await,
1402 Ok(Some(Outgoing::Response(response)))
1403 );
1404 }
1405
1406 #[tokio::test]
1407 async fn document_link_resolve() {
1408 let (service, _) = LspService::new(|_| Mock::default());
1409 let mut service = Spawn::new(service);
1410
1411 super::helper::initialize(&mut service).await;
1412
1413 let params = lsp::DocumentLink {
1414 range: Default::default(),
1415 target: Default::default(),
1416 tooltip: Default::default(),
1417 data: Default::default(),
1418 };
1419 let request: Incoming = helper::request("textDocument/documentLinkResolve", params).unwrap();
1420 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1421 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1422 assert_eq!(
1423 service.call(request.clone()).await,
1424 Ok(Some(Outgoing::Response(response)))
1425 );
1426 }
1427
1428 #[tokio::test]
1429 async fn document_symbol() {
1430 let (service, _) = LspService::new(|_| Mock::default());
1431 let mut service = Spawn::new(service);
1432
1433 super::helper::initialize(&mut service).await;
1434
1435 let params = lsp::DocumentSymbolParams {
1436 text_document: lsp::TextDocumentIdentifier {
1437 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1438 },
1439 work_done_progress_params: Default::default(),
1440 partial_result_params: Default::default(),
1441 };
1442 let request: Incoming = helper::request("textDocument/documentSymbol", params).unwrap();
1443 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1444 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1445 assert_eq!(
1446 service.call(request.clone()).await,
1447 Ok(Some(Outgoing::Response(response)))
1448 );
1449 }
1450
1451 #[tokio::test]
1452 async fn folding_range() {
1453 let (service, _) = LspService::new(|_| Mock::default());
1454 let mut service = Spawn::new(service);
1455
1456 super::helper::initialize(&mut service).await;
1457
1458 let params = lsp::FoldingRangeParams {
1459 text_document: lsp::TextDocumentIdentifier {
1460 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1461 },
1462 work_done_progress_params: Default::default(),
1463 partial_result_params: Default::default(),
1464 };
1465 let request: Incoming = helper::request("textDocument/foldingRange", params).unwrap();
1466 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1467 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1468 assert_eq!(
1469 service.call(request.clone()).await,
1470 Ok(Some(Outgoing::Response(response)))
1471 );
1472 }
1473
1474 #[tokio::test]
1475 async fn formatting() {
1476 let (service, _) = LspService::new(|_| Mock::default());
1477 let mut service = Spawn::new(service);
1478
1479 super::helper::initialize(&mut service).await;
1480
1481 let params = lsp::DocumentFormattingParams {
1482 text_document: lsp::TextDocumentIdentifier {
1483 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1484 },
1485 options: Default::default(),
1486 work_done_progress_params: Default::default(),
1487 };
1488 let request: Incoming = helper::request("textDocument/formatting", params).unwrap();
1489 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1490 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1491 assert_eq!(
1492 service.call(request.clone()).await,
1493 Ok(Some(Outgoing::Response(response)))
1494 );
1495 }
1496
1497 #[tokio::test]
1498 async fn hover() {
1499 let (service, _) = LspService::new(|_| Mock::default());
1500 let mut service = Spawn::new(service);
1501
1502 super::helper::initialize(&mut service).await;
1503
1504 let params = lsp::HoverParams {
1505 text_document_position_params: lsp::TextDocumentPositionParams {
1506 text_document: lsp::TextDocumentIdentifier {
1507 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1508 },
1509 position: Default::default(),
1510 },
1511 work_done_progress_params: Default::default(),
1512 };
1513 let request: Incoming = helper::request("textDocument/hover", params).unwrap();
1514 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1515 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1516 assert_eq!(
1517 service.call(request.clone()).await,
1518 Ok(Some(Outgoing::Response(response)))
1519 );
1520 }
1521
1522 #[tokio::test]
1523 async fn implementation() {
1524 let (service, _) = LspService::new(|_| Mock::default());
1525 let mut service = Spawn::new(service);
1526
1527 super::helper::initialize(&mut service).await;
1528
1529 let params = lsp::request::GotoImplementationParams {
1530 text_document_position_params: lsp::TextDocumentPositionParams {
1531 text_document: lsp::TextDocumentIdentifier {
1532 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1533 },
1534 position: Default::default(),
1535 },
1536 work_done_progress_params: Default::default(),
1537 partial_result_params: Default::default(),
1538 };
1539 let request: Incoming = helper::request("textDocument/implementation", params).unwrap();
1540 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1541 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1542 assert_eq!(
1543 service.call(request.clone()).await,
1544 Ok(Some(Outgoing::Response(response)))
1545 );
1546 }
1547
1548 #[tokio::test]
1549 async fn on_type_formatting() {
1550 let (service, _) = LspService::new(|_| Mock::default());
1551 let mut service = Spawn::new(service);
1552
1553 super::helper::initialize(&mut service).await;
1554
1555 let params = lsp::DocumentOnTypeFormattingParams {
1556 text_document_position: lsp::TextDocumentPositionParams {
1557 text_document: lsp::TextDocumentIdentifier {
1558 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1559 },
1560 position: Default::default(),
1561 },
1562 ch: Default::default(),
1563 options: Default::default(),
1564 };
1565 let request: Incoming = helper::request("textDocument/onTypeFormatting", params).unwrap();
1566 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1567 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1568 assert_eq!(
1569 service.call(request.clone()).await,
1570 Ok(Some(Outgoing::Response(response)))
1571 );
1572 }
1573
1574 #[tokio::test]
1575 async fn prepare_call_hierarchy() {
1576 let (service, _) = LspService::new(|_| Mock::default());
1577 let mut service = Spawn::new(service);
1578
1579 super::helper::initialize(&mut service).await;
1580
1581 let params = lsp::CallHierarchyPrepareParams {
1582 text_document_position_params: lsp::TextDocumentPositionParams {
1583 text_document: lsp::TextDocumentIdentifier {
1584 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1585 },
1586 position: Default::default(),
1587 },
1588 work_done_progress_params: Default::default(),
1589 };
1590 let request: Incoming = helper::request("textDocument/prepareCallHierarchy", params).unwrap();
1591 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1592 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1593 assert_eq!(
1594 service.call(request.clone()).await,
1595 Ok(Some(Outgoing::Response(response)))
1596 );
1597 }
1598
1599 #[tokio::test]
1600 async fn prepare_rename() {
1601 let (service, _) = LspService::new(|_| Mock::default());
1602 let mut service = Spawn::new(service);
1603
1604 super::helper::initialize(&mut service).await;
1605
1606 let params = lsp::TextDocumentPositionParams {
1607 text_document: lsp::TextDocumentIdentifier {
1608 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1609 },
1610 position: Default::default(),
1611 };
1612 let request: Incoming = helper::request("textDocument/prepareRename", params).unwrap();
1613 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1614 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1615 assert_eq!(
1616 service.call(request.clone()).await,
1617 Ok(Some(Outgoing::Response(response)))
1618 );
1619 }
1620
1621 #[tokio::test]
1622 async fn range_formatting() {
1623 let (service, _) = LspService::new(|_| Mock::default());
1624 let mut service = Spawn::new(service);
1625
1626 super::helper::initialize(&mut service).await;
1627
1628 let params = lsp::DocumentRangeFormattingParams {
1629 text_document: lsp::TextDocumentIdentifier {
1630 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1631 },
1632 range: Default::default(),
1633 options: Default::default(),
1634 work_done_progress_params: Default::default(),
1635 };
1636 let request: Incoming = helper::request("textDocument/rangeFormatting", params).unwrap();
1637 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1638 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1639 assert_eq!(
1640 service.call(request.clone()).await,
1641 Ok(Some(Outgoing::Response(response)))
1642 );
1643 }
1644
1645 #[tokio::test]
1646 async fn references() {
1647 let (service, _) = LspService::new(|_| Mock::default());
1648 let mut service = Spawn::new(service);
1649
1650 super::helper::initialize(&mut service).await;
1651
1652 let params = lsp::ReferenceParams {
1653 text_document_position: lsp::TextDocumentPositionParams {
1654 text_document: lsp::TextDocumentIdentifier {
1655 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1656 },
1657 position: Default::default(),
1658 },
1659 work_done_progress_params: Default::default(),
1660 partial_result_params: Default::default(),
1661 context: lsp::ReferenceContext {
1662 include_declaration: Default::default(),
1663 },
1664 };
1665 let request: Incoming = helper::request("textDocument/references", params).unwrap();
1666 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1667 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1668 assert_eq!(
1669 service.call(request.clone()).await,
1670 Ok(Some(Outgoing::Response(response)))
1671 );
1672 }
1673
1674 #[tokio::test]
1675 async fn rename() {
1676 let (service, _) = LspService::new(|_| Mock::default());
1677 let mut service = Spawn::new(service);
1678
1679 super::helper::initialize(&mut service).await;
1680
1681 let params = lsp::RenameParams {
1682 text_document_position: lsp::TextDocumentPositionParams {
1683 text_document: lsp::TextDocumentIdentifier {
1684 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1685 },
1686 position: Default::default(),
1687 },
1688 new_name: Default::default(),
1689 work_done_progress_params: Default::default(),
1690 };
1691 let request: Incoming = helper::request("textDocument/rename", params).unwrap();
1692 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1693 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1694 assert_eq!(
1695 service.call(request.clone()).await,
1696 Ok(Some(Outgoing::Response(response)))
1697 );
1698 }
1699
1700 #[tokio::test]
1701 async fn request_else() {
1702 let (service, _) = LspService::new(|_| Mock::default());
1703 let mut service = Spawn::new(service);
1704
1705 super::helper::initialize(&mut service).await;
1706
1707 let params = None::<serde_json::Value>;
1708 let request: Incoming = helper::request("foo/bar", params).unwrap();
1709 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1710 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1711 assert_eq!(
1712 service.call(request.clone()).await,
1713 Ok(Some(Outgoing::Response(response)))
1714 );
1715 }
1716
1717 #[tokio::test]
1718 async fn selection_range() {
1719 let (service, _) = LspService::new(|_| Mock::default());
1720 let mut service = Spawn::new(service);
1721
1722 super::helper::initialize(&mut service).await;
1723
1724 let params = lsp::SelectionRangeParams {
1725 text_document: lsp::TextDocumentIdentifier {
1726 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1727 },
1728 positions: Default::default(),
1729 work_done_progress_params: Default::default(),
1730 partial_result_params: Default::default(),
1731 };
1732 let request: Incoming = helper::request("textDocument/selectionRange", params).unwrap();
1733 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1734 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1735 assert_eq!(
1736 service.call(request.clone()).await,
1737 Ok(Some(Outgoing::Response(response)))
1738 );
1739 }
1740
1741 #[tokio::test]
1742 async fn signature_help() {
1743 let (service, _) = LspService::new(|_| Mock::default());
1744 let mut service = Spawn::new(service);
1745
1746 super::helper::initialize(&mut service).await;
1747
1748 let params = lsp::SignatureHelpParams {
1749 context: Default::default(),
1750 text_document_position_params: lsp::TextDocumentPositionParams {
1751 text_document: lsp::TextDocumentIdentifier {
1752 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1753 },
1754 position: Default::default(),
1755 },
1756 work_done_progress_params: Default::default(),
1757 };
1758 let request: Incoming = helper::request("textDocument/signatureHelp", params).unwrap();
1759 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1760 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1761 assert_eq!(
1762 service.call(request.clone()).await,
1763 Ok(Some(Outgoing::Response(response)))
1764 );
1765 }
1766
1767 #[tokio::test]
1768 async fn type_definition() {
1769 let (service, _) = LspService::new(|_| Mock::default());
1770 let mut service = Spawn::new(service);
1771
1772 super::helper::initialize(&mut service).await;
1773
1774 let params = lsp::request::GotoTypeDefinitionParams {
1775 text_document_position_params: lsp::TextDocumentPositionParams {
1776 text_document: lsp::TextDocumentIdentifier {
1777 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1778 },
1779 position: Default::default(),
1780 },
1781 work_done_progress_params: Default::default(),
1782 partial_result_params: Default::default(),
1783 };
1784 let request: Incoming = helper::request("textDocument/typeDefinition", params).unwrap();
1785 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1786 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1787 assert_eq!(
1788 service.call(request.clone()).await,
1789 Ok(Some(Outgoing::Response(response)))
1790 );
1791 }
1792
1793 #[tokio::test]
1794 async fn will_save() {
1795 let (service, _) = LspService::new(|_| Mock::default());
1796 let mut service = Spawn::new(service);
1797
1798 super::helper::initialize(&mut service).await;
1799
1800 let params = lsp::WillSaveTextDocumentParams {
1801 text_document: lsp::TextDocumentIdentifier {
1802 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1803 },
1804 reason: lsp::TextDocumentSaveReason::MANUAL,
1805 };
1806 let request: Incoming = helper::request("textDocument/willSave", params).unwrap();
1807 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1808 assert_eq!(service.call(request.clone()).await, Ok(None));
1809 }
1810
1811 #[tokio::test]
1812 async fn will_save_wait_until() {
1813 let (service, _) = LspService::new(|_| Mock::default());
1814 let mut service = Spawn::new(service);
1815
1816 super::helper::initialize(&mut service).await;
1817
1818 let params = lsp::WillSaveTextDocumentParams {
1819 text_document: lsp::TextDocumentIdentifier {
1820 uri: lsp::Url::parse("inmemory::///test").unwrap(),
1821 },
1822 reason: lsp::TextDocumentSaveReason::MANUAL,
1823 };
1824 let request: Incoming = helper::request("textDocument/willSaveWaitUntil", params).unwrap();
1825 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1826 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1827 assert_eq!(
1828 service.call(request.clone()).await,
1829 Ok(Some(Outgoing::Response(response)))
1830 );
1831 }
1832 }
1833
1834 mod workspace {
1835 use super::*;
1836 use crate::jsonrpc::{Error, Id, Incoming, Outgoing, Response};
1837 use serde_json::Value;
1838 use std::task::Poll;
1839 use tower_test::mock::Spawn;
1840
1841 #[tokio::test]
1842 async fn did_change_configuration() {
1843 let (service, _) = LspService::new(|_| Mock::default());
1844 let mut service = Spawn::new(service);
1845
1846 super::helper::initialize(&mut service).await;
1847
1848 let params = lsp::DidChangeConfigurationParams { settings: Value::Null };
1849 let request: Incoming = helper::request("workspace/didChangeConfiguration", params).unwrap();
1850 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1851 assert_eq!(service.call(request.clone()).await, Ok(None));
1852 }
1853
1854 #[tokio::test]
1855 async fn did_change_watched_files() {
1856 let (service, _) = LspService::new(|_| Mock::default());
1857 let mut service = Spawn::new(service);
1858
1859 super::helper::initialize(&mut service).await;
1860
1861 let params = lsp::DidChangeWatchedFilesParams {
1862 changes: Default::default(),
1863 };
1864 let request: Incoming = helper::request("workspace/didChangeWatchedFiles", params).unwrap();
1865 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1866 assert_eq!(service.call(request.clone()).await, Ok(None));
1867 }
1868
1869 #[tokio::test]
1870 async fn did_change_workspace_folders() {
1871 let (service, _) = LspService::new(|_| Mock::default());
1872 let mut service = Spawn::new(service);
1873
1874 super::helper::initialize(&mut service).await;
1875
1876 let params = lsp::DidChangeWorkspaceFoldersParams::default();
1877 let request: Incoming = helper::request("workspace/didChangeWorkspaceFolders", params).unwrap();
1878 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1879 assert_eq!(service.call(request.clone()).await, Ok(None));
1880 }
1881
1882 #[tokio::test]
1883 async fn execute_command() {
1884 let (service, _) = LspService::new(|_| Mock::default());
1885 let mut service = Spawn::new(service);
1886
1887 super::helper::initialize(&mut service).await;
1888
1889 let params = lsp::ExecuteCommandParams::default();
1890 let request: Incoming = helper::request("workspace/executeCommand", params).unwrap();
1891 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1892 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1893 assert_eq!(
1894 service.call(request.clone()).await,
1895 Ok(Some(Outgoing::Response(response)))
1896 );
1897 }
1898
1899 #[tokio::test]
1900 async fn symbol() {
1901 let (service, _) = LspService::new(|_| Mock::default());
1902 let mut service = Spawn::new(service);
1903
1904 super::helper::initialize(&mut service).await;
1905
1906 let params = lsp::WorkspaceSymbolParams::default();
1907 let request: Incoming = helper::request("workspace/symbol", params).unwrap();
1908 let response = Response::error(Some(Id::Number(1)), Error::method_not_found());
1909 assert_eq!(service.poll_ready(), Poll::Ready(Ok(())));
1910 assert_eq!(
1911 service.call(request.clone()).await,
1912 Ok(Some(Outgoing::Response(response)))
1913 );
1914 }
1915 }
1916}