]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/tests/attribute.rs
fix: Don't duplicate attribute completions
[rust.git] / crates / ide_completion / src / tests / attribute.rs
1 //! Completion tests for attributes.
2 use expect_test::{expect, Expect};
3
4 use crate::tests::{check_edit, completion_list};
5
6 fn check(ra_fixture: &str, expect: Expect) {
7     let actual = completion_list(ra_fixture);
8     expect.assert_eq(&actual);
9 }
10
11 #[test]
12 fn proc_macros() {
13     check(
14         r#"
15 //- proc_macros: identity
16 #[$0]
17 struct Foo;
18 "#,
19         expect![[r#"
20             at allow(…)
21             at cfg(…)
22             at cfg_attr(…)
23             at deny(…)
24             at forbid(…)
25             at warn(…)
26             at deprecated
27             at doc = "…"
28             at doc(hidden)
29             at doc(alias = "…")
30             at must_use
31             at no_mangle
32             at derive(…)
33             at repr(…)
34             at non_exhaustive
35             kw self
36             kw super
37             kw crate
38             md proc_macros
39         "#]],
40     )
41 }
42
43 #[test]
44 fn proc_macros_qualified() {
45     check(
46         r#"
47 //- proc_macros: identity
48 #[proc_macros::$0]
49 struct Foo;
50 "#,
51         expect![[r#"
52             at input_replace pub macro input_replace
53             at identity      pub macro identity
54         "#]],
55     )
56 }
57
58 #[test]
59 fn inside_nested_attr() {
60     check(r#"#[cfg($0)]"#, expect![[]])
61 }
62
63 #[test]
64 fn with_existing_attr() {
65     check(
66         r#"#[no_mangle] #[$0] mcall!();"#,
67         expect![[r#"
68             at allow(…)
69             at cfg(…)
70             at cfg_attr(…)
71             at deny(…)
72             at forbid(…)
73             at warn(…)
74             kw self
75             kw super
76             kw crate
77         "#]],
78     )
79 }
80
81 #[test]
82 fn attr_on_source_file() {
83     check(
84         r#"#![$0]"#,
85         expect![[r#"
86             at allow(…)
87             at cfg(…)
88             at cfg_attr(…)
89             at deny(…)
90             at forbid(…)
91             at warn(…)
92             at deprecated
93             at doc = "…"
94             at doc(hidden)
95             at doc(alias = "…")
96             at must_use
97             at no_mangle
98             at crate_name = ""
99             at feature(…)
100             at no_implicit_prelude
101             at no_main
102             at no_std
103             at recursion_limit = "…"
104             at type_length_limit = …
105             at windows_subsystem = "…"
106             kw self
107             kw super
108             kw crate
109         "#]],
110     );
111 }
112
113 #[test]
114 fn attr_on_module() {
115     check(
116         r#"#[$0] mod foo;"#,
117         expect![[r#"
118             at allow(…)
119             at cfg(…)
120             at cfg_attr(…)
121             at deny(…)
122             at forbid(…)
123             at warn(…)
124             at deprecated
125             at doc = "…"
126             at doc(hidden)
127             at doc(alias = "…")
128             at must_use
129             at no_mangle
130             at macro_use
131             at path = "…"
132             kw self
133             kw super
134             kw crate
135         "#]],
136     );
137     check(
138         r#"mod foo {#![$0]}"#,
139         expect![[r#"
140             at allow(…)
141             at cfg(…)
142             at cfg_attr(…)
143             at deny(…)
144             at forbid(…)
145             at warn(…)
146             at deprecated
147             at doc = "…"
148             at doc(hidden)
149             at doc(alias = "…")
150             at must_use
151             at no_mangle
152             at no_implicit_prelude
153             kw self
154             kw super
155             kw crate
156         "#]],
157     );
158 }
159
160 #[test]
161 fn attr_on_macro_rules() {
162     check(
163         r#"#[$0] macro_rules! foo {}"#,
164         expect![[r#"
165             at allow(…)
166             at cfg(…)
167             at cfg_attr(…)
168             at deny(…)
169             at forbid(…)
170             at warn(…)
171             at deprecated
172             at doc = "…"
173             at doc(hidden)
174             at doc(alias = "…")
175             at must_use
176             at no_mangle
177             at macro_export
178             at macro_use
179             kw self
180             kw super
181             kw crate
182         "#]],
183     );
184 }
185
186 #[test]
187 fn attr_on_macro_def() {
188     check(
189         r#"#[$0] macro foo {}"#,
190         expect![[r#"
191             at allow(…)
192             at cfg(…)
193             at cfg_attr(…)
194             at deny(…)
195             at forbid(…)
196             at warn(…)
197             at deprecated
198             at doc = "…"
199             at doc(hidden)
200             at doc(alias = "…")
201             at must_use
202             at no_mangle
203             kw self
204             kw super
205             kw crate
206         "#]],
207     );
208 }
209
210 #[test]
211 fn attr_on_extern_crate() {
212     check(
213         r#"#[$0] extern crate foo;"#,
214         expect![[r#"
215             at allow(…)
216             at cfg(…)
217             at cfg_attr(…)
218             at deny(…)
219             at forbid(…)
220             at warn(…)
221             at deprecated
222             at doc = "…"
223             at doc(hidden)
224             at doc(alias = "…")
225             at must_use
226             at no_mangle
227             at macro_use
228             kw self
229             kw super
230             kw crate
231         "#]],
232     );
233 }
234
235 #[test]
236 fn attr_on_use() {
237     check(
238         r#"#[$0] use foo;"#,
239         expect![[r#"
240             at allow(…)
241             at cfg(…)
242             at cfg_attr(…)
243             at deny(…)
244             at forbid(…)
245             at warn(…)
246             at deprecated
247             at doc = "…"
248             at doc(hidden)
249             at doc(alias = "…")
250             at must_use
251             at no_mangle
252             kw self
253             kw super
254             kw crate
255         "#]],
256     );
257 }
258
259 #[test]
260 fn attr_on_type_alias() {
261     check(
262         r#"#[$0] type foo = ();"#,
263         expect![[r#"
264             at allow(…)
265             at cfg(…)
266             at cfg_attr(…)
267             at deny(…)
268             at forbid(…)
269             at warn(…)
270             at deprecated
271             at doc = "…"
272             at doc(hidden)
273             at doc(alias = "…")
274             at must_use
275             at no_mangle
276             kw self
277             kw super
278             kw crate
279         "#]],
280     );
281 }
282
283 #[test]
284 fn attr_on_struct() {
285     check(
286         r#"
287 //- minicore:derive
288 #[$0]
289 struct Foo;
290 "#,
291         expect![[r#"
292             at allow(…)
293             at cfg(…)
294             at cfg_attr(…)
295             at deny(…)
296             at forbid(…)
297             at warn(…)
298             at deprecated
299             at doc = "…"
300             at doc(hidden)
301             at doc(alias = "…")
302             at must_use
303             at no_mangle
304             at derive(…)
305             at repr(…)
306             at non_exhaustive
307             kw self
308             kw super
309             kw crate
310             md core
311             at derive           pub macro derive
312         "#]],
313     );
314 }
315
316 #[test]
317 fn attr_on_enum() {
318     check(
319         r#"#[$0] enum Foo {}"#,
320         expect![[r#"
321             at allow(…)
322             at cfg(…)
323             at cfg_attr(…)
324             at deny(…)
325             at forbid(…)
326             at warn(…)
327             at deprecated
328             at doc = "…"
329             at doc(hidden)
330             at doc(alias = "…")
331             at must_use
332             at no_mangle
333             at derive(…)
334             at repr(…)
335             at non_exhaustive
336             kw self
337             kw super
338             kw crate
339         "#]],
340     );
341 }
342
343 #[test]
344 fn attr_on_const() {
345     check(
346         r#"#[$0] const FOO: () = ();"#,
347         expect![[r#"
348             at allow(…)
349             at cfg(…)
350             at cfg_attr(…)
351             at deny(…)
352             at forbid(…)
353             at warn(…)
354             at deprecated
355             at doc = "…"
356             at doc(hidden)
357             at doc(alias = "…")
358             at must_use
359             at no_mangle
360             kw self
361             kw super
362             kw crate
363         "#]],
364     );
365 }
366
367 #[test]
368 fn attr_on_static() {
369     check(
370         r#"#[$0] static FOO: () = ()"#,
371         expect![[r#"
372             at allow(…)
373             at cfg(…)
374             at cfg_attr(…)
375             at deny(…)
376             at forbid(…)
377             at warn(…)
378             at deprecated
379             at doc = "…"
380             at doc(hidden)
381             at doc(alias = "…")
382             at must_use
383             at no_mangle
384             at export_name = "…"
385             at link_name = "…"
386             at link_section = "…"
387             at global_allocator
388             at used
389             kw self
390             kw super
391             kw crate
392         "#]],
393     );
394 }
395
396 #[test]
397 fn attr_on_trait() {
398     check(
399         r#"#[$0] trait Foo {}"#,
400         expect![[r#"
401             at allow(…)
402             at cfg(…)
403             at cfg_attr(…)
404             at deny(…)
405             at forbid(…)
406             at warn(…)
407             at deprecated
408             at doc = "…"
409             at doc(hidden)
410             at doc(alias = "…")
411             at must_use
412             at no_mangle
413             at must_use
414             kw self
415             kw super
416             kw crate
417         "#]],
418     );
419 }
420
421 #[test]
422 fn attr_on_impl() {
423     check(
424         r#"#[$0] impl () {}"#,
425         expect![[r#"
426             at allow(…)
427             at cfg(…)
428             at cfg_attr(…)
429             at deny(…)
430             at forbid(…)
431             at warn(…)
432             at deprecated
433             at doc = "…"
434             at doc(hidden)
435             at doc(alias = "…")
436             at must_use
437             at no_mangle
438             at automatically_derived
439             kw self
440             kw super
441             kw crate
442         "#]],
443     );
444     check(
445         r#"impl () {#![$0]}"#,
446         expect![[r#"
447             at allow(…)
448             at cfg(…)
449             at cfg_attr(…)
450             at deny(…)
451             at forbid(…)
452             at warn(…)
453             at deprecated
454             at doc = "…"
455             at doc(hidden)
456             at doc(alias = "…")
457             at must_use
458             at no_mangle
459             kw self
460             kw super
461             kw crate
462         "#]],
463     );
464 }
465
466 #[test]
467 fn attr_on_extern_block() {
468     check(
469         r#"#[$0] extern {}"#,
470         expect![[r#"
471             at allow(…)
472             at cfg(…)
473             at cfg_attr(…)
474             at deny(…)
475             at forbid(…)
476             at warn(…)
477             at deprecated
478             at doc = "…"
479             at doc(hidden)
480             at doc(alias = "…")
481             at must_use
482             at no_mangle
483             at link
484             kw self
485             kw super
486             kw crate
487         "#]],
488     );
489     check(
490         r#"extern {#![$0]}"#,
491         expect![[r#"
492             at allow(…)
493             at cfg(…)
494             at cfg_attr(…)
495             at deny(…)
496             at forbid(…)
497             at warn(…)
498             at deprecated
499             at doc = "…"
500             at doc(hidden)
501             at doc(alias = "…")
502             at must_use
503             at no_mangle
504             at link
505             kw self
506             kw super
507             kw crate
508         "#]],
509     );
510 }
511
512 #[test]
513 fn attr_on_variant() {
514     check(
515         r#"enum Foo { #[$0] Bar }"#,
516         expect![[r#"
517             at allow(…)
518             at cfg(…)
519             at cfg_attr(…)
520             at deny(…)
521             at forbid(…)
522             at warn(…)
523             at non_exhaustive
524             kw self
525             kw super
526             kw crate
527         "#]],
528     );
529 }
530
531 #[test]
532 fn attr_on_fn() {
533     check(
534         r#"#[$0] fn main() {}"#,
535         expect![[r#"
536             at allow(…)
537             at cfg(…)
538             at cfg_attr(…)
539             at deny(…)
540             at forbid(…)
541             at warn(…)
542             at deprecated
543             at doc = "…"
544             at doc(hidden)
545             at doc(alias = "…")
546             at must_use
547             at no_mangle
548             at export_name = "…"
549             at link_name = "…"
550             at link_section = "…"
551             at cold
552             at ignore = "…"
553             at inline
554             at must_use
555             at panic_handler
556             at proc_macro
557             at proc_macro_derive(…)
558             at proc_macro_attribute
559             at should_panic
560             at target_feature = "…"
561             at test
562             at track_caller
563             kw self
564             kw super
565             kw crate
566         "#]],
567     );
568 }
569
570 #[test]
571 fn attr_on_expr() {
572     cov_mark::check!(no_keyword_completion_in_attr_of_expr);
573     check(
574         r#"fn main() { #[$0] foo() }"#,
575         expect![[r#"
576             at allow(…)
577             at cfg(…)
578             at cfg_attr(…)
579             at deny(…)
580             at forbid(…)
581             at warn(…)
582             kw self
583             kw super
584             kw crate
585         "#]],
586     );
587 }
588
589 #[test]
590 fn attr_in_source_file_end() {
591     check(
592         r#"#[$0]"#,
593         expect![[r#"
594             at allow(…)
595             at automatically_derived
596             at cfg(…)
597             at cfg_attr(…)
598             at cold
599             at deny(…)
600             at deprecated
601             at derive(…)
602             at doc = "…"
603             at doc(alias = "…")
604             at doc(hidden)
605             at export_name = "…"
606             at forbid(…)
607             at global_allocator
608             at ignore = "…"
609             at inline
610             at link
611             at link_name = "…"
612             at link_section = "…"
613             at macro_export
614             at macro_use
615             at must_use
616             at no_mangle
617             at non_exhaustive
618             at panic_handler
619             at path = "…"
620             at proc_macro
621             at proc_macro_attribute
622             at proc_macro_derive(…)
623             at repr(…)
624             at should_panic
625             at target_feature = "…"
626             at test
627             at track_caller
628             at used
629             at warn(…)
630             kw self
631             kw super
632             kw crate
633         "#]],
634     );
635 }
636
637 mod cfg {
638     use super::*;
639
640     #[test]
641     fn cfg_target_endian() {
642         check(
643             r#"#[cfg(target_endian = $0"#,
644             expect![[r#"
645                 ba little
646                 ba big
647             "#]],
648         );
649     }
650 }
651
652 mod derive {
653     use super::*;
654
655     fn check_derive(ra_fixture: &str, expect: Expect) {
656         let actual = completion_list(ra_fixture);
657         expect.assert_eq(&actual);
658     }
659
660     #[test]
661     fn no_completion_for_incorrect_derive() {
662         check_derive(
663             r#"
664 //- minicore: derive, copy, clone, ord, eq, default, fmt
665 #[derive{$0)] struct Test;
666 "#,
667             expect![[]],
668         )
669     }
670
671     #[test]
672     fn empty_derive() {
673         check_derive(
674             r#"
675 //- minicore: derive, copy, clone, ord, eq, default, fmt
676 #[derive($0)] struct Test;
677 "#,
678             expect![[r#"
679                 de Default
680                 de Clone, Copy
681                 de PartialEq
682                 de PartialEq, Eq
683                 de PartialEq, Eq, PartialOrd, Ord
684                 de Clone
685                 de PartialEq, PartialOrd
686             "#]],
687         );
688     }
689
690     #[test]
691     fn derive_with_input_before() {
692         check_derive(
693             r#"
694 //- minicore: derive, copy, clone, ord, eq, default, fmt
695 #[derive(serde::Serialize, PartialEq, $0)] struct Test;
696 "#,
697             expect![[r#"
698                 de Default
699                 de Clone, Copy
700                 de Eq
701                 de Eq, PartialOrd, Ord
702                 de Clone
703                 de PartialOrd
704             "#]],
705         )
706     }
707
708     #[test]
709     fn derive_with_input_after() {
710         check_derive(
711             r#"
712 //- minicore: derive, copy, clone, ord, eq, default, fmt
713 #[derive($0 serde::Serialize, PartialEq)] struct Test;
714 "#,
715             expect![[r#"
716                 de Default
717                 de Clone, Copy
718                 de Eq
719                 de Eq, PartialOrd, Ord
720                 de Clone
721                 de PartialOrd
722             "#]],
723         )
724     }
725
726     #[test]
727     fn derive_flyimport() {
728         check_derive(
729             r#"
730 //- proc_macros: derive_identity
731 #[derive(der$0)] struct Test;
732 "#,
733             expect![[r#"
734                 de DeriveIdentity (use proc_macros::DeriveIdentity)
735             "#]],
736         );
737         check_derive(
738             r#"
739 //- proc_macros: derive_identity
740 use proc_macros::DeriveIdentity;
741 #[derive(der$0)] struct Test;
742 "#,
743             expect![[r#"
744                 de DeriveIdentity
745             "#]],
746         );
747     }
748
749     #[test]
750     fn derive_flyimport_edit() {
751         check_edit(
752             "DeriveIdentity",
753             r#"
754 //- proc_macros: derive_identity
755 #[derive(der$0)] struct Test;
756 "#,
757             r#"
758 use proc_macros::DeriveIdentity;
759
760 #[derive(DeriveIdentity)] struct Test;
761 "#,
762         );
763     }
764 }
765
766 mod lint {
767     use super::*;
768
769     #[test]
770     fn lint_empty() {
771         check_edit(
772             "deprecated",
773             r#"#[allow($0)] struct Test;"#,
774             r#"#[allow(deprecated)] struct Test;"#,
775         )
776     }
777
778     #[test]
779     fn lint_with_existing() {
780         check_edit(
781             "deprecated",
782             r#"#[allow(keyword_idents, $0)] struct Test;"#,
783             r#"#[allow(keyword_idents, deprecated)] struct Test;"#,
784         )
785     }
786
787     #[test]
788     fn lint_qualified() {
789         check_edit(
790             "deprecated",
791             r#"#[allow(keyword_idents, $0)] struct Test;"#,
792             r#"#[allow(keyword_idents, deprecated)] struct Test;"#,
793         )
794     }
795
796     #[test]
797     fn lint_feature() {
798         check_edit(
799             "box_syntax",
800             r#"#[feature(box_$0)] struct Test;"#,
801             r#"#[feature(box_syntax)] struct Test;"#,
802         )
803     }
804
805     #[test]
806     fn lint_clippy_unqualified() {
807         check_edit(
808             "clippy::as_conversions",
809             r#"#[allow($0)] struct Test;"#,
810             r#"#[allow(clippy::as_conversions)] struct Test;"#,
811         );
812     }
813
814     #[test]
815     fn lint_clippy_qualified() {
816         check_edit(
817             "as_conversions",
818             r#"#[allow(clippy::$0)] struct Test;"#,
819             r#"#[allow(clippy::as_conversions)] struct Test;"#,
820         );
821     }
822
823     #[test]
824     fn lint_rustdoc_unqualified() {
825         check_edit(
826             "rustdoc::bare_urls",
827             r#"#[allow($0)] struct Test;"#,
828             r#"#[allow(rustdoc::bare_urls)] struct Test;"#,
829         );
830     }
831
832     #[test]
833     fn lint_rustdoc_qualified() {
834         check_edit(
835             "bare_urls",
836             r#"#[allow(rustdoc::$0)] struct Test;"#,
837             r#"#[allow(rustdoc::bare_urls)] struct Test;"#,
838         );
839     }
840
841     #[test]
842     fn lint_unclosed() {
843         check_edit(
844             "deprecated",
845             r#"#[allow(dep$0 struct Test;"#,
846             r#"#[allow(deprecated struct Test;"#,
847         );
848         check_edit(
849             "bare_urls",
850             r#"#[allow(rustdoc::$0 struct Test;"#,
851             r#"#[allow(rustdoc::bare_urls struct Test;"#,
852         );
853     }
854 }
855
856 mod repr {
857     use super::*;
858
859     fn check_repr(ra_fixture: &str, expect: Expect) {
860         let actual = completion_list(ra_fixture);
861         expect.assert_eq(&actual);
862     }
863
864     #[test]
865     fn no_completion_for_incorrect_repr() {
866         check_repr(r#"#[repr{$0)] struct Test;"#, expect![[]])
867     }
868
869     #[test]
870     fn empty() {
871         check_repr(
872             r#"#[repr($0)] struct Test;"#,
873             expect![[r#"
874                 ba align($0)
875                 ba packed
876                 ba transparent
877                 ba C
878                 ba u8
879                 ba u16
880                 ba u32
881                 ba u64
882                 ba u128
883                 ba usize
884                 ba i8
885                 ba i16
886                 ba i32
887                 ba i64
888                 ba i28
889                 ba isize
890             "#]],
891         );
892     }
893
894     #[test]
895     fn transparent() {
896         check_repr(r#"#[repr(transparent, $0)] struct Test;"#, expect![[r#""#]]);
897     }
898
899     #[test]
900     fn align() {
901         check_repr(
902             r#"#[repr(align(1), $0)] struct Test;"#,
903             expect![[r#"
904                 ba transparent
905                 ba C
906                 ba u8
907                 ba u16
908                 ba u32
909                 ba u64
910                 ba u128
911                 ba usize
912                 ba i8
913                 ba i16
914                 ba i32
915                 ba i64
916                 ba i28
917                 ba isize
918             "#]],
919         );
920     }
921
922     #[test]
923     fn packed() {
924         check_repr(
925             r#"#[repr(packed, $0)] struct Test;"#,
926             expect![[r#"
927                 ba transparent
928                 ba C
929                 ba u8
930                 ba u16
931                 ba u32
932                 ba u64
933                 ba u128
934                 ba usize
935                 ba i8
936                 ba i16
937                 ba i32
938                 ba i64
939                 ba i28
940                 ba isize
941             "#]],
942         );
943     }
944
945     #[test]
946     fn c() {
947         check_repr(
948             r#"#[repr(C, $0)] struct Test;"#,
949             expect![[r#"
950                 ba align($0)
951                 ba packed
952                 ba u8
953                 ba u16
954                 ba u32
955                 ba u64
956                 ba u128
957                 ba usize
958                 ba i8
959                 ba i16
960                 ba i32
961                 ba i64
962                 ba i28
963                 ba isize
964             "#]],
965         );
966     }
967
968     #[test]
969     fn prim() {
970         check_repr(
971             r#"#[repr(usize, $0)] struct Test;"#,
972             expect![[r#"
973                 ba align($0)
974                 ba packed
975                 ba C
976             "#]],
977         );
978     }
979 }