]> git.lizzy.rs Git - rust.git/blobdiff - crates/rust-analyzer/tests/heavy_tests/support.rs
Merge branch 'Veetaha-feat/sync-branch'
[rust.git] / crates / rust-analyzer / tests / heavy_tests / support.rs
index 67f3c9332e652cfcc07ad0aa7dc76a00e1ce820b..15d2a05a41961896395c6abdae4d85548bb0439e 100644 (file)
@@ -9,29 +9,32 @@
 use crossbeam_channel::{after, select, Receiver};
 use lsp_server::{Connection, Message, Notification, Request};
 use lsp_types::{
-    notification::{DidOpenTextDocument, Exit},
-    request::Shutdown,
-    ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, TextDocumentClientCapabilities,
-    TextDocumentIdentifier, TextDocumentItem, Url, WorkDoneProgress,
+    notification::Exit, request::Shutdown, TextDocumentIdentifier, Url, WorkDoneProgress,
 };
+use lsp_types::{ProgressParams, ProgressParamsValue};
 use serde::Serialize;
 use serde_json::{to_string_pretty, Value};
 use tempfile::TempDir;
-use test_utils::{find_mismatch, parse_fixture};
+use test_utils::{find_mismatch, Fixture};
 
-use req::{ProgressParams, ProgressParamsValue};
-use rust_analyzer::{main_loop, req, ServerConfig};
+use ra_db::AbsPathBuf;
+use ra_project_model::ProjectManifest;
+use rust_analyzer::{
+    config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject},
+    main_loop,
+};
 
 pub struct Project<'a> {
     fixture: &'a str,
     with_sysroot: bool,
     tmp_dir: Option<TempDir>,
     roots: Vec<PathBuf>,
+    config: Option<Box<dyn Fn(&mut Config)>>,
 }
 
 impl<'a> Project<'a> {
     pub fn with_fixture(fixture: &str) -> Project {
-        Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false }
+        Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false, config: None }
     }
 
     pub fn tmp_dir(mut self, tmp_dir: TempDir) -> Project<'a> {
@@ -39,7 +42,7 @@ pub fn tmp_dir(mut self, tmp_dir: TempDir) -> Project<'a> {
         self
     }
 
-    pub fn root(mut self, path: &str) -> Project<'a> {
+    pub(crate) fn root(mut self, path: &str) -> Project<'a> {
         self.roots.push(path.into());
         self
     }
@@ -49,30 +52,54 @@ pub fn with_sysroot(mut self, sysroot: bool) -> Project<'a> {
         self
     }
 
+    pub fn with_config(mut self, config: impl Fn(&mut Config) + 'static) -> Project<'a> {
+        self.config = Some(Box::new(config));
+        self
+    }
+
     pub fn server(self) -> Server {
         let tmp_dir = self.tmp_dir.unwrap_or_else(|| TempDir::new().unwrap());
         static INIT: Once = Once::new();
         INIT.call_once(|| {
             env_logger::builder().is_test(true).try_init().unwrap();
-            ra_prof::set_filter(if crate::PROFILE.is_empty() {
-                ra_prof::Filter::disabled()
-            } else {
-                ra_prof::Filter::from_spec(&crate::PROFILE)
-            });
+            ra_prof::init_from(crate::PROFILE);
         });
 
-        let mut paths = vec![];
-
-        for entry in parse_fixture(self.fixture) {
-            let path = tmp_dir.path().join(entry.meta);
+        for entry in Fixture::parse(self.fixture) {
+            let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]);
             fs::create_dir_all(path.parent().unwrap()).unwrap();
             fs::write(path.as_path(), entry.text.as_bytes()).unwrap();
-            paths.push((path, entry.text));
         }
 
-        let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect();
+        let tmp_dir_path = AbsPathBuf::assert(tmp_dir.path().to_path_buf());
+        let mut roots =
+            self.roots.into_iter().map(|root| tmp_dir_path.join(root)).collect::<Vec<_>>();
+        if roots.is_empty() {
+            roots.push(tmp_dir_path.clone());
+        }
+        let linked_projects = roots
+            .into_iter()
+            .map(|it| ProjectManifest::discover_single(&it).unwrap())
+            .map(LinkedProject::from)
+            .collect::<Vec<_>>();
 
-        Server::new(tmp_dir, self.with_sysroot, roots, paths)
+        let mut config = Config {
+            client_caps: ClientCapsConfig {
+                location_link: true,
+                code_action_literals: true,
+                work_done_progress: true,
+                ..Default::default()
+            },
+            with_sysroot: self.with_sysroot,
+            linked_projects,
+            files: FilesConfig { watcher: FilesWatcher::Client, exclude: Vec::new() },
+            ..Config::new(tmp_dir_path)
+        };
+        if let Some(f) = &self.config {
+            f(&mut config)
+        }
+
+        Server::new(tmp_dir, config)
     }
 }
 
