aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-06-16 20:53:43 +0100
committerGitHub <[email protected]>2021-06-16 20:53:43 +0100
commitd6b8af44829521a9f925c4d87599efa3fef38edc (patch)
tree47119538effd381ecd8e15d422103512f2b47406 /crates/ide_completion/src/lib.rs
parentf38770cd2606148bfe764351849ea7ebea45132c (diff)
parentaa644b55859c6b5c6695a5d4fb35d1b6efbbebcc (diff)
Merge #9301
9301: internal: Start refactoring ide_completion tests r=Veykril a=Veykril Our current completion test infra resovles around usually just checking a specific `CompletionKind` which is suboptimal. We only see what we want to see in tests with this causing us to miss a lot of incorrect completions we are doing. Instead we should test for different cursor locations for all kinds(sans the magic kind maybe? not sure yet). This way we will also see potential duplicate completions that merely different in their kind. Also since most completion submodules complete things in tests of other modules due to the tests overlapping it makes more sense to group these tests differently which implies moving them to a new module. Exceptions for this might be stuff like attribute completion as these cannot currently interfere. I only wrote a few tests to check for completions in `ItemList` position so far and I already found a few incorrect/irrelevant completions as these haven't been tested properly due to them being hidden by the `CompletionKind` filtering. I think `CompletionKind` doesn't really seem to be beneficial to me as to I can't think of a occasion where we would want to only check a specific completion kind. Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/ide_completion/src/lib.rs')
-rw-r--r--crates/ide_completion/src/lib.rs123
1 files changed, 5 insertions, 118 deletions
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 18983aa01..bf73818dc 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -1,14 +1,14 @@
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 12
13use completions::flyimport::position_for_import; 13use completions::flyimport::position_for_import;
14use ide_db::{ 14use ide_db::{
@@ -141,6 +141,7 @@ pub fn completions(
141 let ctx = CompletionContext::new(db, position, config)?; 141 let ctx = CompletionContext::new(db, position, config)?;
142 142
143 if ctx.no_completion_required() { 143 if ctx.no_completion_required() {
144 cov_mark::hit!(no_completion_required);
144 // No work required here. 145 // No work required here.
145 return None; 146 return None;
146 } 147 }
@@ -200,117 +201,3 @@ pub fn resolve_completion_edits(
200 201
201 ImportEdit { import, scope }.to_text_edit(config.insert_use).map(|edit| vec![edit]) 202 ImportEdit { import, scope }.to_text_edit(config.insert_use).map(|edit| vec![edit])
202} 203}
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}