mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-17 02:08:30 +00:00
Merge #9675
9675: internal: Move and clean up record completion tests r=Veykril a=Veykril Now all that's left are the expression related tests which will take some time to go through bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
096e369698
6 changed files with 249 additions and 342 deletions
|
@ -47,98 +47,69 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::{
|
||||
tests::{check_edit, filtered_completion_list},
|
||||
CompletionKind,
|
||||
};
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference);
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
fn check_snippet(ra_fixture: &str, expect: Expect) {
|
||||
let actual = filtered_completion_list(ra_fixture, CompletionKind::Snippet);
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
use crate::tests::check_edit;
|
||||
|
||||
#[test]
|
||||
fn test_record_literal_field_default() {
|
||||
let test_code = r#"
|
||||
//- minicore: default
|
||||
struct S { foo: u32, bar: usize }
|
||||
|
||||
impl Default for S {
|
||||
fn default() -> Self {
|
||||
S {
|
||||
foo: 0,
|
||||
bar: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn process(f: S) {
|
||||
let other = S {
|
||||
foo: 5,
|
||||
.$0
|
||||
};
|
||||
}
|
||||
"#;
|
||||
check(
|
||||
test_code,
|
||||
expect![[r#"
|
||||
fd bar usize
|
||||
"#]],
|
||||
);
|
||||
|
||||
check_snippet(
|
||||
test_code,
|
||||
expect![[r#"
|
||||
fd ..Default::default()
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_literal_field_default_completion() {
|
||||
fn default_completion_edit() {
|
||||
check_edit(
|
||||
"..Default::default()",
|
||||
r#"
|
||||
//- minicore: default
|
||||
struct S { foo: u32, bar: usize }
|
||||
struct Struct { foo: u32, bar: usize }
|
||||
|
||||
impl Default for S {
|
||||
fn default() -> Self {
|
||||
S {
|
||||
foo: 0,
|
||||
bar: 0,
|
||||
}
|
||||
}
|
||||
impl Default for Struct {
|
||||
fn default() -> Self {}
|
||||
}
|
||||
|
||||
fn process(f: S) {
|
||||
let other = S {
|
||||
fn foo() {
|
||||
let other = Struct {
|
||||
foo: 5,
|
||||
.$0
|
||||
};
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
struct S { foo: u32, bar: usize }
|
||||
struct Struct { foo: u32, bar: usize }
|
||||
|
||||
impl Default for S {
|
||||
fn default() -> Self {
|
||||
S {
|
||||
foo: 0,
|
||||
bar: 0,
|
||||
}
|
||||
}
|
||||
impl Default for Struct {
|
||||
fn default() -> Self {}
|
||||
}
|
||||
|
||||
fn process(f: S) {
|
||||
let other = S {
|
||||
fn foo() {
|
||||
let other = Struct {
|
||||
foo: 5,
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
"#,
|
||||
);
|
||||
check_edit(
|
||||
"..Default::default()",
|
||||
r#"
|
||||
//- minicore: default
|
||||
struct Struct { foo: u32, bar: usize }
|
||||
|
||||
impl Default for Struct {
|
||||
fn default() -> Self {}
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let other = Struct {
|
||||
foo: 5,
|
||||
$0
|
||||
};
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
struct Struct { foo: u32, bar: usize }
|
||||
|
||||
impl Default for Struct {
|
||||
fn default() -> Self {}
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let other = Struct {
|
||||
foo: 5,
|
||||
..Default::default()
|
||||
};
|
||||
|
@ -146,223 +117,4 @@ fn process(f: S) {
|
|||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_literal_field_without_default() {
|
||||
let test_code = r#"
|
||||
struct S { foo: u32, bar: usize }
|
||||
|
||||
fn process(f: S) {
|
||||
let other = S {
|
||||
foo: 5,
|
||||
.$0
|
||||
};
|
||||
}
|
||||
"#;
|
||||
check(
|
||||
test_code,
|
||||
expect![[r#"
|
||||
fd bar usize
|
||||
"#]],
|
||||
);
|
||||
|
||||
check_snippet(test_code, expect![[r#""#]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_pattern_field() {
|
||||
check(
|
||||
r#"
|
||||
struct S { foo: u32 }
|
||||
|
||||
fn process(f: S) {
|
||||
match f {
|
||||
S { f$0: 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 { $0 } => (),
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd foo u32
|
||||
fd bar ()
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[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$0: 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, $0 } = 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$0 }
|
||||
}
|
||||
"#,
|
||||
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 { $0 }
|
||||
}
|
||||
"#,
|
||||
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 { $0 }
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd b u32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_literal_generic_struct() {
|
||||
check(
|
||||
r#"
|
||||
struct A<T> { a: T }
|
||||
|
||||
fn foo() {
|
||||
let _: A<u32> = A { $0 }
|
||||
}
|
||||
"#,
|
||||
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$0 })
|
||||
}
|
||||
"#,
|
||||
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, $0 }
|
||||
}
|
||||
"#,
|
||||
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, $0 .. loop {} }
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd foo2 u32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,10 +108,4 @@ mod tests {
|
|||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_complete_snippets_in_path() {
|
||||
check(r#"fn foo(x: i32) { ::foo$0 }"#, expect![[""]]);
|
||||
check(r#"fn foo(x: i32) { ::$0 }"#, expect![[""]]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,29 +299,6 @@ mod tests {
|
|||
expect.assert_eq(&actual)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn name_ref_function_type_const() {
|
||||
check(
|
||||
r#"
|
||||
trait Test {
|
||||
type TestType;
|
||||
const TEST_CONST: u16;
|
||||
fn test();
|
||||
}
|
||||
struct T;
|
||||
|
||||
impl Test for T {
|
||||
t$0
|
||||
}
|
||||
"#,
|
||||
expect![["
|
||||
ta type TestType = \n\
|
||||
ct const TEST_CONST: u16 = \n\
|
||||
fn fn test()
|
||||
"]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completion_inside_fn() {
|
||||
check(
|
||||
|
@ -572,27 +549,6 @@ impl Test for T {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hide_implemented_fn() {
|
||||
check(
|
||||
r#"
|
||||
trait Test {
|
||||
fn foo();
|
||||
fn foo_bar();
|
||||
}
|
||||
struct T;
|
||||
|
||||
impl Test for T {
|
||||
fn foo() {}
|
||||
fn f$0
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn fn foo_bar()
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_fn() {
|
||||
check_edit(
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
//! Most tests live in this module or its submodules unless for very specific completions like
|
||||
//! `attributes` or `lifetimes` where the completed concept is a distinct thing.
|
||||
//! Notable examples for completions that are being tested in this module's submodule are paths.
|
||||
//! Another exception are `check_edit` tests which usually live in the completion modules themselves,
|
||||
//! as the main purpose of this test module here is to give the developer an overview of whats being
|
||||
//! completed where, not how.
|
||||
|
||||
mod attribute;
|
||||
mod fn_param;
|
||||
|
@ -10,6 +13,7 @@ mod item_list;
|
|||
mod item;
|
||||
mod pattern;
|
||||
mod predicate;
|
||||
mod record;
|
||||
mod sourcegen;
|
||||
mod type_pos;
|
||||
mod use_tree;
|
||||
|
|
|
@ -210,3 +210,40 @@ fn in_trait_assoc_item_list() {
|
|||
"##]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn in_trait_impl_assoc_item_list() {
|
||||
check(
|
||||
r#"
|
||||
trait Test {
|
||||
type Type0;
|
||||
type Type1;
|
||||
const CONST0: ();
|
||||
const CONST1: ();
|
||||
fn function0();
|
||||
fn function1();
|
||||
}
|
||||
|
||||
impl Test for () {
|
||||
type Type0 = ();
|
||||
const CONST0: () = ();
|
||||
fn function0() {}
|
||||
$0
|
||||
}
|
||||
"#,
|
||||
expect![[r##"
|
||||
kw pub(crate)
|
||||
kw pub
|
||||
kw unsafe
|
||||
kw fn
|
||||
kw const
|
||||
kw type
|
||||
kw self
|
||||
kw super
|
||||
kw crate
|
||||
md module
|
||||
ma makro!(…) #[macro_export] macro_rules! makro
|
||||
ma makro!(…) #[macro_export] macro_rules! makro
|
||||
"##]],
|
||||
);
|
||||
}
|
||||
|
|
164
crates/ide_completion/src/tests/record.rs
Normal file
164
crates/ide_completion/src/tests/record.rs
Normal file
|
@ -0,0 +1,164 @@
|
|||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::tests::completion_list;
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let actual = completion_list(ra_fixture);
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_default_impl() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: default
|
||||
struct Struct { foo: u32, bar: usize }
|
||||
|
||||
impl Default for Struct {
|
||||
fn default() -> Self {
|
||||
Struct {
|
||||
foo: 0,
|
||||
bar: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let other = Struct {
|
||||
foo: 5,
|
||||
$0
|
||||
};
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd ..Default::default()
|
||||
fd bar usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn without_default_impl() {
|
||||
check(
|
||||
r#"
|
||||
struct Struct { foo: u32, bar: usize }
|
||||
|
||||
fn foo() {
|
||||
let other = Struct {
|
||||
foo: 5,
|
||||
$0
|
||||
};
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd bar usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn record_pattern_field() {
|
||||
check(
|
||||
r#"
|
||||
struct Struct { foo: u32, bar: u32 }
|
||||
|
||||
fn foo(s: Struct) {
|
||||
match s {
|
||||
Struct { foo, $0: 92 } => (),
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd bar u32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pattern_enum_variant() {
|
||||
check(
|
||||
r#"
|
||||
enum Enum { Variant { foo: u32, bar: u32 } }
|
||||
fn foo(e: Enum) {
|
||||
match e {
|
||||
Enum::Variant { foo, $0 } => (),
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd bar u32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn record_literal_field_in_macro() {
|
||||
check(
|
||||
r#"
|
||||
macro_rules! m { ($e:expr) => { $e } }
|
||||
struct Struct { field: u32 }
|
||||
fn foo() {
|
||||
m!(Struct { fie$0 })
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fd field u32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn record_pattern_field_in_macro() {
|
||||
check(
|
||||
r"
|
||||
macro_rules! m { ($e:expr) => { $e } }
|
||||
struct Struct { field: u32 }
|
||||
|
||||
fn foo(f: Struct) {
|
||||
m!(match f {
|
||||
Struct { f$0: 92 } => (),
|
||||
})
|
||||
}
|
||||
",
|
||||
expect![[r#"
|
||||
fd field u32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn functional_update() {
|
||||
// FIXME: This should filter out all completions that do not have the type `Foo`
|
||||
check(
|
||||
r#"
|
||||
struct Foo { foo1: u32, foo2: u32 }
|
||||
|
||||
fn main() {
|
||||
let thing = 1;
|
||||
let foo = Foo { foo1: 0, foo2: 0 };
|
||||
let foo2 = Foo { thing, ..$0 }
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
kw unsafe
|
||||
kw match
|
||||
kw while
|
||||
kw while let
|
||||
kw loop
|
||||
kw if
|
||||
kw if let
|
||||
kw for
|
||||
kw true
|
||||
kw false
|
||||
kw return
|
||||
kw self
|
||||
kw super
|
||||
kw crate
|
||||
lc foo Foo
|
||||
lc thing i32
|
||||
st Foo
|
||||
fn main() fn()
|
||||
bt u32
|
||||
"#]],
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue