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