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:
bors[bot] 2021-06-17 13:44:38 +00:00 committed by GitHub
commit 3ae0c5911a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 242 additions and 171 deletions

View file

@ -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
"#]],
);
}

View file

@ -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);
}

View file

@ -33,7 +33,6 @@ pub(super) fn complete_lint(
#[cfg(test)]
mod tests {
use crate::tests::check_edit;
#[test]

View file

@ -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);

View file

@ -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]

View file

@ -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#""#]],
);
}

View file

@ -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(

View file

@ -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() {

View file

@ -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(

View file

@ -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))
}

View file

@ -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)
}

View 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
"#]],
)
}