Modernize completion presentation tests

This commit is contained in:
Aleksey Kladov 2020-07-04 09:35:44 +02:00
parent 65768feaff
commit aaba2300fb

View File

@ -330,14 +330,14 @@ pub(crate) fn compute_score(
// FIXME: this should not fall back to string equality. // FIXME: this should not fall back to string equality.
let ty = &ty.display(ctx.db).to_string(); let ty = &ty.display(ctx.db).to_string();
let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax {
mark::hit!(test_struct_field_completion_in_record_lit); mark::hit!(record_field_type_match);
let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?; let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?;
( (
struct_field.name(ctx.db).to_string(), struct_field.name(ctx.db).to_string(),
struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), struct_field.signature_ty(ctx.db).display(ctx.db).to_string(),
) )
} else if let Some(active_parameter) = &ctx.active_parameter { } else if let Some(active_parameter) = &ctx.active_parameter {
mark::hit!(test_struct_field_completion_in_func_call); mark::hit!(active_param_type_match);
(active_parameter.name.clone(), active_parameter.ty.clone()) (active_parameter.name.clone(), active_parameter.ty.clone())
} else { } else {
return None; return None;
@ -461,63 +461,56 @@ fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static s
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use insta::assert_debug_snapshot; use expect::{expect, Expect};
use test_utils::mark; use test_utils::mark;
use crate::completion::{ use crate::completion::{
test_utils::{check_edit, check_edit_with_config, do_completion}, test_utils::{check_edit, check_edit_with_config, do_completion},
CompletionConfig, CompletionItem, CompletionKind, CompletionConfig, CompletionKind,
}; };
fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> { fn check(ra_fixture: &str, expect: Expect) {
do_completion(ra_fixture, CompletionKind::Reference) let actual = do_completion(ra_fixture, CompletionKind::Reference);
expect.assert_debug_eq(&actual);
} }
#[test] #[test]
fn enum_detail_includes_names_for_record() { fn enum_detail_includes_record_fields() {
assert_debug_snapshot!( check(
do_reference_completion(
r#" r#"
enum Foo { enum Foo { Foo { x: i32, y: i32 } }
Foo {x: i32, y: i32}
}
fn main() { Foo::Fo<|> } fn main() { Foo::Fo<|> }
"#, "#,
), expect![[r#"
@r###"
[ [
CompletionItem { CompletionItem {
label: "Foo", label: "Foo",
source_range: 56..58, source_range: 54..56,
delete: 56..58, delete: 54..56,
insert: "Foo", insert: "Foo",
kind: EnumVariant, kind: EnumVariant,
detail: "{ x: i32, y: i32 }", detail: "{ x: i32, y: i32 }",
}, },
] ]
"### "#]],
); );
} }
#[test] #[test]
fn enum_detail_doesnt_include_names_for_tuple() { fn enum_detail_doesnt_include_tuple_fields() {
assert_debug_snapshot!( check(
do_reference_completion(
r#" r#"
enum Foo { enum Foo { Foo (i32, i32) }
Foo (i32, i32)
}
fn main() { Foo::Fo<|> } fn main() { Foo::Fo<|> }
"#, "#,
), expect![[r#"
@r###"
[ [
CompletionItem { CompletionItem {
label: "Foo(…)", label: "Foo(…)",
source_range: 50..52, source_range: 46..48,
delete: 50..52, delete: 46..48,
insert: "Foo($0)", insert: "Foo($0)",
kind: EnumVariant, kind: EnumVariant,
lookup: "Foo", lookup: "Foo",
@ -525,57 +518,50 @@ mod tests {
trigger_call_info: true, trigger_call_info: true,
}, },
] ]
"### "#]],
); );
} }
#[test] #[test]
fn enum_detail_just_parentheses_for_unit() { fn enum_detail_just_parentheses_for_unit() {
assert_debug_snapshot!( check(
do_reference_completion(
r#" r#"
enum Foo { enum Foo { Foo }
Foo
}
fn main() { Foo::Fo<|> } fn main() { Foo::Fo<|> }
"#, "#,
), expect![[r#"
@r###"
[ [
CompletionItem { CompletionItem {
label: "Foo", label: "Foo",
source_range: 39..41, source_range: 35..37,
delete: 39..41, delete: 35..37,
insert: "Foo", insert: "Foo",
kind: EnumVariant, kind: EnumVariant,
detail: "()", detail: "()",
}, },
] ]
"### "#]],
); );
} }
#[test] #[test]
fn sets_deprecated_flag_in_completion_items() { fn sets_deprecated_flag_in_completion_items() {
assert_debug_snapshot!( check(
do_reference_completion(
r#" r#"
#[deprecated] #[deprecated]
fn something_deprecated() {} fn something_deprecated() {}
#[deprecated(since = "1.0.0")] #[deprecated(since = "1.0.0")]
fn something_else_deprecated() {} fn something_else_deprecated() {}
fn main() { som<|> } fn main() { som<|> }
"#, "#,
), expect![[r#"
@r###"
[ [
CompletionItem { CompletionItem {
label: "main()", label: "main()",
source_range: 122..125, source_range: 121..124,
delete: 122..125, delete: 121..124,
insert: "main()$0", insert: "main()$0",
kind: Function, kind: Function,
lookup: "main", lookup: "main",
@ -583,8 +569,8 @@ mod tests {
}, },
CompletionItem { CompletionItem {
label: "something_deprecated()", label: "something_deprecated()",
source_range: 122..125, source_range: 121..124,
delete: 122..125, delete: 121..124,
insert: "something_deprecated()$0", insert: "something_deprecated()$0",
kind: Function, kind: Function,
lookup: "something_deprecated", lookup: "something_deprecated",
@ -593,8 +579,8 @@ mod tests {
}, },
CompletionItem { CompletionItem {
label: "something_else_deprecated()", label: "something_else_deprecated()",
source_range: 122..125, source_range: 121..124,
delete: 122..125, delete: 121..124,
insert: "something_else_deprecated()$0", insert: "something_else_deprecated()$0",
kind: Function, kind: Function,
lookup: "something_else_deprecated", lookup: "something_else_deprecated",
@ -602,33 +588,28 @@ mod tests {
deprecated: true, deprecated: true,
}, },
] ]
"### "#]],
); );
assert_debug_snapshot!(do_reference_completion( check(
r#" r#"
struct A { struct A { #[deprecated] the_field: u32 }
#[deprecated] fn foo() { A { the<|> } }
the_field: u32,
}
fn foo() {
A { the<|> }
}
"#, "#,
), expect![[r#"
@r###"
[ [
CompletionItem { CompletionItem {
label: "the_field", label: "the_field",
source_range: 69..72, source_range: 57..60,
delete: 69..72, delete: 57..60,
insert: "the_field", insert: "the_field",
kind: Field, kind: Field,
detail: "u32", detail: "u32",
deprecated: true, deprecated: true,
}, },
] ]
"###); "#]],
);
} }
#[test] #[test]
@ -921,262 +902,228 @@ fn main() { frobnicate!(); }
} }
#[test] #[test]
fn test_struct_field_completion_in_func_call() { fn active_param_type_match() {
mark::check!(test_struct_field_completion_in_func_call); mark::check!(active_param_type_match);
assert_debug_snapshot!( check(
do_reference_completion( r#"
r" struct S { foo: i64, bar: u32, baz: () }
struct A { another_field: i64, the_field: u32, my_string: String } fn test(x: u32) { }
fn test(my_param: u32) -> u32 { my_param } fn foo(s: S) { test(s.<|>) }
fn foo(a: A) { "#,
test(a.<|>) expect![[r#"
}
",
),
@r###"
[ [
CompletionItem { CompletionItem {
label: "another_field", label: "bar",
source_range: 136..136, source_range: 83..83,
delete: 136..136, delete: 83..83,
insert: "another_field", insert: "bar",
kind: Field,
detail: "i64",
},
CompletionItem {
label: "my_string",
source_range: 136..136,
delete: 136..136,
insert: "my_string",
kind: Field,
detail: "{unknown}",
},
CompletionItem {
label: "the_field",
source_range: 136..136,
delete: 136..136,
insert: "the_field",
kind: Field, kind: Field,
detail: "u32", detail: "u32",
score: TypeMatch, score: TypeMatch,
}, },
CompletionItem {
label: "baz",
source_range: 83..83,
delete: 83..83,
insert: "baz",
kind: Field,
detail: "()",
},
CompletionItem {
label: "foo",
source_range: 83..83,
delete: 83..83,
insert: "foo",
kind: Field,
detail: "i64",
},
] ]
"### "#]],
); );
} }
#[test] #[test]
fn test_struct_field_completion_in_func_call_with_type_and_name() { fn active_param_type_and_name_match() {
assert_debug_snapshot!( check(
do_reference_completion( r#"
r" struct S { foo: i64, bar: u32, baz: u32 }
struct A { another_field: i64, another_good_type: u32, the_field: u32 } fn test(bar: u32) { }
fn test(the_field: u32) -> u32 { the_field } fn foo(s: S) { test(s.<|>) }
fn foo(a: A) { "#,
test(a.<|>) expect![[r#"
}
",
),
@r###"
[ [
CompletionItem { CompletionItem {
label: "another_field", label: "bar",
source_range: 143..143, source_range: 86..86,
delete: 143..143, delete: 86..86,
insert: "another_field", insert: "bar",
kind: Field,
detail: "i64",
},
CompletionItem {
label: "another_good_type",
source_range: 143..143,
delete: 143..143,
insert: "another_good_type",
kind: Field,
detail: "u32",
score: TypeMatch,
},
CompletionItem {
label: "the_field",
source_range: 143..143,
delete: 143..143,
insert: "the_field",
kind: Field, kind: Field,
detail: "u32", detail: "u32",
score: TypeAndNameMatch, score: TypeAndNameMatch,
}, },
]
"###
);
}
#[test]
fn test_struct_field_completion_in_record_lit() {
mark::check!(test_struct_field_completion_in_record_lit);
assert_debug_snapshot!(
do_reference_completion(
r"
struct A { another_field: i64, another_good_type: u32, the_field: u32 }
struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
fn foo(a: A) {
let b = B {
the_field: a.<|>
};
}
",
),
@r###"
[
CompletionItem { CompletionItem {
label: "another_field", label: "baz",
source_range: 189..189, source_range: 86..86,
delete: 189..189, delete: 86..86,
insert: "another_field", insert: "baz",
kind: Field,
detail: "i64",
},
CompletionItem {
label: "another_good_type",
source_range: 189..189,
delete: 189..189,
insert: "another_good_type",
kind: Field, kind: Field,
detail: "u32", detail: "u32",
score: TypeMatch, score: TypeMatch,
}, },
CompletionItem { CompletionItem {
label: "the_field", label: "foo",
source_range: 189..189, source_range: 86..86,
delete: 189..189, delete: 86..86,
insert: "the_field", insert: "foo",
kind: Field,
detail: "i64",
},
]
"#]],
);
}
#[test]
fn record_field_type_match() {
mark::check!(record_field_type_match);
check(
r#"
struct A { foo: i64, bar: u32, baz: u32 }
struct B { x: (), y: f32, bar: u32 }
fn foo(a: A) { B { bar: a.<|> }; }
"#,
expect![[r#"
[
CompletionItem {
label: "bar",
source_range: 105..105,
delete: 105..105,
insert: "bar",
kind: Field, kind: Field,
detail: "u32", detail: "u32",
score: TypeAndNameMatch, score: TypeAndNameMatch,
}, },
]
"###
);
}
#[test]
fn test_struct_field_completion_in_record_lit_and_fn_call() {
assert_debug_snapshot!(
do_reference_completion(
r"
struct A { another_field: i64, another_good_type: u32, the_field: u32 }
struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
fn test(the_field: i64) -> i64 { the_field }
fn foo(a: A) {
let b = B {
the_field: test(a.<|>)
};
}
",
),
@r###"
[
CompletionItem { CompletionItem {
label: "another_field", label: "baz",
source_range: 239..239, source_range: 105..105,
delete: 239..239, delete: 105..105,
insert: "another_field", insert: "baz",
kind: Field,
detail: "i64",
score: TypeMatch,
},
CompletionItem {
label: "another_good_type",
source_range: 239..239,
delete: 239..239,
insert: "another_good_type",
kind: Field,
detail: "u32",
},
CompletionItem {
label: "the_field",
source_range: 239..239,
delete: 239..239,
insert: "the_field",
kind: Field,
detail: "u32",
},
]
"###
);
}
#[test]
fn test_struct_field_completion_in_fn_call_and_record_lit() {
assert_debug_snapshot!(
do_reference_completion(
r"
struct A { another_field: i64, another_good_type: u32, the_field: u32 }
struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
fn test(the_field: i64) -> i64 { the_field }
fn foo(a: A) {
test(B {
the_field: a.<|>
});
}
",
),
@r###"
[
CompletionItem {
label: "another_field",
source_range: 231..231,
delete: 231..231,
insert: "another_field",
kind: Field,
detail: "i64",
},
CompletionItem {
label: "another_good_type",
source_range: 231..231,
delete: 231..231,
insert: "another_good_type",
kind: Field, kind: Field,
detail: "u32", detail: "u32",
score: TypeMatch, score: TypeMatch,
}, },
CompletionItem { CompletionItem {
label: "the_field", label: "foo",
source_range: 231..231, source_range: 105..105,
delete: 231..231, delete: 105..105,
insert: "the_field", insert: "foo",
kind: Field,
detail: "i64",
},
]
"#]],
)
}
#[test]
fn record_field_type_match_and_fn_call() {
check(
r#"
struct A { foo: i64, bar: u32, baz: u32 }
struct B { x: (), y: f32, bar: u32 }
fn f(foo: i64) { }
fn foo(a: A) { B { bar: f(a.<|>) }; }
"#,
expect![[r#"
[
CompletionItem {
label: "bar",
source_range: 127..127,
delete: 127..127,
insert: "bar",
kind: Field,
detail: "u32",
},
CompletionItem {
label: "baz",
source_range: 127..127,
delete: 127..127,
insert: "baz",
kind: Field,
detail: "u32",
},
CompletionItem {
label: "foo",
source_range: 127..127,
delete: 127..127,
insert: "foo",
kind: Field,
detail: "i64",
score: TypeAndNameMatch,
},
]
"#]],
);
check(
r#"
struct A { foo: i64, bar: u32, baz: u32 }
struct B { x: (), y: f32, bar: u32 }
fn f(foo: i64) { }
fn foo(a: A) { f(B { bar: a.<|> }); }
"#,
expect![[r#"
[
CompletionItem {
label: "bar",
source_range: 127..127,
delete: 127..127,
insert: "bar",
kind: Field, kind: Field,
detail: "u32", detail: "u32",
score: TypeAndNameMatch, score: TypeAndNameMatch,
}, },
CompletionItem {
label: "baz",
source_range: 127..127,
delete: 127..127,
insert: "baz",
kind: Field,
detail: "u32",
score: TypeMatch,
},
CompletionItem {
label: "foo",
source_range: 127..127,
delete: 127..127,
insert: "foo",
kind: Field,
detail: "i64",
},
] ]
"### "#]],
); );
} }
#[test] #[test]
fn prioritize_exact_ref_match() { fn prioritize_exact_ref_match() {
assert_debug_snapshot!( check(
do_reference_completion( r#"
r"
struct WorldSnapshot { _f: () }; struct WorldSnapshot { _f: () };
fn go(world: &WorldSnapshot) { fn go(world: &WorldSnapshot) { go(w<|>) }
go(w<|>) "#,
} expect![[r#"
",
),
@r###"
[ [
CompletionItem { CompletionItem {
label: "WorldSnapshot", label: "WorldSnapshot",
source_range: 71..72, source_range: 67..68,
delete: 71..72, delete: 67..68,
insert: "WorldSnapshot", insert: "WorldSnapshot",
kind: Struct, kind: Struct,
}, },
CompletionItem { CompletionItem {
label: "go(…)", label: "go(…)",
source_range: 71..72, source_range: 67..68,
delete: 71..72, delete: 67..68,
insert: "go(${1:world})$0", insert: "go(${1:world})$0",
kind: Function, kind: Function,
lookup: "go", lookup: "go",
@ -1185,15 +1132,15 @@ fn main() { frobnicate!(); }
}, },
CompletionItem { CompletionItem {
label: "world", label: "world",
source_range: 71..72, source_range: 67..68,
delete: 71..72, delete: 67..68,
insert: "world", insert: "world",
kind: Binding, kind: Binding,
detail: "&WorldSnapshot", detail: "&WorldSnapshot",
score: TypeAndNameMatch, score: TypeAndNameMatch,
}, },
] ]
"### "#]],
); );
} }
} }