summaryrefslogtreecommitdiff
path: root/support/texlab/src/test/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/test/mod.rs')
-rw-r--r--support/texlab/src/test/mod.rs632
1 files changed, 0 insertions, 632 deletions
diff --git a/support/texlab/src/test/mod.rs b/support/texlab/src/test/mod.rs
deleted file mode 100644
index 5f26fb0dcc..0000000000
--- a/support/texlab/src/test/mod.rs
+++ /dev/null
@@ -1,632 +0,0 @@
-#![allow(deprecated)]
-
-mod client;
-mod server;
-
-pub use self::{
- client::{TestLatexLspClient, TestLspClient},
- server::TestLatexLspServer,
-};
-
-use crate::{
- protocol::*,
- server::LatexLspServer,
- tex::{Distribution, UnknownDistribution},
-};
-use futures::{
- channel::mpsc,
- future::{join, AbortHandle, Abortable},
- lock::Mutex,
- prelude::*,
-};
-use jsonrpc::MessageHandler;
-use once_cell::sync::Lazy;
-use std::{path::PathBuf, sync::Arc};
-use tempfile::{tempdir, TempDir};
-use tokio::fs;
-
-struct GlobalDistribution {
- distro: Mutex<Option<Arc<dyn Distribution>>>,
-}
-
-impl GlobalDistribution {
- fn new() -> Self {
- Self {
- distro: Mutex::new(None),
- }
- }
-
- async fn get(&self, use_distro: bool) -> Arc<dyn Distribution> {
- if use_distro {
- let mut distro_lock = self.distro.lock().await;
- match &*distro_lock {
- Some(distro) => distro.clone(),
- None => {
- let distro = Distribution::detect().await;
- *distro_lock = Some(distro.clone());
- distro
- }
- }
- } else {
- Arc::new(UnknownDistribution::default())
- }
- }
-}
-
-static DISTRO: Lazy<GlobalDistribution> = Lazy::new(GlobalDistribution::new);
-
-#[derive(Debug)]
-struct Endpoint<S, C> {
- receiver: mpsc::Receiver<String>,
- client: Arc<C>,
- server: Arc<S>,
- handler: MessageHandler<S, C>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct TestBedBuilder {
- files: Vec<(PathBuf, String)>,
- use_distro: bool,
- root_dir: Option<PathBuf>,
- latex_build: Option<LatexBuildOptions>,
- latex_lint: Option<LatexLintOptions>,
- latex_forward_search: Option<LatexForwardSearchOptions>,
- bibtex_formatting: Option<BibtexFormattingOptions>,
-}
-
-impl TestBedBuilder {
- pub fn new() -> Self {
- Self::default()
- }
-
- pub fn file<P: Into<PathBuf>>(&mut self, path: P, text: &str) -> &mut Self {
- self.files.push((path.into(), text.trim().into()));
- self
- }
-
- pub fn use_distro(&mut self) -> &mut Self {
- self.use_distro = true;
- self
- }
-
- pub fn root_dir<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
- self.root_dir = Some(path.into());
- self
- }
-
- pub fn latex_build(&mut self, options: LatexBuildOptions) -> &mut Self {
- self.latex_build = Some(options);
- self
- }
-
- pub fn latex_lint(&mut self, options: LatexLintOptions) -> &mut Self {
- self.latex_lint = Some(options);
- self
- }
-
- pub fn latex_forward_search(&mut self, options: LatexForwardSearchOptions) -> &mut Self {
- self.latex_forward_search = Some(options);
- self
- }
-
- pub fn bibtex_formatting(&mut self, options: BibtexFormattingOptions) -> &mut Self {
- self.bibtex_formatting = Some(options);
- self
- }
-
- pub async fn build(&self) -> TestBed {
- let dir = tempdir().expect("failed to create temporary directory");
- for (path, text) in &self.files {
- let full_path = dir.path().join(path);
- fs::create_dir_all(full_path.parent().unwrap())
- .await
- .unwrap();
- fs::write(&full_path, text).await.unwrap();
- }
-
- let (tx1, rx1) = mpsc::channel(0);
- let (tx2, rx2) = mpsc::channel(0);
-
- let endpoint1 = self.build_endpoint1(&dir, tx2, rx1).await;
- let endpoint2 = self.build_endpoint2(&dir, tx1, rx2).await;
- let server = Arc::clone(&endpoint2.server);
- let client = Arc::clone(&endpoint2.client);
- TestBed {
- dir,
- server,
- client,
- endpoint1: Some(endpoint1),
- endpoint2: Some(endpoint2),
- handle: None,
- }
- }
-
- async fn build_endpoint1(
- &self,
- dir: &TempDir,
- tx2: mpsc::Sender<String>,
- rx1: mpsc::Receiver<String>,
- ) -> Endpoint<LatexLspServer<LatexLspClient>, LatexLspClient> {
- let client = Arc::new(LatexLspClient::new(tx2.clone()));
- let server = Arc::new(LatexLspServer::new(
- DISTRO.get(self.use_distro).await,
- Arc::clone(&client),
- Arc::new(dir.path().to_path_buf()),
- ));
-
- Endpoint {
- receiver: rx1,
- client: Arc::clone(&client),
- server: Arc::clone(&server),
- handler: MessageHandler {
- client,
- server,
- output: tx2.clone(),
- },
- }
- }
-
- async fn build_endpoint2(
- &self,
- dir: &TempDir,
- tx1: mpsc::Sender<String>,
- rx2: mpsc::Receiver<String>,
- ) -> Endpoint<TestLatexLspServer, TestLatexLspClient> {
- let options = Options {
- latex: Some(LatexOptions {
- root_directory: self.root_dir.as_ref().map(|path| dir.path().join(path)),
- build: self.latex_build.clone(),
- forward_search: self.latex_forward_search.clone(),
- lint: self.latex_lint.clone(),
- }),
- bibtex: Some(BibtexOptions {
- formatting: self.bibtex_formatting.clone(),
- }),
- };
-
- let test_client = Arc::new(TestLatexLspClient::new(tx1.clone()));
- let test_server = Arc::new(TestLatexLspServer::new(options));
-
- Endpoint {
- receiver: rx2,
- client: Arc::clone(&test_client),
- server: Arc::clone(&test_server),
- handler: MessageHandler {
- client: test_client,
- server: test_server,
- output: tx1,
- },
- }
- }
-}
-
-pub struct TestBed {
- pub dir: TempDir,
- pub server: Arc<TestLatexLspServer>,
- pub client: Arc<TestLatexLspClient>,
- endpoint1: Option<Endpoint<LatexLspServer<LatexLspClient>, LatexLspClient>>,
- endpoint2: Option<Endpoint<TestLatexLspServer, TestLatexLspClient>>,
- handle: Option<AbortHandle>,
-}
-
-impl TestBed {
- pub fn spawn(&mut self) {
- let (handle, reg) = AbortHandle::new_pair();
-
- let endpoint1 = self.endpoint1.take().unwrap();
- let endpoint2 = self.endpoint2.take().unwrap();
- let mut rx1 = endpoint1.receiver;
- let mut rx2 = endpoint2.receiver;
- let mut handler1 = endpoint1.handler;
- let mut handler2 = endpoint2.handler;
-
- tokio::spawn(Abortable::new(
- async move {
- let task1 = async move {
- while let Some(json) = rx2.next().await {
- handler2.handle(&json).await;
- }
- };
-
- let task2 = async move {
- while let Some(json) = rx1.next().await {
- handler1.handle(&json).await;
- }
- };
-
- join(task1, task2).await;
- },
- reg,
- ));
- self.handle = Some(handle);
- }
-
- pub async fn initialize(&self, capabilities: ClientCapabilities) {
- self.client
- .initialize(InitializeParams {
- capabilities,
- initialization_options: None,
- process_id: None,
- root_path: None,
- root_uri: None,
- trace: None,
- workspace_folders: None,
- client_info: None,
- })
- .await
- .unwrap();
- self.client.initialized(InitializedParams {}).await;
- }
-
- pub fn path(&self, relative_path: &str) -> PathBuf {
- self.dir.path().join(relative_path)
- }
-
- pub fn uri(&self, relative_path: &str) -> Uri {
- Uri::from_file_path(self.path(relative_path)).unwrap()
- }
-
- pub fn identifier(&self, relative_path: &str) -> TextDocumentIdentifier {
- TextDocumentIdentifier::new(self.uri(relative_path).into())
- }
-
- pub async fn open(&self, relative_path: &str) {
- let full_path = self.path(relative_path);
- let params = DidOpenTextDocumentParams {
- text_document: TextDocumentItem {
- language_id: if relative_path.ends_with("bib") {
- "bibtex".into()
- } else {
- "latex".into()
- },
- uri: Uri::from_file_path(&full_path).unwrap().into(),
- version: 0,
- text: fs::read_to_string(&full_path).await.unwrap(),
- },
- };
- self.client.did_open(params).await;
- }
-
- pub async fn edit<S: Into<String>>(&self, relative_path: &str, text: S) {
- let uri = self.uri(relative_path).into();
- let params = DidChangeTextDocumentParams {
- text_document: VersionedTextDocumentIdentifier::new(uri, 0),
- content_changes: vec![TextDocumentContentChangeEvent {
- range: None,
- range_length: None,
- text: text.into(),
- }],
- };
- self.client.did_change(params).await;
- }
-
- pub async fn push_options(&self) {
- let options = self.server.options.lock().await.clone();
- let params = DidChangeConfigurationParams {
- settings: serde_json::to_value::<Options>(options).unwrap(),
- };
- self.client.did_change_configuration(params).await
- }
-
- pub async fn definition_link(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<LocationLink>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- let response = self.client.definition(params).await.ok()?;
- match response {
- DefinitionResponse::LocationLinks(links) => Some(links),
- DefinitionResponse::Locations(_) => unreachable!(),
- }
- }
-
- pub async fn definition_location(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<Location>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- let response = self.client.definition(params).await.ok()?;
- match response {
- DefinitionResponse::LocationLinks(_) => unreachable!(),
- DefinitionResponse::Locations(locations) => Some(locations),
- }
- }
-
- pub async fn completion(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<CompletionItem>> {
- let params = CompletionParams {
- text_document_position: TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- },
- context: None,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client
- .completion(params)
- .await
- .ok()
- .map(|list| list.items)
- }
-
- pub async fn folding_range(&self, relative_path: &str) -> Option<Vec<FoldingRange>> {
- let params = FoldingRangeParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client.folding_range(params).await.ok()
- }
-
- pub async fn document_highlight(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Vec<DocumentHighlight>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- self.client.document_highlight(params).await.ok()
- }
-
- pub async fn document_link(&self, relative_path: &str) -> Option<Vec<DocumentLink>> {
- let params = DocumentLinkParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client.document_link(params).await.ok()
- }
-
- pub async fn references(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- include_declaration: bool,
- ) -> Option<Vec<Location>> {
- let params = ReferenceParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(relative_path),
- Position::new(line, character),
- ),
- context: ReferenceContext {
- include_declaration,
- },
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.client.references(params).await.ok()
- }
-
- pub async fn prepare_rename(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Option<Range>> {
- let pos = Position::new(line, character);
- let params = TextDocumentPositionParams::new(self.identifier(relative_path), pos);
- self.client.prepare_rename(params).await.ok()
- }
-
- pub async fn rename<S: Into<String>>(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- new_name: S,
- ) -> Option<Option<WorkspaceEdit>> {
- let params = RenameParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(relative_path),
- Position::new(line, character),
- ),
- new_name: new_name.into(),
- work_done_progress_params: WorkDoneProgressParams::default(),
- };
- self.client.rename(params).await.ok()
- }
-
- pub async fn document_symbol_flat(
- &self,
- relative_path: &str,
- ) -> Option<Vec<SymbolInformation>> {
- let params = DocumentSymbolParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- match self.client.document_symbol(params).await.ok()? {
- DocumentSymbolResponse::Flat(symbols) => Some(symbols),
- DocumentSymbolResponse::Nested(_) => unreachable!(),
- }
- }
-
- pub async fn document_symbol_nested(&self, relative_path: &str) -> Option<Vec<DocumentSymbol>> {
- let params = DocumentSymbolParams {
- text_document: self.identifier(relative_path),
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- match self.client.document_symbol(params).await.ok()? {
- DocumentSymbolResponse::Flat(_) => unreachable!(),
- DocumentSymbolResponse::Nested(symbols) => Some(symbols),
- }
- }
-
- pub async fn hover(
- &self,
- relative_path: &str,
- line: u64,
- character: u64,
- ) -> Option<Option<Hover>> {
- let params = TextDocumentPositionParams {
- text_document: self.identifier(relative_path),
- position: Position::new(line, character),
- };
- self.client.hover(params).await.ok()
- }
-
- pub async fn detect_root(&self, relative_path: &str) {
- self.client
- .detect_root(self.identifier(relative_path))
- .await
- .unwrap();
- }
-
- pub async fn shutdown(&self) {
- self.client.shutdown(()).await.unwrap();
- self.client.exit(()).await;
- }
-}
-
-impl Drop for TestBed {
- fn drop(&mut self) {
- if let Some(handle) = self.handle.as_ref() {
- handle.abort();
- }
- }
-}
-
-pub static PULL_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: None,
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: Some(true),
- did_change_configuration: None,
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};
-
-pub static PUSH_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: None,
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: None,
- did_change_configuration: Some(GenericCapability {
- dynamic_registration: Some(true),
- }),
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};
-
-pub static NESTED_SYMBOL_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: Some(TextDocumentClientCapabilities {
- code_action: None,
- code_lens: None,
- color_provider: None,
- completion: None,
- declaration: None,
- definition: None,
- document_highlight: None,
- document_link: None,
- document_symbol: Some(DocumentSymbolCapability {
- hierarchical_document_symbol_support: Some(true),
- dynamic_registration: None,
- symbol_kind: None,
- }),
- folding_range: None,
- formatting: None,
- hover: None,
- implementation: None,
- on_type_formatting: None,
- publish_diagnostics: None,
- range_formatting: None,
- references: None,
- rename: None,
- signature_help: None,
- synchronization: None,
- type_definition: None,
- }),
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: Some(true),
- did_change_configuration: None,
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};
-
-pub static LOCATION_LINK_CAPABILITIES: ClientCapabilities = {
- ClientCapabilities {
- experimental: None,
- text_document: Some(TextDocumentClientCapabilities {
- code_action: None,
- code_lens: None,
- color_provider: None,
- completion: None,
- declaration: None,
- definition: Some(GotoCapability {
- dynamic_registration: None,
- link_support: Some(true),
- }),
- document_highlight: None,
- document_link: None,
- document_symbol: None,
- folding_range: None,
- formatting: None,
- hover: None,
- implementation: None,
- on_type_formatting: None,
- publish_diagnostics: None,
- range_formatting: None,
- references: None,
- rename: None,
- signature_help: None,
- synchronization: None,
- type_definition: None,
- }),
- window: None,
- workspace: Some(WorkspaceClientCapabilities {
- apply_edit: None,
- configuration: Some(true),
- did_change_configuration: None,
- did_change_watched_files: None,
- execute_command: None,
- symbol: None,
- workspace_edit: None,
- workspace_folders: None,
- }),
- }
-};