diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs | 1016 |
1 files changed, 1016 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs new file mode 100644 index 000000000..1578ba2c3 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs @@ -0,0 +1,1016 @@ +//! Completion tests for attributes. +use expect_test::{expect, Expect}; + +use crate::tests::{check_edit, completion_list}; + +fn check(ra_fixture: &str, expect: Expect) { + let actual = completion_list(ra_fixture); + expect.assert_eq(&actual); +} + +#[test] +fn proc_macros() { + check( + r#" +//- proc_macros: identity +#[$0] +struct Foo; +"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at derive(…) + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at non_exhaustive + at repr(…) + at warn(…) + md proc_macros + kw crate:: + kw self:: + "#]], + ) +} + +#[test] +fn proc_macros_on_comment() { + check( + r#" +//- proc_macros: identity +/// $0 +#[proc_macros::identity] +struct Foo; +"#, + expect![[r#""#]], + ) +} + +#[test] +fn proc_macros_qualified() { + check( + r#" +//- proc_macros: identity +#[proc_macros::$0] +struct Foo; +"#, + expect![[r#" + at identity proc_macro identity + "#]], + ) +} + +#[test] +fn inside_nested_attr() { + check(r#"#[cfg($0)]"#, expect![[]]) +} + +#[test] +fn with_existing_attr() { + check( + r#"#[no_mangle] #[$0] mcall!();"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at forbid(…) + at warn(…) + kw crate:: + kw self:: + "#]], + ) +} + +#[test] +fn attr_on_source_file() { + check( + r#"#![$0]"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at crate_name = "" + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at feature(…) + at forbid(…) + at must_use + at no_implicit_prelude + at no_main + at no_mangle + at no_std + at recursion_limit = "…" + at type_length_limit = … + at warn(…) + at windows_subsystem = "…" + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_module() { + check( + r#"#[$0] mod foo;"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at macro_use + at must_use + at no_mangle + at path = "…" + at warn(…) + kw crate:: + kw self:: + kw super:: + "#]], + ); + check( + r#"mod foo {#![$0]}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_implicit_prelude + at no_mangle + at warn(…) + kw crate:: + kw self:: + kw super:: + "#]], + ); +} + +#[test] +fn attr_on_macro_rules() { + check( + r#"#[$0] macro_rules! foo {}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at macro_export + at macro_use + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_macro_def() { + check( + r#"#[$0] macro foo {}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_extern_crate() { + check( + r#"#[$0] extern crate foo;"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at macro_use + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_use() { + check( + r#"#[$0] use foo;"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_type_alias() { + check( + r#"#[$0] type foo = ();"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_struct() { + check( + r#" +//- minicore:derive +#[$0] +struct Foo; +"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at derive macro derive + at derive(…) + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at non_exhaustive + at repr(…) + at warn(…) + md core + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_enum() { + check( + r#"#[$0] enum Foo {}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at derive(…) + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at non_exhaustive + at repr(…) + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_const() { + check( + r#"#[$0] const FOO: () = ();"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_static() { + check( + r#"#[$0] static FOO: () = ()"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at export_name = "…" + at forbid(…) + at global_allocator + at link_name = "…" + at link_section = "…" + at must_use + at no_mangle + at used + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_trait() { + check( + r#"#[$0] trait Foo {}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_impl() { + check( + r#"#[$0] impl () {}"#, + expect![[r#" + at allow(…) + at automatically_derived + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); + check( + r#"impl () {#![$0]}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_extern_block() { + check( + r#"#[$0] extern {}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at link + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); + check( + r#"extern {#![$0]}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at forbid(…) + at link + at must_use + at no_mangle + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_variant() { + check( + r#"enum Foo { #[$0] Bar }"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at forbid(…) + at non_exhaustive + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_on_fn() { + check( + r#"#[$0] fn main() {}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at cold + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at export_name = "…" + at forbid(…) + at ignore = "…" + at inline + at link_name = "…" + at link_section = "…" + at must_use + at must_use + at no_mangle + at panic_handler + at proc_macro + at proc_macro_attribute + at proc_macro_derive(…) + at should_panic + at target_feature(enable = "…") + at test + at track_caller + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn attr_in_source_file_end() { + check( + r#"#[$0]"#, + expect![[r#" + at allow(…) + at automatically_derived + at cfg(…) + at cfg_attr(…) + at cold + at deny(…) + at deprecated + at derive(…) + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at export_name = "…" + at forbid(…) + at global_allocator + at ignore = "…" + at inline + at link + at link_name = "…" + at link_section = "…" + at macro_export + at macro_use + at must_use + at no_mangle + at non_exhaustive + at panic_handler + at path = "…" + at proc_macro + at proc_macro_attribute + at proc_macro_derive(…) + at repr(…) + at should_panic + at target_feature(enable = "…") + at test + at track_caller + at used + at warn(…) + kw crate:: + kw self:: + "#]], + ); +} + +mod cfg { + use super::*; + + #[test] + fn cfg_target_endian() { + check( + r#"#[cfg(target_endian = $0"#, + expect![[r#" + ba big + ba little + "#]], + ); + } +} + +mod derive { + use super::*; + + fn check_derive(ra_fixture: &str, expect: Expect) { + let actual = completion_list(ra_fixture); + expect.assert_eq(&actual); + } + + #[test] + fn no_completion_for_incorrect_derive() { + check_derive( + r#" +//- minicore: derive, copy, clone, ord, eq, default, fmt +#[derive{$0)] struct Test; +"#, + expect![[]], + ) + } + + #[test] + fn empty_derive() { + check_derive( + r#" +//- minicore: derive, copy, clone, ord, eq, default, fmt +#[derive($0)] struct Test; +"#, + expect![[r#" + de Clone macro Clone + de Clone, Copy + de Default macro Default + de PartialEq macro PartialEq + de PartialEq, Eq + de PartialEq, Eq, PartialOrd, Ord + de PartialEq, PartialOrd + md core + kw crate:: + kw self:: + "#]], + ); + } + + #[test] + fn derive_with_input_before() { + check_derive( + r#" +//- minicore: derive, copy, clone, ord, eq, default, fmt +#[derive(serde::Serialize, PartialEq, $0)] struct Test; +"#, + expect![[r#" + de Clone macro Clone + de Clone, Copy + de Default macro Default + de Eq + de Eq, PartialOrd, Ord + de PartialOrd + md core + kw crate:: + kw self:: + "#]], + ) + } + + #[test] + fn derive_with_input_after() { + check_derive( + r#" +//- minicore: derive, copy, clone, ord, eq, default, fmt +#[derive($0 serde::Serialize, PartialEq)] struct Test; +"#, + expect![[r#" + de Clone macro Clone + de Clone, Copy + de Default macro Default + de Eq + de Eq, PartialOrd, Ord + de PartialOrd + md core + kw crate:: + kw self:: + "#]], + ); + } + + #[test] + fn derive_with_existing_derives() { + check_derive( + r#" +//- minicore: derive, copy, clone, ord, eq, default, fmt +#[derive(PartialEq, Eq, Or$0)] struct Test; +"#, + expect![[r#" + de Clone macro Clone + de Clone, Copy + de Default macro Default + de PartialOrd + de PartialOrd, Ord + md core + kw crate:: + kw self:: + "#]], + ); + } + + #[test] + fn derive_flyimport() { + check_derive( + r#" +//- proc_macros: derive_identity +//- minicore: derive +#[derive(der$0)] struct Test; +"#, + expect![[r#" + de DeriveIdentity (use proc_macros::DeriveIdentity) proc_macro DeriveIdentity + md core + md proc_macros + kw crate:: + kw self:: + "#]], + ); + check_derive( + r#" +//- proc_macros: derive_identity +//- minicore: derive +use proc_macros::DeriveIdentity; +#[derive(der$0)] struct Test; +"#, + expect![[r#" + de DeriveIdentity proc_macro DeriveIdentity + md core + md proc_macros + kw crate:: + kw self:: + "#]], + ); + } + + #[test] + fn derive_flyimport_edit() { + check_edit( + "DeriveIdentity", + r#" +//- proc_macros: derive_identity +//- minicore: derive +#[derive(der$0)] struct Test; +"#, + r#" +use proc_macros::DeriveIdentity; + +#[derive(DeriveIdentity)] struct Test; +"#, + ); + } + + #[test] + fn qualified() { + check_derive( + r#" +//- proc_macros: derive_identity +//- minicore: derive, copy, clone +#[derive(proc_macros::$0)] struct Test; +"#, + expect![[r#" + de DeriveIdentity proc_macro DeriveIdentity + "#]], + ); + check_derive( + r#" +//- proc_macros: derive_identity +//- minicore: derive, copy, clone +#[derive(proc_macros::C$0)] struct Test; +"#, + expect![[r#" + de DeriveIdentity proc_macro DeriveIdentity + "#]], + ); + } +} + +mod lint { + use super::*; + + #[test] + fn lint_empty() { + check_edit( + "deprecated", + r#"#[allow($0)] struct Test;"#, + r#"#[allow(deprecated)] struct Test;"#, + ) + } + + #[test] + fn lint_with_existing() { + check_edit( + "deprecated", + r#"#[allow(keyword_idents, $0)] struct Test;"#, + r#"#[allow(keyword_idents, deprecated)] struct Test;"#, + ) + } + + #[test] + fn lint_qualified() { + check_edit( + "deprecated", + r#"#[allow(keyword_idents, $0)] struct Test;"#, + r#"#[allow(keyword_idents, deprecated)] struct Test;"#, + ) + } + + #[test] + fn lint_feature() { + check_edit( + "box_syntax", + r#"#[feature(box_$0)] struct Test;"#, + r#"#[feature(box_syntax)] struct Test;"#, + ) + } + + #[test] + fn lint_clippy_unqualified() { + check_edit( + "clippy::as_conversions", + r#"#[allow($0)] struct Test;"#, + r#"#[allow(clippy::as_conversions)] struct Test;"#, + ); + } + + #[test] + fn lint_clippy_qualified() { + check_edit( + "as_conversions", + r#"#[allow(clippy::$0)] struct Test;"#, + r#"#[allow(clippy::as_conversions)] struct Test;"#, + ); + } + + #[test] + fn lint_rustdoc_unqualified() { + check_edit( + "rustdoc::bare_urls", + r#"#[allow($0)] struct Test;"#, + r#"#[allow(rustdoc::bare_urls)] struct Test;"#, + ); + } + + #[test] + fn lint_rustdoc_qualified() { + check_edit( + "bare_urls", + r#"#[allow(rustdoc::$0)] struct Test;"#, + r#"#[allow(rustdoc::bare_urls)] struct Test;"#, + ); + } + + #[test] + fn lint_unclosed() { + check_edit( + "deprecated", + r#"#[allow(dep$0 struct Test;"#, + r#"#[allow(deprecated struct Test;"#, + ); + check_edit( + "bare_urls", + r#"#[allow(rustdoc::$0 struct Test;"#, + r#"#[allow(rustdoc::bare_urls struct Test;"#, + ); + } +} + +mod repr { + use super::*; + + fn check_repr(ra_fixture: &str, expect: Expect) { + let actual = completion_list(ra_fixture); + expect.assert_eq(&actual); + } + + #[test] + fn no_completion_for_incorrect_repr() { + check_repr(r#"#[repr{$0)] struct Test;"#, expect![[]]) + } + + #[test] + fn empty() { + check_repr( + r#"#[repr($0)] struct Test;"#, + expect![[r#" + ba C + ba align($0) + ba i16 + ba i28 + ba i32 + ba i64 + ba i8 + ba isize + ba packed + ba transparent + ba u128 + ba u16 + ba u32 + ba u64 + ba u8 + ba usize + "#]], + ); + } + + #[test] + fn transparent() { + check_repr(r#"#[repr(transparent, $0)] struct Test;"#, expect![[r#""#]]); + } + + #[test] + fn align() { + check_repr( + r#"#[repr(align(1), $0)] struct Test;"#, + expect![[r#" + ba C + ba i16 + ba i28 + ba i32 + ba i64 + ba i8 + ba isize + ba transparent + ba u128 + ba u16 + ba u32 + ba u64 + ba u8 + ba usize + "#]], + ); + } + + #[test] + fn packed() { + check_repr( + r#"#[repr(packed, $0)] struct Test;"#, + expect![[r#" + ba C + ba i16 + ba i28 + ba i32 + ba i64 + ba i8 + ba isize + ba transparent + ba u128 + ba u16 + ba u32 + ba u64 + ba u8 + ba usize + "#]], + ); + } + + #[test] + fn c() { + check_repr( + r#"#[repr(C, $0)] struct Test;"#, + expect![[r#" + ba align($0) + ba i16 + ba i28 + ba i32 + ba i64 + ba i8 + ba isize + ba packed + ba u128 + ba u16 + ba u32 + ba u64 + ba u8 + ba usize + "#]], + ); + } + + #[test] + fn prim() { + check_repr( + r#"#[repr(usize, $0)] struct Test;"#, + expect![[r#" + ba C + ba align($0) + ba packed + "#]], + ); + } +} |