From 45232dfa689bafadf98b92ef30fd32ea9a5e9e7a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 21 Dec 2018 18:13:21 +0300 Subject: organize completion tests better --- crates/ra_analysis/src/completion.rs | 343 ++++------------------------------- 1 file changed, 34 insertions(+), 309 deletions(-) (limited to 'crates/ra_analysis/src/completion.rs') diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs index 09894d955..a11e98ac0 100644 --- a/crates/ra_analysis/src/completion.rs +++ b/crates/ra_analysis/src/completion.rs @@ -16,7 +16,7 @@ use hir::source_binder; use crate::{ db, Cancelable, FilePosition, - completion::completion_item::Completions, + completion::completion_item::{Completions, CompletionKind}, }; pub use crate::completion::completion_item::{CompletionItem, InsertText}; @@ -81,7 +81,12 @@ fn param_completions(acc: &mut Completions, ctx: SyntaxNodeRef) { Some((label, lookup)) } }) - .for_each(|(label, lookup)| CompletionItem::new(label).lookup_by(lookup).add_to(acc)); + .for_each(|(label, lookup)| { + CompletionItem::new(label) + .lookup_by(lookup) + .kind(CompletionKind::Magic) + .add_to(acc) + }); fn process<'a, N: ast::FnDefOwner<'a>>( node: N, @@ -105,341 +110,61 @@ fn is_node<'a, N: AstNode<'a>>(node: SyntaxNodeRef<'a>) -> bool { } #[cfg(test)] -mod tests { - use test_utils::assert_eq_dbg; - - use crate::mock_analysis::single_file_with_position; +fn check_completion(code: &str, expected_completions: &str, kind: CompletionKind) { + use crate::mock_analysis::{single_file_with_position, analysis_and_position}; + let (analysis, position) = if code.contains("//-") { + analysis_and_position(code) + } else { + single_file_with_position(code) + }; + let completions = completions(&analysis.imp.db, position).unwrap().unwrap(); + completions.assert_match(expected_completions, kind); +} +#[cfg(test)] +mod tests { use super::*; - fn is_snippet(completion_item: &CompletionItem) -> bool { - match completion_item.insert_text() { - InsertText::Snippet { .. } => true, - _ => false, - } - } - - fn check_scope_completion(code: &str, expected_completions: &str) { - let (analysis, position) = single_file_with_position(code); - let completions = completions(&analysis.imp.db, position) - .unwrap() - .unwrap() - .into_iter() - .filter(|c| !is_snippet(c)) - .collect::>(); - assert_eq_dbg(expected_completions, &completions); - } - - fn check_snippet_completion(code: &str, expected_completions: &str) { - let (analysis, position) = single_file_with_position(code); - let completions = completions(&analysis.imp.db, position) - .unwrap() - .unwrap() - .into_iter() - .filter(is_snippet) - .collect::>(); - assert_eq_dbg(expected_completions, &completions); - } - - #[test] - fn test_completion_let_scope() { - check_scope_completion( - r" - fn quux(x: i32) { - let y = 92; - 1 + <|>; - let z = (); - } - ", - r#"[CompletionItem { label: "y", lookup: None, snippet: None }, - CompletionItem { label: "x", lookup: None, snippet: None }, - CompletionItem { label: "quux", lookup: None, snippet: None }]"#, - ); - } - - #[test] - fn test_completion_if_let_scope() { - check_scope_completion( - r" - fn quux() { - if let Some(x) = foo() { - let y = 92; - }; - if let Some(a) = bar() { - let b = 62; - 1 + <|> - } - } - ", - r#"[CompletionItem { label: "b", lookup: None, snippet: None }, - CompletionItem { label: "a", lookup: None, snippet: None }, - CompletionItem { label: "quux", lookup: None, snippet: None }]"#, - ); - } - - #[test] - fn test_completion_for_scope() { - check_scope_completion( - r" - fn quux() { - for x in &[1, 2, 3] { - <|> - } - } - ", - r#"[CompletionItem { label: "x", lookup: None, snippet: None }, - CompletionItem { label: "quux", lookup: None, snippet: None }]"#, - ); - } - - #[test] - fn test_completion_mod_scope() { - check_scope_completion( - r" - struct Foo; - enum Baz {} - fn quux() { - <|> - } - ", - r#"[CompletionItem { label: "quux", lookup: None, snippet: None }, - CompletionItem { label: "Foo", lookup: None, snippet: None }, - CompletionItem { label: "Baz", lookup: None, snippet: None }]"#, - ); - } - - #[test] - fn test_completion_mod_scope_no_self_use() { - check_scope_completion( - r" - use foo<|>; - ", - r#"[]"#, - ); - } - - #[test] - fn test_completion_self_path() { - check_scope_completion( - r" - use self::m::<|>; - - mod m { - struct Bar; - } - ", - r#"[CompletionItem { label: "Bar", lookup: None, snippet: None }]"#, - ); - } - - #[test] - fn test_completion_mod_scope_nested() { - check_scope_completion( - r" - struct Foo; - mod m { - struct Bar; - fn quux() { <|> } - } - ", - r#"[CompletionItem { label: "quux", lookup: None, snippet: None }, - CompletionItem { label: "Bar", lookup: None, snippet: None }]"#, - ); - } - - #[test] - fn test_complete_type() { - check_scope_completion( - r" - struct Foo; - fn x() -> <|> - ", - r#"[CompletionItem { label: "Foo", lookup: None, snippet: None }, - CompletionItem { label: "x", lookup: None, snippet: None }]"#, - ) - } - - #[test] - fn test_complete_shadowing() { - check_scope_completion( - r" - fn foo() -> { - let bar = 92; - { - let bar = 62; - <|> - } - } - ", - r#"[CompletionItem { label: "bar", lookup: None, snippet: None }, - CompletionItem { label: "foo", lookup: None, snippet: None }]"#, - ) - } - - #[test] - fn test_complete_self() { - check_scope_completion( - r" - impl S { fn foo(&self) { <|> } } - ", - r#"[CompletionItem { label: "self", lookup: None, snippet: None }]"#, - ) - } - - #[test] - fn test_completion_kewords() { - check_snippet_completion(r" - fn quux() { - <|> - } - ", r#"[CompletionItem { label: "if", lookup: None, snippet: Some("if $0 {}") }, - CompletionItem { label: "match", lookup: None, snippet: Some("match $0 {}") }, - CompletionItem { label: "while", lookup: None, snippet: Some("while $0 {}") }, - CompletionItem { label: "loop", lookup: None, snippet: Some("loop {$0}") }, - CompletionItem { label: "return", lookup: None, snippet: Some("return") }, - CompletionItem { label: "pd", lookup: None, snippet: Some("eprintln!(\"$0 = {:?}\", $0);") }, - CompletionItem { label: "ppd", lookup: None, snippet: Some("eprintln!(\"$0 = {:#?}\", $0);") }]"#); - } - - #[test] - fn test_completion_else() { - check_snippet_completion(r" - fn quux() { - if true { - () - } <|> - } - ", r#"[CompletionItem { label: "if", lookup: None, snippet: Some("if $0 {}") }, - CompletionItem { label: "match", lookup: None, snippet: Some("match $0 {}") }, - CompletionItem { label: "while", lookup: None, snippet: Some("while $0 {}") }, - CompletionItem { label: "loop", lookup: None, snippet: Some("loop {$0}") }, - CompletionItem { label: "else", lookup: None, snippet: Some("else {$0}") }, - CompletionItem { label: "else if", lookup: None, snippet: Some("else if $0 {}") }, - CompletionItem { label: "return", lookup: None, snippet: Some("return") }, - CompletionItem { label: "pd", lookup: None, snippet: Some("eprintln!(\"$0 = {:?}\", $0);") }, - CompletionItem { label: "ppd", lookup: None, snippet: Some("eprintln!(\"$0 = {:#?}\", $0);") }]"#); - } - - #[test] - fn test_completion_return_value() { - check_snippet_completion(r" - fn quux() -> i32 { - <|> - 92 - } - ", r#"[CompletionItem { label: "if", lookup: None, snippet: Some("if $0 {}") }, - CompletionItem { label: "match", lookup: None, snippet: Some("match $0 {}") }, - CompletionItem { label: "while", lookup: None, snippet: Some("while $0 {}") }, - CompletionItem { label: "loop", lookup: None, snippet: Some("loop {$0}") }, - CompletionItem { label: "return", lookup: None, snippet: Some("return $0;") }, - CompletionItem { label: "pd", lookup: None, snippet: Some("eprintln!(\"$0 = {:?}\", $0);") }, - CompletionItem { label: "ppd", lookup: None, snippet: Some("eprintln!(\"$0 = {:#?}\", $0);") }]"#); - check_snippet_completion(r" - fn quux() { - <|> - 92 - } - ", r#"[CompletionItem { label: "if", lookup: None, snippet: Some("if $0 {}") }, - CompletionItem { label: "match", lookup: None, snippet: Some("match $0 {}") }, - CompletionItem { label: "while", lookup: None, snippet: Some("while $0 {}") }, - CompletionItem { label: "loop", lookup: None, snippet: Some("loop {$0}") }, - CompletionItem { label: "return", lookup: None, snippet: Some("return;") }, - CompletionItem { label: "pd", lookup: None, snippet: Some("eprintln!(\"$0 = {:?}\", $0);") }, - CompletionItem { label: "ppd", lookup: None, snippet: Some("eprintln!(\"$0 = {:#?}\", $0);") }]"#); - } - - #[test] - fn test_completion_return_no_stmt() { - check_snippet_completion(r" - fn quux() -> i32 { - match () { - () => <|> - } - } - ", r#"[CompletionItem { label: "if", lookup: None, snippet: Some("if $0 {}") }, - CompletionItem { label: "match", lookup: None, snippet: Some("match $0 {}") }, - CompletionItem { label: "while", lookup: None, snippet: Some("while $0 {}") }, - CompletionItem { label: "loop", lookup: None, snippet: Some("loop {$0}") }, - CompletionItem { label: "return", lookup: None, snippet: Some("return $0") }, - CompletionItem { label: "pd", lookup: None, snippet: Some("eprintln!(\"$0 = {:?}\", $0);") }, - CompletionItem { label: "ppd", lookup: None, snippet: Some("eprintln!(\"$0 = {:#?}\", $0);") }]"#); - } - - #[test] - fn test_continue_break_completion() { - check_snippet_completion(r" - fn quux() -> i32 { - loop { <|> } - } - ", r#"[CompletionItem { label: "if", lookup: None, snippet: Some("if $0 {}") }, - CompletionItem { label: "match", lookup: None, snippet: Some("match $0 {}") }, - CompletionItem { label: "while", lookup: None, snippet: Some("while $0 {}") }, - CompletionItem { label: "loop", lookup: None, snippet: Some("loop {$0}") }, - CompletionItem { label: "continue", lookup: None, snippet: Some("continue") }, - CompletionItem { label: "break", lookup: None, snippet: Some("break") }, - CompletionItem { label: "return", lookup: None, snippet: Some("return $0") }, - CompletionItem { label: "pd", lookup: None, snippet: Some("eprintln!(\"$0 = {:?}\", $0);") }, - CompletionItem { label: "ppd", lookup: None, snippet: Some("eprintln!(\"$0 = {:#?}\", $0);") }]"#); - check_snippet_completion(r" - fn quux() -> i32 { - loop { || { <|> } } - } - ", r#"[CompletionItem { label: "if", lookup: None, snippet: Some("if $0 {}") }, - CompletionItem { label: "match", lookup: None, snippet: Some("match $0 {}") }, - CompletionItem { label: "while", lookup: None, snippet: Some("while $0 {}") }, - CompletionItem { label: "loop", lookup: None, snippet: Some("loop {$0}") }, - CompletionItem { label: "return", lookup: None, snippet: Some("return $0") }, - CompletionItem { label: "pd", lookup: None, snippet: Some("eprintln!(\"$0 = {:?}\", $0);") }, - CompletionItem { label: "ppd", lookup: None, snippet: Some("eprintln!(\"$0 = {:#?}\", $0);") }]"#); + fn check_magic_completion(code: &str, expected_completions: &str) { + check_completion(code, expected_completions, CompletionKind::Magic); } #[test] fn test_param_completion_last_param() { - check_scope_completion(r" + check_magic_completion( + r" fn foo(file_id: FileId) {} fn bar(file_id: FileId) {} fn baz(file<|>) {} - ", r#"[CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); + ", + r#"file_id "file_id: FileId""#, + ); } #[test] fn test_param_completion_nth_param() { - check_scope_completion(r" + check_magic_completion( + r" fn foo(file_id: FileId) {} fn bar(file_id: FileId) {} fn baz(file<|>, x: i32) {} - ", r#"[CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); + ", + r#"file_id "file_id: FileId""#, + ); } #[test] fn test_param_completion_trait_param() { - check_scope_completion(r" + check_magic_completion( + r" pub(crate) trait SourceRoot { pub fn contains(&self, file_id: FileId) -> bool; pub fn module_map(&self) -> &ModuleMap; pub fn lines(&self, file_id: FileId) -> &LineIndex; pub fn syntax(&self, file<|>) } - ", r#"[CompletionItem { label: "self", lookup: None, snippet: None }, - CompletionItem { label: "SourceRoot", lookup: None, snippet: None }, - CompletionItem { label: "file_id: FileId", lookup: Some("file_id"), snippet: None }]"#); - } - - #[test] - fn test_item_snippets() { - // check_snippet_completion(r" - // <|> - // ", - // r##"[CompletionItem { label: "Test function", lookup: None, snippet: Some("#[test]\nfn test_${1:feature}() {\n$0\n}"##, - // ); - check_snippet_completion(r" - #[cfg(test)] - mod tests { - <|> - } ", - r##"[CompletionItem { label: "Test function", lookup: Some("tfn"), snippet: Some("#[test]\nfn ${1:feature}() {\n $0\n}") }, - CompletionItem { label: "pub(crate)", lookup: None, snippet: Some("pub(crate) $0") }]"##, + r#"file_id "file_id: FileId""#, ); } } -- cgit v1.2.3