//! Completion tests for use trees. 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 use_tree_completion() { check( r#" struct implThing; use crate::{impl$0}; "#, expect![[r#" st implThing implThing kw self "#]], ); check( r#" struct implThing; use crate::{impl$0; "#, expect![[r#" st implThing implThing kw self "#]], ); } #[test] fn use_tree_start() { cov_mark::check!(unqualified_path_selected_only); check( r#" //- /lib.rs crate:main deps:other_crate use f$0 struct Foo; enum FooBar { Foo, Bar } mod foo {} //- /other_crate/lib.rs crate:other_crate // nothing here "#, expect![[r#" en FooBar:: md foo md other_crate kw crate:: kw self:: "#]], ); } #[test] fn use_tree_start_abs() { cov_mark::check!(use_tree_crate_roots_only); check( r#" //- /lib.rs crate:main deps:other_crate use ::f$0 struct Foo; mod foo {} //- /other_crate/lib.rs crate:other_crate // nothing here "#, expect![[r#" md other_crate "#]], ); } #[test] fn dont_complete_current_use() { cov_mark::check!(dont_complete_current_use); check(r#"use self::foo$0;"#, expect![[r#""#]]); check( r#" mod foo { pub struct S; } use self::{foo::*, bar$0}; "#, expect![[r#" md foo st S S "#]], ); } #[test] fn nested_use_tree() { check( r#" mod foo { pub mod bar { pub struct FooBar; } } use foo::{bar::$0} "#, expect![[r#" st FooBar FooBar "#]], ); check( r#" mod foo { pub mod bar { pub struct FooBar; } } use foo::{$0} "#, expect![[r#" md bar kw self "#]], ); } #[test] fn deeply_nested_use_tree() { check( r#" mod foo { pub mod bar { pub mod baz { pub struct FooBarBaz; } } } use foo::{bar::{baz::$0}} "#, expect![[r#" st FooBarBaz FooBarBaz "#]], ); check( r#" mod foo { pub mod bar { pub mod baz { pub struct FooBarBaz; } } } use foo::{bar::{$0}} "#, expect![[r#" md baz kw self "#]], ); } #[test] fn plain_qualified_use_tree() { check( r#" use foo::$0 mod foo { struct Private; pub struct Foo; macro_rules! foo_ { {} => {} } pub use foo_ as foo; } struct Bar; "#, expect![[r#" ma foo macro_rules! foo_ st Foo Foo "#]], ); } #[test] fn enum_plain_qualified_use_tree() { cov_mark::check!(enum_plain_qualified_use_tree); check( r#" use Foo::$0 enum Foo { UnitVariant, TupleVariant(), RecordVariant {}, } impl Foo { const CONST: () = () fn func() {} } "#, expect![[r#" ev RecordVariant RecordVariant ev TupleVariant TupleVariant ev UnitVariant UnitVariant "#]], ); } #[test] fn self_qualified_use_tree() { check( r#" use self::$0 mod foo {} struct Bar; "#, expect![[r#" md foo st Bar Bar "#]], ); } #[test] fn super_qualified_use_tree() { check( r#" mod bar { use super::$0 } mod foo {} struct Bar; "#, expect![[r#" md bar md foo st Bar Bar "#]], ); } #[test] fn super_super_qualified_use_tree() { check( r#" mod a { const A: usize = 0; mod b { const B: usize = 0; mod c { use super::super::$0 } } } "#, expect![[r#" ct A usize md b kw super:: "#]], ); } #[test] fn crate_qualified_use_tree() { check( r#" use crate::$0 mod foo {} struct Bar; "#, expect![[r#" md foo st Bar Bar "#]], ); } #[test] fn extern_crate_qualified_use_tree() { check( r#" //- /lib.rs crate:main deps:other_crate use other_crate::$0 //- /other_crate/lib.rs crate:other_crate pub struct Foo; pub mod foo {} "#, expect![[r#" md foo st Foo Foo "#]], ); } #[test] fn pub_use_tree() { check( r#" pub struct X; pub mod bar {} pub use $0; "#, expect![[r#" md bar kw crate:: kw self:: "#]], ); } #[test] fn pub_suggest_use_tree_super_acc_to_depth_in_tree() { // https://github.com/rust-lang/rust-analyzer/issues/12439 // Check discussion in https://github.com/rust-lang/rust-analyzer/pull/12447 check( r#" mod foo { mod bar { pub use super::$0; } } "#, expect![[r#" md bar kw super:: "#]], ); // Not suggest super when at crate root check( r#" mod foo { mod bar { pub use super::super::$0; } } "#, expect![[r#" md foo "#]], ); check( r#" mod foo { use $0; } "#, expect![[r#" kw crate:: kw self:: kw super:: "#]], ); // Not suggest super after another kw in path ( here it is foo1 ) check( r#" mod foo { mod bar { use super::super::foo1::$0; } } mod foo1 { pub mod bar1 {} } "#, expect![[r#" md bar1 "#]], ); } #[test] fn use_tree_braces_at_start() { check( r#" struct X; mod bar {} use {$0}; "#, expect![[r#" md bar kw crate:: kw self:: "#]], ); } #[test] fn impl_prefix_does_not_add_fn_snippet() { // regression test for 7222 check( r#" mod foo { pub fn bar(x: u32) {} } use self::foo::impl$0 "#, expect![[r#" fn bar fn(u32) "#]], ); } #[test] fn use_tree_no_unstable_items_on_stable() { check( r#" //- /lib.rs crate:main deps:std use std::$0 //- /std.rs crate:std #[unstable] pub mod simd {} #[unstable] pub struct S; #[unstable] pub fn foo() {} #[unstable] #[macro_export] marco_rules! m { () => {} } "#, expect![""], ); } #[test] fn use_tree_unstable_items_on_nightly() { check( r#" //- toolchain:nightly //- /lib.rs crate:main deps:std use std::$0 //- /std.rs crate:std #[unstable] pub mod simd {} #[unstable] pub struct S; #[unstable] pub fn foo() {} #[unstable] #[macro_export] marco_rules! m { () => {} } "#, expect![[r#" fn foo fn() md simd st S S "#]], ); }