@@ -90,55 +117,15 @@ pub struct Server {
 }
 
 impl Server {
-    fn new(
-        dir: TempDir,
-        with_sysroot: bool,
-        roots: Vec<PathBuf>,
-        files: Vec<(PathBuf, String)>,
-    ) -> Server {
-        let path = dir.path().to_path_buf();
-
-        let roots = if roots.is_empty() { vec![path] } else { roots };
+    fn new(dir: TempDir, config: Config) -> Server {
         let (connection, client) = Connection::memory();
 
         let _thread = jod_thread::Builder::new()
             .name("test server".to_string())
-            .spawn(move || {
-                main_loop(
-                    roots,
-                    ClientCapabilities {
-                        workspace: None,
-                        text_document: Some(TextDocumentClientCapabilities {
-                            definition: Some(GotoCapability {
-                                dynamic_registration: None,
-                                link_support: Some(true),
-                            }),
-                            ..Default::default()
-                        }),
-                        window: None,
-                        experimental: None,
-                    },
-                    ServerConfig { with_sysroot, ..ServerConfig::default() },
-                    connection,
-                )
-                .unwrap()
-            })
+            .spawn(move || main_loop(config, connection).unwrap())
             .expect("failed to spawn a thread");
 
-        let res =
-            Server { req_id: Cell::new(1), dir, messages: Default::default(), client, _thread };
-
-        for (path, text) in files {
-            res.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams {
-                text_document: TextDocumentItem {
-                    uri: Url::from_file_path(path).unwrap(),
-                    language_id: "rust".to_string(),
-                    version: 0,
-                    text,
-                },
-            })
-        }
-        res
+        Server { req_id: Cell::new(1), dir, messages: Default::default(), client, _thread }
     }
 
     pub fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier {
@@ -188,7 +175,14 @@ fn send_request_(&self, r: Request) -> Value {
         self.client.sender.send(r.into()).unwrap();
         while let Some(msg) = self.recv() {
             match msg {
-                Message::Request(req) => panic!("unexpected request: {:?}", req),
+                Message::Request(req) => {
+                    if req.method != "window/workDoneProgress/create"
+                        && !(req.method == "client/registerCapability"
+                            && req.params.to_string().contains("workspace/didChangeWatchedFiles"))
+                    {
+                        panic!("unexpected request: {:?}", req)
+                    }
+                }
                 Message::Notification(_) => (),
                 Message::Response(res) => {
                     assert_eq!(res.id, id);
@@ -206,9 +200,13 @@ pub fn wait_until_workspace_is_loaded(&self) {
             Message::Notification(n) if n.method == "$/progress" => {
                 match n.clone().extract::<ProgressParams>("$/progress").unwrap() {
                     ProgressParams {
-                        token: req::ProgressToken::String(ref token),
+                        token: lsp_types::ProgressToken::String(ref token),
                         value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(_)),
-                    } if token == "rustAnalyzer/startup" => true,
+<<<<<<< HEAD
+                    } if token == "rustAnalyzer/roots scanned" => true,
+=======
+                    } if token == "rustAnalyzer/rootsScanned" => true,
+>>>>>>> Veetaha-feat/sync-branch
                     _ => false,
                 }
             }