diff options
Diffstat (limited to 'crates/server/tests/heavy_tests')
-rw-r--r-- | crates/server/tests/heavy_tests/main.rs | 36 | ||||
-rw-r--r-- | crates/server/tests/heavy_tests/support.rs | 65 |
2 files changed, 89 insertions, 12 deletions
diff --git a/crates/server/tests/heavy_tests/main.rs b/crates/server/tests/heavy_tests/main.rs index 94c8243b0..9c0196f22 100644 --- a/crates/server/tests/heavy_tests/main.rs +++ b/crates/server/tests/heavy_tests/main.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | extern crate tempdir; | 1 | #[macro_use] |
2 | extern crate crossbeam_channel; | 2 | extern crate crossbeam_channel; |
3 | extern crate tempdir; | ||
3 | extern crate languageserver_types; | 4 | extern crate languageserver_types; |
4 | extern crate serde; | 5 | extern crate serde; |
5 | extern crate serde_json; | 6 | extern crate serde_json; |
@@ -9,10 +10,12 @@ extern crate m; | |||
9 | 10 | ||
10 | mod support; | 11 | mod support; |
11 | 12 | ||
12 | use m::req::{Runnables, RunnablesParams}; | 13 | use m::req::{Runnables, RunnablesParams, DidReloadWorkspace}; |
13 | 14 | ||
14 | use support::project; | 15 | use support::project; |
15 | 16 | ||
17 | const LOG: &'static str = "WARN"; | ||
18 | |||
16 | #[test] | 19 | #[test] |
17 | fn test_runnables() { | 20 | fn test_runnables() { |
18 | let server = project(r" | 21 | let server = project(r" |
@@ -40,3 +43,32 @@ fn foo() { | |||
40 | ]"# | 43 | ]"# |
41 | ); | 44 | ); |
42 | } | 45 | } |
46 | |||
47 | #[test] | ||
48 | fn test_project_model() { | ||
49 | let server = project(r#" | ||
50 | //- Cargo.toml | ||
51 | [package] | ||
52 | name = "foo" | ||
53 | version = "0.0.0" | ||
54 | |||
55 | //- src/lib.rs | ||
56 | pub fn foo() {} | ||
57 | "#); | ||
58 | server.notification::<DidReloadWorkspace>(r#"[ | ||
59 | { | ||
60 | "packages": [ | ||
61 | { | ||
62 | "manifest": "$PROJECT_ROOT$/Cargo.toml", | ||
63 | "name": "foo", | ||
64 | "targets": [ 0 ] | ||
65 | } | ||
66 | ], | ||
67 | "targets": [ | ||
68 | { "kind": "Lib", "name": "foo", "pkg": 0, "root": "$PROJECT_ROOT$/src/lib.rs" } | ||
69 | ], | ||
70 | "ws_members": [ 0 ] | ||
71 | } | ||
72 | ]"# | ||
73 | ); | ||
74 | } | ||
diff --git a/crates/server/tests/heavy_tests/support.rs b/crates/server/tests/heavy_tests/support.rs index 36ca56af3..006926216 100644 --- a/crates/server/tests/heavy_tests/support.rs +++ b/crates/server/tests/heavy_tests/support.rs | |||
@@ -3,16 +3,18 @@ use std::{ | |||
3 | thread, | 3 | thread, |
4 | cell::{Cell, RefCell}, | 4 | cell::{Cell, RefCell}, |
5 | path::PathBuf, | 5 | path::PathBuf, |
6 | time::Duration, | ||
7 | sync::Once, | ||
6 | }; | 8 | }; |
7 | 9 | ||
8 | use tempdir::TempDir; | 10 | use tempdir::TempDir; |
9 | use crossbeam_channel::{bounded, Sender, Receiver}; | 11 | use crossbeam_channel::{bounded, after, Sender, Receiver}; |
10 | use flexi_logger::Logger; | 12 | use flexi_logger::Logger; |
11 | use languageserver_types::{ | 13 | use languageserver_types::{ |
12 | Url, | 14 | Url, |
13 | TextDocumentIdentifier, | 15 | TextDocumentIdentifier, |
14 | request::{Request, Shutdown}, | 16 | request::{Request, Shutdown}, |
15 | notification::DidOpenTextDocument, | 17 | notification::{Notification, DidOpenTextDocument}, |
16 | DidOpenTextDocumentParams, | 18 | DidOpenTextDocumentParams, |
17 | TextDocumentItem, | 19 | TextDocumentItem, |
18 | }; | 20 | }; |
@@ -23,7 +25,8 @@ use gen_lsp_server::{RawMessage, RawRequest, RawNotification}; | |||
23 | use m::{Result, main_loop}; | 25 | use m::{Result, main_loop}; |
24 | 26 | ||
25 | pub fn project(fixture: &str) -> Server { | 27 | pub fn project(fixture: &str) -> Server { |
26 | Logger::with_env_or_str("").start().unwrap(); | 28 | static INIT: Once = Once::new(); |
29 | INIT.call_once(|| Logger::with_env_or_str(::LOG).start().unwrap()); | ||
27 | 30 | ||
28 | let tmp_dir = TempDir::new("test-project") | 31 | let tmp_dir = TempDir::new("test-project") |
29 | .unwrap(); | 32 | .unwrap(); |
@@ -34,6 +37,7 @@ pub fn project(fixture: &str) -> Server { | |||
34 | () => { | 37 | () => { |
35 | if let Some(file_name) = file_name { | 38 | if let Some(file_name) = file_name { |
36 | let path = tmp_dir.path().join(file_name); | 39 | let path = tmp_dir.path().join(file_name); |
40 | fs::create_dir_all(path.parent().unwrap()).unwrap(); | ||
37 | fs::write(path.as_path(), buf.as_bytes()).unwrap(); | 41 | fs::write(path.as_path(), buf.as_bytes()).unwrap(); |
38 | paths.push((path, buf.clone())); | 42 | paths.push((path, buf.clone())); |
39 | } | 43 | } |
@@ -121,6 +125,25 @@ impl Server { | |||
121 | ); | 125 | ); |
122 | } | 126 | } |
123 | 127 | ||
128 | pub fn notification<N>( | ||
129 | &self, | ||
130 | expected: &str, | ||
131 | ) | ||
132 | where | ||
133 | N: Notification, | ||
134 | { | ||
135 | let expected = expected.replace("$PROJECT_ROOT$", &self.dir.path().display().to_string()); | ||
136 | let expected: Value = from_str(&expected).unwrap(); | ||
137 | let actual = self.wait_for_notification(N::METHOD); | ||
138 | assert_eq!( | ||
139 | expected, actual, | ||
140 | "Expected:\n{}\n\ | ||
141 | Actual:\n{}\n", | ||
142 | to_string_pretty(&expected).unwrap(), | ||
143 | to_string_pretty(&actual).unwrap(), | ||
144 | ); | ||
145 | } | ||
146 | |||
124 | fn send_request<R>(&self, id: u64, params: R::Params) -> Value | 147 | fn send_request<R>(&self, id: u64, params: R::Params) -> Value |
125 | where | 148 | where |
126 | R: Request, | 149 | R: Request, |
@@ -130,7 +153,6 @@ impl Server { | |||
130 | self.sender.as_ref() | 153 | self.sender.as_ref() |
131 | .unwrap() | 154 | .unwrap() |
132 | .send(RawMessage::Request(r)); | 155 | .send(RawMessage::Request(r)); |
133 | |||
134 | while let Some(msg) = self.recv() { | 156 | while let Some(msg) = self.recv() { |
135 | match msg { | 157 | match msg { |
136 | RawMessage::Request(req) => panic!("unexpected request: {:?}", req), | 158 | RawMessage::Request(req) => panic!("unexpected request: {:?}", req), |
@@ -146,15 +168,38 @@ impl Server { | |||
146 | } | 168 | } |
147 | panic!("no response"); | 169 | panic!("no response"); |
148 | } | 170 | } |
171 | fn wait_for_notification(&self, method: &str) -> Value { | ||
172 | let f = |msg: &RawMessage| match msg { | ||
173 | RawMessage::Notification(n) if n.method == method => { | ||
174 | Some(n.params.clone()) | ||
175 | } | ||
176 | _ => None, | ||
177 | }; | ||
178 | |||
179 | for msg in self.messages.borrow().iter() { | ||
180 | if let Some(res) = f(msg) { | ||
181 | return res; | ||
182 | } | ||
183 | } | ||
184 | while let Some(msg) = self.recv() { | ||
185 | if let Some(res) = f(&msg) { | ||
186 | return res; | ||
187 | } | ||
188 | } | ||
189 | panic!("no response") | ||
190 | } | ||
149 | fn recv(&self) -> Option<RawMessage> { | 191 | fn recv(&self) -> Option<RawMessage> { |
150 | self.receiver.recv() | 192 | let timeout = Duration::from_secs(5); |
151 | .map(|msg| { | 193 | let msg = select! { |
152 | self.messages.borrow_mut().push(msg.clone()); | 194 | recv(&self.receiver, msg) => msg, |
153 | msg | 195 | recv(after(timeout)) => panic!("timed out"), |
154 | }) | 196 | }; |
197 | msg.map(|msg| { | ||
198 | self.messages.borrow_mut().push(msg.clone()); | ||
199 | msg | ||
200 | }) | ||
155 | } | 201 | } |
156 | fn send_notification(&self, not: RawNotification) { | 202 | fn send_notification(&self, not: RawNotification) { |
157 | |||
158 | self.sender.as_ref() | 203 | self.sender.as_ref() |
159 | .unwrap() | 204 | .unwrap() |
160 | .send(RawMessage::Notification(not)); | 205 | .send(RawMessage::Notification(not)); |