Merge #9312
9312: internal: Move out item specific completion tests r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
3ae0c5911a
12 changed files with 242 additions and 171 deletions
|
|
@ -322,7 +322,7 @@ mod tests {
|
|||
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::{tests::filtered_completion_list, CompletionKind};
|
||||
use crate::tests::completion_list;
|
||||
|
||||
#[test]
|
||||
fn attributes_are_sorted() {
|
||||
|
|
@ -341,7 +341,7 @@ mod tests {
|
|||
}
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let actual = filtered_completion_list(ra_fixture, CompletionKind::Attribute);
|
||||
let actual = completion_list(ra_fixture);
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
|
|
@ -786,6 +786,7 @@ mod tests {
|
|||
at target_feature = "…"
|
||||
at test
|
||||
at track_caller
|
||||
kw return
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
@ -801,6 +802,7 @@ mod tests {
|
|||
at deny(…)
|
||||
at forbid(…)
|
||||
at warn(…)
|
||||
kw return
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ const DEFAULT_DERIVE_COMPLETIONS: &[DeriveDependencies] = &[
|
|||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::{tests::filtered_completion_list, CompletionKind};
|
||||
use crate::tests::completion_list;
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let builtin_derives = r#"
|
||||
|
|
@ -106,10 +106,7 @@ pub macro PartialOrd {}
|
|||
pub macro Ord {}
|
||||
|
||||
"#;
|
||||
let actual = filtered_completion_list(
|
||||
&format!("{} {}", builtin_derives, ra_fixture),
|
||||
CompletionKind::Attribute,
|
||||
);
|
||||
let actual = completion_list(&format!("{} {}", builtin_derives, ra_fixture));
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ pub(super) fn complete_lint(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use crate::tests::check_edit;
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -37,17 +37,6 @@ pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Suggest .await syntax for types that implement Future trait
|
||||
if let Some(receiver) = ctx.dot_receiver() {
|
||||
if let Some(ty) = ctx.sema.type_of_expr(receiver) {
|
||||
if ty.impls_future(ctx.db) {
|
||||
let mut item = kw_completion("await");
|
||||
item.detail("expr.await");
|
||||
item.add_to(acc);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
|
|
@ -59,6 +48,19 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
|||
cov_mark::hit!(no_keyword_completion_in_record_lit);
|
||||
return;
|
||||
}
|
||||
|
||||
// Suggest .await syntax for types that implement Future trait
|
||||
if let Some(receiver) = ctx.dot_receiver() {
|
||||
if let Some(ty) = ctx.sema.type_of_expr(receiver) {
|
||||
if ty.impls_future(ctx.db) {
|
||||
let mut item =
|
||||
CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await");
|
||||
item.kind(CompletionItemKind::Keyword).detail("expr.await");
|
||||
item.add_to(acc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let mut add_keyword = |kw, snippet| add_keyword(ctx, acc, kw, snippet);
|
||||
|
||||
let expects_assoc_item = ctx.expects_assoc_item();
|
||||
|
|
@ -67,6 +69,9 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
|||
|
||||
if ctx.has_impl_or_trait_prev_sibling() {
|
||||
add_keyword("where", "where ");
|
||||
if ctx.has_impl_prev_sibling() {
|
||||
add_keyword("for", "for ");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ctx.previous_token_is(T![unsafe]) {
|
||||
|
|
@ -385,22 +390,6 @@ fn quux() -> i32 {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_where_keyword() {
|
||||
check(
|
||||
r"trait A $0",
|
||||
expect![[r#"
|
||||
kw where
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r"impl A $0",
|
||||
expect![[r#"
|
||||
kw where
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_keyword_completion_in_comments() {
|
||||
cov_mark::check!(no_keyword_completion_in_comments);
|
||||
|
|
@ -477,22 +466,6 @@ fn foo() {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn before_field() {
|
||||
check(
|
||||
r#"
|
||||
struct Foo {
|
||||
$0
|
||||
pub f: i32,
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
kw pub(crate)
|
||||
kw pub
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skip_struct_initializer() {
|
||||
cov_mark::check!(no_keyword_completion_in_record_lit);
|
||||
|
|
|
|||
|
|
@ -49,19 +49,11 @@ pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
|
|||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::{
|
||||
tests::{check_edit, filtered_completion_list_with_config, TEST_CONFIG},
|
||||
CompletionConfig, CompletionKind,
|
||||
};
|
||||
use crate::tests::{check_edit, completion_list};
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
check_with_config(TEST_CONFIG, ra_fixture, expect);
|
||||
}
|
||||
|
||||
fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
|
||||
let actual =
|
||||
filtered_completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
|
||||
expect.assert_eq(&actual)
|
||||
let actual = completion_list(ra_fixture);
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -141,11 +141,11 @@ fn module_chain_to_containing_module_file(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{tests::filtered_completion_list, CompletionKind};
|
||||
use crate::tests::completion_list;
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let actual = filtered_completion_list(ra_fixture, CompletionKind::Magic);
|
||||
let actual = completion_list(ra_fixture);
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
|
|
@ -153,17 +153,17 @@ mod tests {
|
|||
fn lib_module_completion() {
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
mod $0
|
||||
//- /foo.rs
|
||||
fn foo() {}
|
||||
//- /foo/ignored_foo.rs
|
||||
fn ignored_foo() {}
|
||||
//- /bar/mod.rs
|
||||
fn bar() {}
|
||||
//- /bar/ignored_bar.rs
|
||||
fn ignored_bar() {}
|
||||
"#,
|
||||
//- /lib.rs
|
||||
mod $0
|
||||
//- /foo.rs
|
||||
fn foo() {}
|
||||
//- /foo/ignored_foo.rs
|
||||
fn ignored_foo() {}
|
||||
//- /bar/mod.rs
|
||||
fn bar() {}
|
||||
//- /bar/ignored_bar.rs
|
||||
fn ignored_bar() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
md foo;
|
||||
md bar;
|
||||
|
|
@ -175,13 +175,13 @@ mod tests {
|
|||
fn no_module_completion_with_module_body() {
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
mod $0 {
|
||||
//- /lib.rs
|
||||
mod $0 {
|
||||
|
||||
}
|
||||
//- /foo.rs
|
||||
fn foo() {}
|
||||
"#,
|
||||
}
|
||||
//- /foo.rs
|
||||
fn foo() {}
|
||||
"#,
|
||||
expect![[r#""#]],
|
||||
);
|
||||
}
|
||||
|
|
@ -190,17 +190,17 @@ mod tests {
|
|||
fn main_module_completion() {
|
||||
check(
|
||||
r#"
|
||||
//- /main.rs
|
||||
mod $0
|
||||
//- /foo.rs
|
||||
fn foo() {}
|
||||
//- /foo/ignored_foo.rs
|
||||
fn ignored_foo() {}
|
||||
//- /bar/mod.rs
|
||||
fn bar() {}
|
||||
//- /bar/ignored_bar.rs
|
||||
fn ignored_bar() {}
|
||||
"#,
|
||||
//- /main.rs
|
||||
mod $0
|
||||
//- /foo.rs
|
||||
fn foo() {}
|
||||
//- /foo/ignored_foo.rs
|
||||
fn ignored_foo() {}
|
||||
//- /bar/mod.rs
|
||||
fn bar() {}
|
||||
//- /bar/ignored_bar.rs
|
||||
fn ignored_bar() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
md foo;
|
||||
md bar;
|
||||
|
|
@ -212,13 +212,13 @@ mod tests {
|
|||
fn main_test_module_completion() {
|
||||
check(
|
||||
r#"
|
||||
//- /main.rs
|
||||
mod tests {
|
||||
mod $0;
|
||||
}
|
||||
//- /tests/foo.rs
|
||||
fn foo() {}
|
||||
"#,
|
||||
//- /main.rs
|
||||
mod tests {
|
||||
mod $0;
|
||||
}
|
||||
//- /tests/foo.rs
|
||||
fn foo() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
md foo
|
||||
"#]],
|
||||
|
|
@ -229,19 +229,19 @@ mod tests {
|
|||
fn directly_nested_module_completion() {
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
mod foo;
|
||||
//- /foo.rs
|
||||
mod $0;
|
||||
//- /foo/bar.rs
|
||||
fn bar() {}
|
||||
//- /foo/bar/ignored_bar.rs
|
||||
fn ignored_bar() {}
|
||||
//- /foo/baz/mod.rs
|
||||
fn baz() {}
|
||||
//- /foo/moar/ignored_moar.rs
|
||||
fn ignored_moar() {}
|
||||
"#,
|
||||
//- /lib.rs
|
||||
mod foo;
|
||||
//- /foo.rs
|
||||
mod $0;
|
||||
//- /foo/bar.rs
|
||||
fn bar() {}
|
||||
//- /foo/bar/ignored_bar.rs
|
||||
fn ignored_bar() {}
|
||||
//- /foo/baz/mod.rs
|
||||
fn baz() {}
|
||||
//- /foo/moar/ignored_moar.rs
|
||||
fn ignored_moar() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
md bar
|
||||
md baz
|
||||
|
|
@ -253,15 +253,15 @@ mod tests {
|
|||
fn nested_in_source_module_completion() {
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
mod foo;
|
||||
//- /foo.rs
|
||||
mod bar {
|
||||
mod $0
|
||||
}
|
||||
//- /foo/bar/baz.rs
|
||||
fn baz() {}
|
||||
"#,
|
||||
//- /lib.rs
|
||||
mod foo;
|
||||
//- /foo.rs
|
||||
mod bar {
|
||||
mod $0
|
||||
}
|
||||
//- /foo/bar/baz.rs
|
||||
fn baz() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
md baz;
|
||||
"#]],
|
||||
|
|
@ -299,16 +299,16 @@ mod tests {
|
|||
fn already_declared_bin_module_completion_omitted() {
|
||||
check(
|
||||
r#"
|
||||
//- /src/bin.rs crate:main
|
||||
fn main() {}
|
||||
//- /src/bin/foo.rs
|
||||
mod $0
|
||||
//- /src/bin/bar.rs
|
||||
mod foo;
|
||||
fn bar() {}
|
||||
//- /src/bin/bar/bar_ignored.rs
|
||||
fn bar_ignored() {}
|
||||
"#,
|
||||
//- /src/bin.rs crate:main
|
||||
fn main() {}
|
||||
//- /src/bin/foo.rs
|
||||
mod $0
|
||||
//- /src/bin/bar.rs
|
||||
mod foo;
|
||||
fn bar() {}
|
||||
//- /src/bin/bar/bar_ignored.rs
|
||||
fn bar_ignored() {}
|
||||
"#,
|
||||
expect![[r#""#]],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,26 +555,6 @@ fn f() {m::$0}
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_in_assoc_item_list() {
|
||||
check(
|
||||
r#"
|
||||
#[macro_export]
|
||||
macro_rules! foo { () => {} }
|
||||
mod bar {}
|
||||
|
||||
struct MyStruct {}
|
||||
impl MyStruct {
|
||||
crate::$0
|
||||
}
|
||||
"#,
|
||||
expect![[r##"
|
||||
md bar
|
||||
ma foo!(…) #[macro_export] macro_rules! foo
|
||||
"##]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_reexported_items_under_correct_name() {
|
||||
check(
|
||||
|
|
|
|||
|
|
@ -36,7 +36,11 @@ pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionConte
|
|||
}
|
||||
|
||||
pub(crate) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
if !ctx.expects_item() || ctx.previous_token_is(T![unsafe]) || ctx.path_qual().is_some() {
|
||||
if !ctx.expects_item()
|
||||
|| ctx.previous_token_is(T![unsafe])
|
||||
|| ctx.path_qual().is_some()
|
||||
|| ctx.has_impl_or_trait_prev_sibling()
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ctx.has_visibility_prev_sibling() {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use syntax::{ast, AstNode};
|
|||
use crate::{patterns::ImmediateLocation, CompletionContext, Completions};
|
||||
|
||||
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
if ctx.is_path_disallowed() || !ctx.is_trivial_path() {
|
||||
if ctx.is_path_disallowed() || !ctx.is_trivial_path() || ctx.has_impl_or_trait_prev_sibling() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -68,6 +68,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
|||
return;
|
||||
}
|
||||
let add_resolution = match res {
|
||||
ScopeDef::ImplSelfType(_) => {
|
||||
!ctx.previous_token_is(syntax::T![impl]) && !ctx.previous_token_is(syntax::T![for])
|
||||
}
|
||||
// Don't suggest attribute macros and derives.
|
||||
ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
||||
// no values in type places
|
||||
|
|
@ -712,23 +715,6 @@ fn f() {}
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_target_type_or_trait_in_impl_block() {
|
||||
check(
|
||||
r#"
|
||||
trait MyTrait {}
|
||||
struct MyStruct {}
|
||||
|
||||
impl My$0
|
||||
"#,
|
||||
expect![[r#"
|
||||
sp Self
|
||||
tt MyTrait
|
||||
st MyStruct
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_types_and_const_in_arg_list() {
|
||||
check(
|
||||
|
|
|
|||
|
|
@ -305,6 +305,10 @@ impl<'a> CompletionContext<'a> {
|
|||
)
|
||||
}
|
||||
|
||||
pub(crate) fn has_impl_prev_sibling(&self) -> bool {
|
||||
matches!(self.prev_sibling, Some(ImmediatePrevSibling::ImplDefType))
|
||||
}
|
||||
|
||||
pub(crate) fn has_visibility_prev_sibling(&self) -> bool {
|
||||
matches!(self.prev_sibling, Some(ImmediatePrevSibling::Visibility))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
//! Tests and test utilities for completions.
|
||||
//!
|
||||
//! 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.
|
||||
|
||||
mod item_list;
|
||||
mod use_tree;
|
||||
mod items;
|
||||
|
||||
use hir::{PrefixKind, Semantics};
|
||||
use ide_db::{
|
||||
|
|
@ -32,7 +39,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
|
|||
},
|
||||
};
|
||||
|
||||
fn completion_list(code: &str) -> String {
|
||||
pub(crate) fn completion_list(code: &str) -> String {
|
||||
completion_list_with_config(TEST_CONFIG, code)
|
||||
}
|
||||
|
||||
|
|
|
|||
127
crates/ide_completion/src/tests/items.rs
Normal file
127
crates/ide_completion/src/tests/items.rs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
//! Completions tests for item specifics overall.
|
||||
//!
|
||||
//! Except for use items which are tested in [super::use_tree] and mod declarations with are tested
|
||||
//! in [crate::completions::mod_].
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::tests::completion_list;
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let base = r#"#[rustc_builtin_macro]
|
||||
pub macro Clone {}
|
||||
enum Enum { Variant }
|
||||
struct Struct {}
|
||||
#[macro_export]
|
||||
macro_rules! foo {}
|
||||
mod bar {}
|
||||
const CONST: () = ();
|
||||
trait Trait {}
|
||||
"#;
|
||||
let actual = completion_list(&format!("{}{}", base, ra_fixture));
|
||||
expect.assert_eq(&actual)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn target_type_or_trait_in_impl_block() {
|
||||
check(
|
||||
r#"
|
||||
impl Tra$0
|
||||
"#,
|
||||
expect![[r##"
|
||||
tt Trait
|
||||
en Enum
|
||||
st Struct
|
||||
md bar
|
||||
ma foo!(…) #[macro_export] macro_rules! foo
|
||||
ma foo!(…) #[macro_export] macro_rules! foo
|
||||
bt u32
|
||||
bt bool
|
||||
bt u8
|
||||
bt isize
|
||||
bt u16
|
||||
bt u64
|
||||
bt u128
|
||||
bt f32
|
||||
bt i128
|
||||
bt i16
|
||||
bt str
|
||||
bt i64
|
||||
bt char
|
||||
bt f64
|
||||
bt i32
|
||||
bt i8
|
||||
bt usize
|
||||
"##]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn target_type_in_trait_impl_block() {
|
||||
check(
|
||||
r#"
|
||||
impl Trait for Str$0
|
||||
"#,
|
||||
expect![[r##"
|
||||
tt Trait
|
||||
en Enum
|
||||
st Struct
|
||||
md bar
|
||||
ma foo!(…) #[macro_export] macro_rules! foo
|
||||
ma foo!(…) #[macro_export] macro_rules! foo
|
||||
bt u32
|
||||
bt bool
|
||||
bt u8
|
||||
bt isize
|
||||
bt u16
|
||||
bt u64
|
||||
bt u128
|
||||
bt f32
|
||||
bt i128
|
||||
bt i16
|
||||
bt str
|
||||
bt i64
|
||||
bt char
|
||||
bt f64
|
||||
bt i32
|
||||
bt i8
|
||||
bt usize
|
||||
"##]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_trait_name_in_trait_def() {
|
||||
check(
|
||||
r"trait A $0",
|
||||
expect![[r#"
|
||||
kw where
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_trait_or_target_name_in_impl() {
|
||||
check(
|
||||
r"impl Trait $0",
|
||||
expect![[r#"
|
||||
kw where
|
||||
kw for
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn before_record_field() {
|
||||
check(
|
||||
r#"
|
||||
struct Foo {
|
||||
$0
|
||||
pub f: i32,
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
kw pub(crate)
|
||||
kw pub
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue