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)] #[cfg(test)]
mod tests { mod tests {
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; use expect::{expect, Expect};
use insta::assert_debug_snapshot;
fn complete(code: &str) -> Vec<CompletionItem> { use crate::completion::{test_utils::completion_list, CompletionKind};
do_completion(code, CompletionKind::Reference)
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(ra_fixture, CompletionKind::Reference);
expect.assert_eq(&actual)
} }
#[test] #[test]
fn completes_enum_variants_and_modules() { fn completes_enum_variants_and_modules() {
let completions = complete( check(
r" r#"
enum E { X } enum E { X }
use self::E::X; use self::E::X;
const Z: E = E::X; const Z: E = E::X;
mod m {} mod m {}
static FOO: E = E::X; static FOO: E = E::X;
struct Bar { f: u32 } struct Bar { f: u32 }
fn foo() { fn foo() {
match E::X { 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] #[test]
fn completes_in_simple_macro_call() { fn completes_in_simple_macro_call() {
let completions = complete( check(
r" r#"
macro_rules! m { ($e:expr) => { $e } } macro_rules! m { ($e:expr) => { $e } }
enum E { X } enum E { X }
fn foo() { fn foo() {
m!(match E::X { 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::{ use crate::{
completion::{ completion::{
completion_config::SnippetCap,
completion_context::CompletionContext, completion_context::CompletionContext,
completion_item::{Builder, CompletionKind, Completions}, completion_item::{Builder, CompletionKind, Completions},
}, },
CompletionItem, CompletionItem, CompletionItemKind,
}; };
use super::completion_config::SnippetCap;
pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
if !ctx.config.enable_postfix_completions { if !ctx.config.enable_postfix_completions {
return; return;
@ -103,10 +102,9 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
&format!("while {} {{\n $0\n}}", receiver_text), &format!("while {} {{\n $0\n}}", receiver_text),
) )
.add_to(acc); .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)) postfix_snippet(ctx, cap, &dot_receiver, "ref", "&expr", &format!("&{}", receiver_text))
.add_to(acc); .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 dot_receiver = include_references(dot_receiver);
let receiver_text = let receiver_text =
get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal); get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal);
match try_enum { match try_enum {
Some(try_enum) => { Some(try_enum) => match try_enum {
match try_enum { TryEnum::Result => {
TryEnum::Result => { postfix_snippet(
postfix_snippet(
ctx, ctx,
cap, cap,
&dot_receiver, &dot_receiver,
"match", "match",
"match expr {}", "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); .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 => { None => {
postfix_snippet( postfix_snippet(
ctx, ctx,
@ -159,7 +159,7 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
&dot_receiver, &dot_receiver,
"match", "match",
"match expr {}", "match expr {}",
&format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text), &format!("match {} {{\n ${{1:_}} => {{$0}},\n}}", receiver_text),
) )
.add_to(acc); .add_to(acc);
} }
@ -232,536 +232,147 @@ fn postfix_snippet(
}; };
CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label) CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
.detail(detail) .detail(detail)
.kind(CompletionItemKind::Snippet)
.snippet_edit(cap, edit) .snippet_edit(cap, edit)
} }
#[cfg(test)] #[cfg(test)]
mod tests { 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> { fn check(ra_fixture: &str, expect: Expect) {
do_completion(code, CompletionKind::Postfix) let actual = completion_list(ra_fixture, CompletionKind::Postfix);
expect.assert_eq(&actual)
} }
#[test] #[test]
fn postfix_completion_works_for_trivial_path_expression() { fn postfix_completion_works_for_trivial_path_expression() {
assert_debug_snapshot!( check(
do_postfix_completion( r#"
r#" fn main() {
fn main() { let bar = true;
let bar = true; bar.<|>
bar.<|> }
} "#,
"#, expect![[r#"
), sn box Box::new(expr)
@r###" sn call function(expr)
[ sn dbg dbg!(expr)
CompletionItem { sn if if expr {}
label: "box", sn match match expr {}
source_range: 40..40, sn not !expr
delete: 36..40, sn ref &expr
insert: "Box::new(bar)", sn refm &mut expr
detail: "Box::new(expr)", sn while while 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 {}",
},
]
"###
); );
} }
#[test] #[test]
fn postfix_completion_works_for_option() { fn postfix_type_filtering() {
assert_debug_snapshot!( check(
do_postfix_completion( r#"
r#" fn main() {
enum Option<T> { let bar: u8 = 12;
Some(T), bar.<|>
None, }
} "#,
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() { #[test]
let bar = Option::Some(true); fn option_iflet() {
bar.<|> check_edit(
} "ifl",
"#, r#"
), enum Option<T> { Some(T), None }
@r###"
[ fn main() {
CompletionItem { let bar = Option::Some(true);
label: "box", bar.<|>
source_range: 97..97, }
delete: 93..97, "#,
insert: "Box::new(bar)", r#"
detail: "Box::new(expr)", enum Option<T> { Some(T), None }
},
CompletionItem { fn main() {
label: "call", let bar = Option::Some(true);
source_range: 97..97, if let Some($1) = bar {
delete: 93..97, $0
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] #[test]
fn postfix_completion_works_for_result() { fn result_match() {
assert_debug_snapshot!( check_edit(
do_postfix_completion( "match",
r#" r#"
enum Result<T, E> { enum Result<T, E> { Ok(T), Err(E) }
Ok(T),
Err(E),
}
fn main() { fn main() {
let bar = Result::Ok(true); let bar = Result::Ok(true);
bar.<|> bar.<|>
} }
"#, "#,
), r#"
@r###" enum Result<T, E> { Ok(T), Err(E) }
[
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 {}",
},
]
"###
);
}
#[test] fn main() {
fn some_postfix_completions_ignored() { let bar = Result::Ok(true);
assert_debug_snapshot!( match bar {
do_postfix_completion( Ok(${1:_}) => {$2},
r#" Err(${3:_}) => {$0},
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",
},
]
"###
); );
} }
#[test] #[test]
fn postfix_completion_works_for_ambiguous_float_literal() { fn postfix_completion_works_for_ambiguous_float_literal() {
assert_debug_snapshot!( check_edit("refm", r#"fn main() { 42.<|> }"#, r#"fn main() { &mut 42 }"#)
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",
},
]
"###
);
} }
#[test] #[test]
fn works_in_simple_macro() { fn works_in_simple_macro() {
assert_debug_snapshot!( check_edit(
do_postfix_completion( "dbg",
r#" r#"
macro_rules! m { ($e:expr) => { $e } } macro_rules! m { ($e:expr) => { $e } }
fn main() { fn main() {
let bar: u8 = 12; let bar: u8 = 12;
m!(bar.b<|>) m!(bar.d<|>)
} }
"#, "#,
), r#"
@r###" macro_rules! m { ($e:expr) => { $e } }
[ fn main() {
CompletionItem { let bar: u8 = 12;
label: "box", m!(dbg!(bar))
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",
},
]
"###
); );
} }
#[test] #[test]
fn postfix_completion_for_references() { fn postfix_completion_for_references() {
assert_debug_snapshot!( check_edit("dbg", r#"fn main() { &&42.<|> }"#, r#"fn main() { dbg!(&&42) }"#);
do_postfix_completion( check_edit("refm", r#"fn main() { &&42.<|> }"#, r#"fn main() { &&&mut 42 }"#);
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",
},
]
"###
);
} }
} }