aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/lib.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-06-16 16:37:23 +0100
committerLukas Wirth <[email protected]>2021-06-16 20:51:20 +0100
commitd338a803941c2b0ac83decfcdfac33c09dfaa971 (patch)
tree6656cf5923aa537bbfba8c1bd267fe8dfafb2c14 /crates/ide_completion/src/lib.rs
parentf38770cd2606148bfe764351849ea7ebea45132c (diff)
Start refactoring ide_completion tests
Diffstat (limited to 'crates/ide_completion/src/lib.rs')
-rw-r--r--crates/ide_completion/src/lib.rs125
1 files changed, 7 insertions, 118 deletions
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 18983aa01..be6442426 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -1,14 +1,16 @@
1//! `completions` crate provides utilities for generating completions of user input. 1//! `completions` crate provides utilities for generating completions of user input.
2 2
3mod completions;
3mod config; 4mod config;
4mod item;
5mod context; 5mod context;
6mod item;
6mod patterns; 7mod patterns;
7#[cfg(test)]
8mod test_utils;
9mod render; 8mod render;
10 9
11mod completions; 10#[cfg(test)]
11mod tests;
12#[cfg(test)]
13mod test_utils;
12 14
13use completions::flyimport::position_for_import; 15use completions::flyimport::position_for_import;
14use ide_db::{ 16use ide_db::{
@@ -141,6 +143,7 @@ pub fn completions(
141 let ctx = CompletionContext::new(db, position, config)?; 143 let ctx = CompletionContext::new(db, position, config)?;
142 144
143 if ctx.no_completion_required() { 145 if ctx.no_completion_required() {
146 cov_mark::hit!(no_completion_required);
144 // No work required here. 147 // No work required here.
145 return None; 148 return None;
146 } 149 }
@@ -200,117 +203,3 @@ pub fn resolve_completion_edits(
200 203
201 ImportEdit { import, scope }.to_text_edit(config.insert_use).map(|edit| vec![edit]) 204 ImportEdit { import, scope }.to_text_edit(config.insert_use).map(|edit| vec![edit])
202} 205}
203
204#[cfg(test)]
205mod tests {
206 use crate::test_utils::{self, TEST_CONFIG};
207
208 struct DetailAndDocumentation<'a> {
209 detail: &'a str,
210 documentation: &'a str,
211 }
212
213 fn check_detail_and_documentation(ra_fixture: &str, expected: DetailAndDocumentation) {
214 let (db, position) = test_utils::position(ra_fixture);
215 let config = TEST_CONFIG;
216 let completions: Vec<_> = crate::completions(&db, &config, position).unwrap().into();
217 for item in completions {
218 if item.detail() == Some(expected.detail) {
219 let opt = item.documentation();
220 let doc = opt.as_ref().map(|it| it.as_str());
221 assert_eq!(doc, Some(expected.documentation));
222 return;
223 }
224 }
225 panic!("completion detail not found: {}", expected.detail)
226 }
227
228 fn check_no_completion(ra_fixture: &str) {
229 let (db, position) = test_utils::position(ra_fixture);
230 let config = TEST_CONFIG;
231
232 let completions: Option<Vec<String>> = crate::completions(&db, &config, position)
233 .and_then(|completions| {
234 let completions: Vec<_> = completions.into();
235 if completions.is_empty() {
236 None
237 } else {
238 Some(completions)
239 }
240 })
241 .map(|completions| {
242 completions.into_iter().map(|completion| format!("{:?}", completion)).collect()
243 });
244
245 // `assert_eq` instead of `assert!(completions.is_none())` to get the list of completions if test will panic.
246 assert_eq!(completions, None, "Completions were generated, but weren't expected");
247 }
248
249 #[test]
250 fn test_completion_detail_from_macro_generated_struct_fn_doc_attr() {
251 check_detail_and_documentation(
252 r#"
253macro_rules! bar {
254 () => {
255 struct Bar;
256 impl Bar {
257 #[doc = "Do the foo"]
258 fn foo(&self) {}
259 }
260 }
261}
262
263bar!();
264
265fn foo() {
266 let bar = Bar;
267 bar.fo$0;
268}
269"#,
270 DetailAndDocumentation { detail: "fn(&self)", documentation: "Do the foo" },
271 );
272 }
273
274 #[test]
275 fn test_completion_detail_from_macro_generated_struct_fn_doc_comment() {
276 check_detail_and_documentation(
277 r#"
278macro_rules! bar {
279 () => {
280 struct Bar;
281 impl Bar {
282 /// Do the foo
283 fn foo(&self) {}
284 }
285 }
286}
287
288bar!();
289
290fn foo() {
291 let bar = Bar;
292 bar.fo$0;
293}
294"#,
295 DetailAndDocumentation { detail: "fn(&self)", documentation: "Do the foo" },
296 );
297 }
298
299 #[test]
300 fn test_no_completions_required() {
301 // There must be no hint for 'in' keyword.
302 check_no_completion(r#"fn foo() { for i i$0 }"#);
303 // After 'in' keyword hints may be spawned.
304 check_detail_and_documentation(
305 r#"
306/// Do the foo
307fn foo() -> &'static str { "foo" }
308
309fn bar() {
310 for c in fo$0
311}
312"#,
313 DetailAndDocumentation { detail: "fn() -> &str", documentation: "Do the foo" },
314 );
315 }
316}