5221: Modernize postfix completion tests r=matklad a=matklad



bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-07-04 13:44:52 +00:00 committed by GitHub
commit 1d3a3c0782
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 168 additions and 608 deletions

View file

@ -33,107 +33,56 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
#[cfg(test)]
mod tests {
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
use insta::assert_debug_snapshot;
use expect::{expect, Expect};
fn complete(code: &str) -> Vec<CompletionItem> {
do_completion(code, CompletionKind::Reference)
use crate::completion::{test_utils::completion_list, CompletionKind};
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(ra_fixture, CompletionKind::Reference);
expect.assert_eq(&actual)
}
#[test]
fn completes_enum_variants_and_modules() {
let completions = complete(
r"
enum E { X }
use self::E::X;
const Z: E = E::X;
mod m {}
check(
r#"
enum E { X }
use self::E::X;
const Z: E = E::X;
mod m {}
static FOO: E = E::X;
struct Bar { f: u32 }
static FOO: E = E::X;
struct Bar { f: u32 }
fn foo() {
match E::X {
<|>
}
}
",
fn foo() {
match E::X { <|> }
}
"#,
expect![[r#"
st Bar
en E
ev X ()
ct Z
md m
"#]],
);
assert_debug_snapshot!(completions, @r###"
[
CompletionItem {
label: "Bar",
source_range: 137..137,
delete: 137..137,
insert: "Bar",
kind: Struct,
},
CompletionItem {
label: "E",
source_range: 137..137,
delete: 137..137,
insert: "E",
kind: Enum,
},
CompletionItem {
label: "X",
source_range: 137..137,
delete: 137..137,
insert: "X",
kind: EnumVariant,
detail: "()",
},
CompletionItem {
label: "Z",
source_range: 137..137,
delete: 137..137,
insert: "Z",
kind: Const,
},
CompletionItem {
label: "m",
source_range: 137..137,
delete: 137..137,
insert: "m",
kind: Module,
},
]
"###);
}
#[test]
fn completes_in_simple_macro_call() {
let completions = complete(
r"
macro_rules! m { ($e:expr) => { $e } }
enum E { X }
check(
r#"
macro_rules! m { ($e:expr) => { $e } }
enum E { X }
fn foo() {
m!(match E::X {
<|>
})
}
",
fn foo() {
m!(match E::X { <|> })
}
"#,
expect![[r#"
en E
ma m!() macro_rules! m
"#]],
);
assert_debug_snapshot!(completions, @r###"
[
CompletionItem {
label: "E",
source_range: 90..90,
delete: 90..90,
insert: "E",
kind: Enum,
},
CompletionItem {
label: "m!(…)",
source_range: 90..90,
delete: 90..90,
insert: "m!($0)",
kind: Macro,
lookup: "m!",
detail: "macro_rules! m",
},
]
"###);
}
}

View file

@ -8,14 +8,13 @@ use ra_text_edit::TextEdit;
use crate::{
completion::{
completion_config::SnippetCap,
completion_context::CompletionContext,
completion_item::{Builder, CompletionKind, Completions},
},
CompletionItem,
CompletionItem, CompletionItemKind,
};
use super::completion_config::SnippetCap;
pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
if !ctx.config.enable_postfix_completions {
return;
@ -103,10 +102,9 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
&format!("while {} {{\n $0\n}}", receiver_text),
)
.add_to(acc);
postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text))
.add_to(acc);
}
// !&&&42 is a compiler error, ergo process it before considering the references
postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text))
.add_to(acc);
postfix_snippet(ctx, cap, &dot_receiver, "ref", "&expr", &format!("&{}", receiver_text))
.add_to(acc);
@ -125,33 +123,35 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
let dot_receiver = include_references(dot_receiver);
let receiver_text =
get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal);
match try_enum {
Some(try_enum) => {
match try_enum {
TryEnum::Result => {
postfix_snippet(
Some(try_enum) => match try_enum {
TryEnum::Result => {
postfix_snippet(
ctx,
cap,
&dot_receiver,
"match",
"match expr {}",
&format!("match {} {{\n Ok(${{1:_}}) => {{$2\\}},\n Err(${{3:_}}) => {{$0\\}},\n}}", receiver_text),
&format!("match {} {{\n Ok(${{1:_}}) => {{$2}},\n Err(${{3:_}}) => {{$0}},\n}}", receiver_text),
)
.add_to(acc);
}
TryEnum::Option => {
postfix_snippet(
ctx,
cap,
&dot_receiver,
"match",
"match expr {}",
&format!("match {} {{\n Some(${{1:_}}) => {{$2\\}},\n None => {{$0\\}},\n}}", receiver_text),
)
.add_to(acc);
}
}
}
TryEnum::Option => {
postfix_snippet(
ctx,
cap,
&dot_receiver,
"match",
"match expr {}",
&format!(
"match {} {{\n Some(${{1:_}}) => {{$2}},\n None => {{$0}},\n}}",
receiver_text
),
)
.add_to(acc);
}
},
None => {
postfix_snippet(
ctx,
@ -159,7 +159,7 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
&dot_receiver,
"match",
"match expr {}",
&format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text),
&format!("match {} {{\n ${{1:_}} => {{$0}},\n}}", receiver_text),
)
.add_to(acc);
}
@ -232,536 +232,147 @@ fn postfix_snippet(
};
CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
.detail(detail)
.kind(CompletionItemKind::Snippet)
.snippet_edit(cap, edit)
}
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use expect::{expect, Expect};
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
use crate::completion::{
test_utils::{check_edit, completion_list},
CompletionKind,
};
fn do_postfix_completion(code: &str) -> Vec<CompletionItem> {
do_completion(code, CompletionKind::Postfix)
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(ra_fixture, CompletionKind::Postfix);
expect.assert_eq(&actual)
}
#[test]
fn postfix_completion_works_for_trivial_path_expression() {
assert_debug_snapshot!(
do_postfix_completion(
r#"
fn main() {
let bar = true;
bar.<|>
}
"#,
),
@r###"
[
CompletionItem {
label: "box",
source_range: 40..40,
delete: 36..40,
insert: "Box::new(bar)",
detail: "Box::new(expr)",
},
CompletionItem {
label: "call",
source_range: 40..40,
delete: 36..40,
insert: "${1}(bar)",
detail: "function(expr)",
},
CompletionItem {
label: "dbg",
source_range: 40..40,
delete: 36..40,
insert: "dbg!(bar)",
detail: "dbg!(expr)",
},
CompletionItem {
label: "if",
source_range: 40..40,
delete: 36..40,
insert: "if bar {\n $0\n}",
detail: "if expr {}",
},
CompletionItem {
label: "match",
source_range: 40..40,
delete: 36..40,
insert: "match bar {\n ${1:_} => {$0\\},\n}",
detail: "match expr {}",
},
CompletionItem {
label: "not",
source_range: 40..40,
delete: 36..40,
insert: "!bar",
detail: "!expr",
},
CompletionItem {
label: "ref",
source_range: 40..40,
delete: 36..40,
insert: "&bar",
detail: "&expr",
},
CompletionItem {
label: "refm",
source_range: 40..40,
delete: 36..40,
insert: "&mut bar",
detail: "&mut expr",
},
CompletionItem {
label: "while",
source_range: 40..40,
delete: 36..40,
insert: "while bar {\n $0\n}",
detail: "while expr {}",
},
]
"###
check(
r#"
fn main() {
let bar = true;
bar.<|>
}
"#,
expect![[r#"
sn box Box::new(expr)
sn call function(expr)
sn dbg dbg!(expr)
sn if if expr {}
sn match match expr {}
sn not !expr
sn ref &expr
sn refm &mut expr
sn while while expr {}
"#]],
);
}
#[test]
fn postfix_completion_works_for_option() {
assert_debug_snapshot!(
do_postfix_completion(
r#"
enum Option<T> {
Some(T),
None,
}
fn postfix_type_filtering() {
check(
r#"
fn main() {
let bar: u8 = 12;
bar.<|>
}
"#,
expect![[r#"
sn box Box::new(expr)
sn call function(expr)
sn dbg dbg!(expr)
sn match match expr {}
sn ref &expr
sn refm &mut expr
"#]],
)
}
fn main() {
let bar = Option::Some(true);
bar.<|>
}
"#,
),
@r###"
[
CompletionItem {
label: "box",
source_range: 97..97,
delete: 93..97,
insert: "Box::new(bar)",
detail: "Box::new(expr)",
},
CompletionItem {
label: "call",
source_range: 97..97,
delete: 93..97,
insert: "${1}(bar)",
detail: "function(expr)",
},
CompletionItem {
label: "dbg",
source_range: 97..97,
delete: 93..97,
insert: "dbg!(bar)",
detail: "dbg!(expr)",
},
CompletionItem {
label: "ifl",
source_range: 97..97,
delete: 93..97,
insert: "if let Some($1) = bar {\n $0\n}",
detail: "if let Some {}",
},
CompletionItem {
label: "match",
source_range: 97..97,
delete: 93..97,
insert: "match bar {\n Some(${1:_}) => {$2\\},\n None => {$0\\},\n}",
detail: "match expr {}",
},
CompletionItem {
label: "not",
source_range: 97..97,
delete: 93..97,
insert: "!bar",
detail: "!expr",
},
CompletionItem {
label: "ref",
source_range: 97..97,
delete: 93..97,
insert: "&bar",
detail: "&expr",
},
CompletionItem {
label: "refm",
source_range: 97..97,
delete: 93..97,
insert: "&mut bar",
detail: "&mut expr",
},
CompletionItem {
label: "while",
source_range: 97..97,
delete: 93..97,
insert: "while let Some($1) = bar {\n $0\n}",
detail: "while let Some {}",
},
]
"###
#[test]
fn option_iflet() {
check_edit(
"ifl",
r#"
enum Option<T> { Some(T), None }
fn main() {
let bar = Option::Some(true);
bar.<|>
}
"#,
r#"
enum Option<T> { Some(T), None }
fn main() {
let bar = Option::Some(true);
if let Some($1) = bar {
$0
}
}
"#,
);
}
#[test]
fn postfix_completion_works_for_result() {
assert_debug_snapshot!(
do_postfix_completion(
r#"
enum Result<T, E> {
Ok(T),
Err(E),
}
fn result_match() {
check_edit(
"match",
r#"
enum Result<T, E> { Ok(T), Err(E) }
fn main() {
let bar = Result::Ok(true);
bar.<|>
}
"#,
),
@r###"
[
CompletionItem {
label: "box",
source_range: 98..98,
delete: 94..98,
insert: "Box::new(bar)",
detail: "Box::new(expr)",
},
CompletionItem {
label: "call",
source_range: 98..98,
delete: 94..98,
insert: "${1}(bar)",
detail: "function(expr)",
},
CompletionItem {
label: "dbg",
source_range: 98..98,
delete: 94..98,
insert: "dbg!(bar)",
detail: "dbg!(expr)",
},
CompletionItem {
label: "ifl",
source_range: 98..98,
delete: 94..98,
insert: "if let Ok($1) = bar {\n $0\n}",
detail: "if let Ok {}",
},
CompletionItem {
label: "match",
source_range: 98..98,
delete: 94..98,
insert: "match bar {\n Ok(${1:_}) => {$2\\},\n Err(${3:_}) => {$0\\},\n}",
detail: "match expr {}",
},
CompletionItem {
label: "not",
source_range: 98..98,
delete: 94..98,
insert: "!bar",
detail: "!expr",
},
CompletionItem {
label: "ref",
source_range: 98..98,
delete: 94..98,
insert: "&bar",
detail: "&expr",
},
CompletionItem {
label: "refm",
source_range: 98..98,
delete: 94..98,
insert: "&mut bar",
detail: "&mut expr",
},
CompletionItem {
label: "while",
source_range: 98..98,
delete: 94..98,
insert: "while let Ok($1) = bar {\n $0\n}",
detail: "while let Ok {}",
},
]
"###
);
}
fn main() {
let bar = Result::Ok(true);
bar.<|>
}
"#,
r#"
enum Result<T, E> { Ok(T), Err(E) }
#[test]
fn some_postfix_completions_ignored() {
assert_debug_snapshot!(
do_postfix_completion(
r#"
fn main() {
let bar: u8 = 12;
bar.<|>
}
"#,
),
@r###"
[
CompletionItem {
label: "box",
source_range: 42..42,
delete: 38..42,
insert: "Box::new(bar)",
detail: "Box::new(expr)",
},
CompletionItem {
label: "call",
source_range: 42..42,
delete: 38..42,
insert: "${1}(bar)",
detail: "function(expr)",
},
CompletionItem {
label: "dbg",
source_range: 42..42,
delete: 38..42,
insert: "dbg!(bar)",
detail: "dbg!(expr)",
},
CompletionItem {
label: "match",
source_range: 42..42,
delete: 38..42,
insert: "match bar {\n ${1:_} => {$0\\},\n}",
detail: "match expr {}",
},
CompletionItem {
label: "not",
source_range: 42..42,
delete: 38..42,
insert: "!bar",
detail: "!expr",
},
CompletionItem {
label: "ref",
source_range: 42..42,
delete: 38..42,
insert: "&bar",
detail: "&expr",
},
CompletionItem {
label: "refm",
source_range: 42..42,
delete: 38..42,
insert: "&mut bar",
detail: "&mut expr",
},
]
"###
fn main() {
let bar = Result::Ok(true);
match bar {
Ok(${1:_}) => {$2},
Err(${3:_}) => {$0},
}
}
"#,
);
}
#[test]
fn postfix_completion_works_for_ambiguous_float_literal() {
assert_debug_snapshot!(
do_postfix_completion(
r#"
fn main() {
42.<|>
}
"#,
),
@r###"
[
CompletionItem {
label: "box",
source_range: 19..19,
delete: 16..19,
insert: "Box::new(42)",
detail: "Box::new(expr)",
},
CompletionItem {
label: "call",
source_range: 19..19,
delete: 16..19,
insert: "${1}(42)",
detail: "function(expr)",
},
CompletionItem {
label: "dbg",
source_range: 19..19,
delete: 16..19,
insert: "dbg!(42)",
detail: "dbg!(expr)",
},
CompletionItem {
label: "match",
source_range: 19..19,
delete: 16..19,
insert: "match 42 {\n ${1:_} => {$0\\},\n}",
detail: "match expr {}",
},
CompletionItem {
label: "not",
source_range: 19..19,
delete: 16..19,
insert: "!42",
detail: "!expr",
},
CompletionItem {
label: "ref",
source_range: 19..19,
delete: 16..19,
insert: "&42",
detail: "&expr",
},
CompletionItem {
label: "refm",
source_range: 19..19,
delete: 16..19,
insert: "&mut 42",
detail: "&mut expr",
},
]
"###
);
check_edit("refm", r#"fn main() { 42.<|> }"#, r#"fn main() { &mut 42 }"#)
}
#[test]
fn works_in_simple_macro() {
assert_debug_snapshot!(
do_postfix_completion(
r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() {
let bar: u8 = 12;
m!(bar.b<|>)
}
"#,
),
@r###"
[
CompletionItem {
label: "box",
source_range: 84..85,
delete: 80..85,
insert: "Box::new(bar)",
detail: "Box::new(expr)",
},
CompletionItem {
label: "call",
source_range: 84..85,
delete: 80..85,
insert: "${1}(bar)",
detail: "function(expr)",
},
CompletionItem {
label: "dbg",
source_range: 84..85,
delete: 80..85,
insert: "dbg!(bar)",
detail: "dbg!(expr)",
},
CompletionItem {
label: "match",
source_range: 84..85,
delete: 80..85,
insert: "match bar {\n ${1:_} => {$0\\},\n}",
detail: "match expr {}",
},
CompletionItem {
label: "not",
source_range: 84..85,
delete: 80..85,
insert: "!bar",
detail: "!expr",
},
CompletionItem {
label: "ref",
source_range: 84..85,
delete: 80..85,
insert: "&bar",
detail: "&expr",
},
CompletionItem {
label: "refm",
source_range: 84..85,
delete: 80..85,
insert: "&mut bar",
detail: "&mut expr",
},
]
"###
check_edit(
"dbg",
r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() {
let bar: u8 = 12;
m!(bar.d<|>)
}
"#,
r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() {
let bar: u8 = 12;
m!(dbg!(bar))
}
"#,
);
}
#[test]
fn postfix_completion_for_references() {
assert_debug_snapshot!(
do_postfix_completion(
r#"
fn main() {
&&&&42.<|>
}
"#,
),
@r###"
[
CompletionItem {
label: "box",
source_range: 23..23,
delete: 16..23,
insert: "Box::new(&&&&42)",
detail: "Box::new(expr)",
},
CompletionItem {
label: "call",
source_range: 23..23,
delete: 16..23,
insert: "${1}(&&&&42)",
detail: "function(expr)",
},
CompletionItem {
label: "dbg",
source_range: 23..23,
delete: 16..23,
insert: "dbg!(&&&&42)",
detail: "dbg!(expr)",
},
CompletionItem {
label: "match",
source_range: 23..23,
delete: 16..23,
insert: "match &&&&42 {\n ${1:_} => {$0\\},\n}",
detail: "match expr {}",
},
CompletionItem {
label: "not",
source_range: 23..23,
delete: 20..23,
insert: "!42",
detail: "!expr",
},
CompletionItem {
label: "ref",
source_range: 23..23,
delete: 20..23,
insert: "&42",
detail: "&expr",
},
CompletionItem {
label: "refm",
source_range: 23..23,
delete: 20..23,
insert: "&mut 42",
detail: "&mut expr",
},
]
"###
);
check_edit("dbg", r#"fn main() { &&42.<|> }"#, r#"fn main() { dbg!(&&42) }"#);
check_edit("refm", r#"fn main() { &&42.<|> }"#, r#"fn main() { &&&mut 42 }"#);
}
}