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