From 0e23175a077de5183a34696490848b47e4198f56 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 3 Jul 2020 11:48:48 +0200 Subject: [PATCH] Cleanup record completion tests --- .../ra_ide/src/completion/complete_record.rs | 578 ++++++------------ .../ra_ide/src/completion/completion_item.rs | 20 +- crates/ra_ide/src/completion/presentation.rs | 25 + crates/ra_ide/src/completion/test_utils.rs | 10 +- 4 files changed, 243 insertions(+), 390 deletions(-) diff --git a/crates/ra_ide/src/completion/complete_record.rs b/crates/ra_ide/src/completion/complete_record.rs index 13eb2f79fa..74b94594dc 100644 --- a/crates/ra_ide/src/completion/complete_record.rs +++ b/crates/ra_ide/src/completion/complete_record.rs @@ -18,389 +18,209 @@ pub(super) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> #[cfg(test)] mod tests { - mod record_pat_tests { - use insta::assert_debug_snapshot; + use expect::{expect, Expect}; - use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; + use crate::completion::{test_utils::completion_list, CompletionKind}; - fn complete(code: &str) -> Vec { - do_completion(code, CompletionKind::Reference) - } - - #[test] - fn test_record_pattern_field() { - let completions = complete( - r" - struct S { foo: u32 } - - fn process(f: S) { - match f { - S { f<|>: 92 } => (), - } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "foo", - source_range: 68..69, - delete: 68..69, - insert: "foo", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn test_record_pattern_enum_variant() { - let completions = complete( - r" - enum E { - S { foo: u32, bar: () } - } - - fn process(e: E) { - match e { - E::S { <|> } => (), - } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "bar", - source_range: 88..88, - delete: 88..88, - insert: "bar", - kind: Field, - detail: "()", - }, - CompletionItem { - label: "foo", - source_range: 88..88, - delete: 88..88, - insert: "foo", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn test_record_pattern_field_in_simple_macro() { - let completions = complete( - r" - macro_rules! m { ($e:expr) => { $e } } - struct S { foo: u32 } - - fn process(f: S) { - m!(match f { - S { f<|>: 92 } => (), - }) - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "foo", - source_range: 110..111, - delete: 110..111, - insert: "foo", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn only_missing_fields_are_completed_in_destruct_pats() { - let completions = complete( - r" - struct S { - foo1: u32, - foo2: u32, - bar: u32, - baz: u32, - } - - fn main() { - let s = S { - foo1: 1, - foo2: 2, - bar: 3, - baz: 4, - }; - if let S { foo1, foo2: a, <|> } = s {} - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "bar", - source_range: 203..203, - delete: 203..203, - insert: "bar", - kind: Field, - detail: "u32", - }, - CompletionItem { - label: "baz", - source_range: 203..203, - delete: 203..203, - insert: "baz", - kind: Field, - detail: "u32", - }, - ] - "###); - } + fn check(ra_fixture: &str, expect: Expect) { + let actual = completion_list(ra_fixture, CompletionKind::Reference); + expect.assert_eq(&actual); } - mod record_lit_tests { - use insta::assert_debug_snapshot; + #[test] + fn test_record_pattern_field() { + check( + r#" +struct S { foo: u32 } - use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; - - fn complete(code: &str) -> Vec { - do_completion(code, CompletionKind::Reference) - } - - #[test] - fn test_record_literal_deprecated_field() { - let completions = complete( - r" - struct A { - #[deprecated] - the_field: u32, - } - fn foo() { - A { the<|> } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "the_field", - source_range: 69..72, - delete: 69..72, - insert: "the_field", - kind: Field, - detail: "u32", - deprecated: true, - }, - ] - "###); - } - - #[test] - fn test_record_literal_field() { - let completions = complete( - r" - struct A { the_field: u32 } - fn foo() { - A { the<|> } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "the_field", - source_range: 46..49, - delete: 46..49, - insert: "the_field", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn test_record_literal_enum_variant() { - let completions = complete( - r" - enum E { - A { a: u32 } - } - fn foo() { - let _ = E::A { <|> } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "a", - source_range: 58..58, - delete: 58..58, - insert: "a", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn test_record_literal_two_structs() { - let completions = complete( - r" - struct A { a: u32 } - struct B { b: u32 } - - fn foo() { - let _: A = B { <|> } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "b", - source_range: 70..70, - delete: 70..70, - insert: "b", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn test_record_literal_generic_struct() { - let completions = complete( - r" - struct A { a: T } - - fn foo() { - let _: A = A { <|> } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "a", - source_range: 56..56, - delete: 56..56, - insert: "a", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn test_record_literal_field_in_simple_macro() { - let completions = complete( - r" - macro_rules! m { ($e:expr) => { $e } } - struct A { the_field: u32 } - fn foo() { - m!(A { the<|> }) - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "the_field", - source_range: 88..91, - delete: 88..91, - insert: "the_field", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn only_missing_fields_are_completed() { - let completions = complete( - r" - struct S { - foo1: u32, - foo2: u32, - bar: u32, - baz: u32, - } - - fn main() { - let foo1 = 1; - let s = S { - foo1, - foo2: 5, - <|> - } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "bar", - source_range: 157..157, - delete: 157..157, - insert: "bar", - kind: Field, - detail: "u32", - }, - CompletionItem { - label: "baz", - source_range: 157..157, - delete: 157..157, - insert: "baz", - kind: Field, - detail: "u32", - }, - ] - "###); - } - - #[test] - fn completes_functional_update() { - let completions = complete( - r" - struct S { - foo1: u32, - foo2: u32, - } - - fn main() { - let foo1 = 1; - let s = S { - foo1, - <|> - .. loop {} - } - } - ", - ); - assert_debug_snapshot!(completions, @r###" - [ - CompletionItem { - label: "foo2", - source_range: 112..112, - delete: 112..112, - insert: "foo2", - kind: Field, - detail: "u32", - }, - ] - "###); - } +fn process(f: S) { + match f { + S { f<|>: 92 } => (), + } +} +"#, + expect![[r#" + fd foo u32 + "#]], + ); + } + + #[test] + fn test_record_pattern_enum_variant() { + check( + r#" +enum E { S { foo: u32, bar: () } } + +fn process(e: E) { + match e { + E::S { <|> } => (), + } +} +"#, + expect![[r#" + fd bar () + fd foo u32 + "#]], + ); + } + + #[test] + fn test_record_pattern_field_in_simple_macro() { + check( + r" +macro_rules! m { ($e:expr) => { $e } } +struct S { foo: u32 } + +fn process(f: S) { + m!(match f { + S { f<|>: 92 } => (), + }) +} +", + expect![[r#" + fd foo u32 + "#]], + ); + } + + #[test] + fn only_missing_fields_are_completed_in_destruct_pats() { + check( + r#" +struct S { + foo1: u32, foo2: u32, + bar: u32, baz: u32, +} + +fn main() { + let s = S { + foo1: 1, foo2: 2, + bar: 3, baz: 4, + }; + if let S { foo1, foo2: a, <|> } = s {} +} +"#, + expect![[r#" + fd bar u32 + fd baz u32 + "#]], + ); + } + + #[test] + fn test_record_literal_field() { + check( + r#" +struct A { the_field: u32 } +fn foo() { + A { the<|> } +} +"#, + expect![[r#" + fd the_field u32 + "#]], + ); + } + + #[test] + fn test_record_literal_enum_variant() { + check( + r#" +enum E { A { a: u32 } } +fn foo() { + let _ = E::A { <|> } +} +"#, + expect![[r#" + fd a u32 + "#]], + ); + } + + #[test] + fn test_record_literal_two_structs() { + check( + r#" +struct A { a: u32 } +struct B { b: u32 } + +fn foo() { + let _: A = B { <|> } +} +"#, + expect![[r#" + fd b u32 + "#]], + ); + } + + #[test] + fn test_record_literal_generic_struct() { + check( + r#" +struct A { a: T } + +fn foo() { + let _: A = A { <|> } +} +"#, + expect![[r#" + fd a u32 + "#]], + ); + } + + #[test] + fn test_record_literal_field_in_simple_macro() { + check( + r#" +macro_rules! m { ($e:expr) => { $e } } +struct A { the_field: u32 } +fn foo() { + m!(A { the<|> }) +} +"#, + expect![[r#" + fd the_field u32 + "#]], + ); + } + + #[test] + fn only_missing_fields_are_completed() { + check( + r#" +struct S { + foo1: u32, foo2: u32, + bar: u32, baz: u32, +} + +fn main() { + let foo1 = 1; + let s = S { foo1, foo2: 5, <|> } +} +"#, + expect![[r#" + fd bar u32 + fd baz u32 + "#]], + ); + } + + #[test] + fn completes_functional_update() { + check( + r#" +struct S { foo1: u32, foo2: u32 } + +fn main() { + let foo1 = 1; + let s = S { foo1, <|> .. loop {} } +} +"#, + expect![[r#" + fd foo2 u32 + "#]], + ); } } diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs index 98348b3492..4db371d57f 100644 --- a/crates/ra_ide/src/completion/completion_item.rs +++ b/crates/ra_ide/src/completion/completion_item.rs @@ -129,24 +129,24 @@ impl CompletionItemKind { #[cfg(test)] pub(crate) fn tag(&self) -> &'static str { match self { - CompletionItemKind::Snippet => "sn", - CompletionItemKind::Keyword => "kw", - CompletionItemKind::Module => "md", - CompletionItemKind::Function => "fn", + CompletionItemKind::Attribute => "at", + CompletionItemKind::Binding => "bn", CompletionItemKind::BuiltinType => "bt", - CompletionItemKind::Struct => "st", + CompletionItemKind::Const => "ct", CompletionItemKind::Enum => "en", CompletionItemKind::EnumVariant => "ev", - CompletionItemKind::Binding => "bn", CompletionItemKind::Field => "fd", + CompletionItemKind::Function => "fn", + CompletionItemKind::Keyword => "kw", + CompletionItemKind::Macro => "ma", + CompletionItemKind::Method => "me", + CompletionItemKind::Module => "md", + CompletionItemKind::Snippet => "sn", CompletionItemKind::Static => "sc", - CompletionItemKind::Const => "ct", + CompletionItemKind::Struct => "st", CompletionItemKind::Trait => "tt", CompletionItemKind::TypeAlias => "ta", - CompletionItemKind::Method => "me", CompletionItemKind::TypeParam => "tp", - CompletionItemKind::Macro => "ma", - CompletionItemKind::Attribute => "at", } } } diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index b18279746e..bd274bd743 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -606,6 +606,31 @@ mod tests { ] "### ); + + assert_debug_snapshot!(do_reference_completion( + r#" +struct A { + #[deprecated] + the_field: u32, +} +fn foo() { + A { the<|> } +} +"#, + ), + @r###" + [ + CompletionItem { + label: "the_field", + source_range: 69..72, + delete: 69..72, + insert: "the_field", + kind: Field, + detail: "u32", + deprecated: true, + }, + ] + "###); } #[test] diff --git a/crates/ra_ide/src/completion/test_utils.rs b/crates/ra_ide/src/completion/test_utils.rs index 5c01654cc0..5938415b3c 100644 --- a/crates/ra_ide/src/completion/test_utils.rs +++ b/crates/ra_ide/src/completion/test_utils.rs @@ -2,6 +2,7 @@ use hir::Semantics; use ra_syntax::{AstNode, NodeOrToken, SyntaxElement}; +use stdx::format_to; use crate::{ completion::{completion_item::CompletionKind, CompletionConfig}, @@ -42,7 +43,14 @@ pub(crate) fn completion_list_with_options( kind_completions.sort_by_key(|c| c.label().to_owned()); kind_completions .into_iter() - .map(|it| format!("{} {}\n", it.kind().unwrap().tag(), it.label())) + .map(|it| { + let mut buf = format!("{} {}", it.kind().unwrap().tag(), it.label()); + if let Some(detail) = it.detail() { + format_to!(buf, " {}", detail); + } + format_to!(buf, "\n"); + buf + }) .collect() }