]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/tests/flyimport.rs
201443e10c2f0c56ac00bd5781a7fc65fb8a1e71
[rust.git] / crates / ide_completion / src / tests / flyimport.rs
1 use expect_test::{expect, Expect};
2
3 use crate::tests::{check_edit, check_edit_with_config, TEST_CONFIG};
4
5 fn check(ra_fixture: &str, expect: Expect) {
6     let config = TEST_CONFIG;
7     let (db, position) = crate::tests::position(ra_fixture);
8     let ctx = crate::context::CompletionContext::new(&db, position, &config).unwrap();
9
10     let mut acc = crate::completions::Completions::default();
11     crate::completions::flyimport::import_on_the_fly(&mut acc, &ctx);
12
13     expect.assert_eq(&super::render_completion_list(Vec::from(acc)));
14 }
15
16 #[test]
17 fn function_fuzzy_completion() {
18     check_edit(
19         "stdin",
20         r#"
21 //- /lib.rs crate:dep
22 pub mod io {
23     pub fn stdin() {}
24 };
25
26 //- /main.rs crate:main deps:dep
27 fn main() {
28     stdi$0
29 }
30 "#,
31         r#"
32 use dep::io::stdin;
33
34 fn main() {
35     stdin()$0
36 }
37 "#,
38     );
39 }
40
41 #[test]
42 fn macro_fuzzy_completion() {
43     check_edit(
44         "macro_with_curlies!",
45         r#"
46 //- /lib.rs crate:dep
47 /// Please call me as macro_with_curlies! {}
48 #[macro_export]
49 macro_rules! macro_with_curlies {
50     () => {}
51 }
52
53 //- /main.rs crate:main deps:dep
54 fn main() {
55     curli$0
56 }
57 "#,
58         r#"
59 use dep::macro_with_curlies;
60
61 fn main() {
62     macro_with_curlies! {$0}
63 }
64 "#,
65     );
66 }
67
68 #[test]
69 fn struct_fuzzy_completion() {
70     check_edit(
71         "ThirdStruct",
72         r#"
73 //- /lib.rs crate:dep
74 pub struct FirstStruct;
75 pub mod some_module {
76     pub struct SecondStruct;
77     pub struct ThirdStruct;
78 }
79
80 //- /main.rs crate:main deps:dep
81 use dep::{FirstStruct, some_module::SecondStruct};
82
83 fn main() {
84     this$0
85 }
86 "#,
87         r#"
88 use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
89
90 fn main() {
91     ThirdStruct
92 }
93 "#,
94     );
95 }
96
97 #[test]
98 fn short_paths_are_ignored() {
99     cov_mark::check!(ignore_short_input_for_path);
100
101     check(
102         r#"
103 //- /lib.rs crate:dep
104 pub struct FirstStruct;
105 pub mod some_module {
106     pub struct SecondStruct;
107     pub struct ThirdStruct;
108 }
109
110 //- /main.rs crate:main deps:dep
111 use dep::{FirstStruct, some_module::SecondStruct};
112
113 fn main() {
114     t$0
115 }
116 "#,
117         expect![[r#""#]],
118     );
119 }
120
121 #[test]
122 fn fuzzy_completions_come_in_specific_order() {
123     cov_mark::check!(certain_fuzzy_order_test);
124     check(
125         r#"
126 //- /lib.rs crate:dep
127 pub struct FirstStruct;
128 pub mod some_module {
129     // already imported, omitted
130     pub struct SecondStruct;
131     // does not contain all letters from the query, omitted
132     pub struct UnrelatedOne;
133     // contains all letters from the query, but not in sequence, displayed last
134     pub struct ThiiiiiirdStruct;
135     // contains all letters from the query, but not in the beginning, displayed second
136     pub struct AfterThirdStruct;
137     // contains all letters from the query in the begginning, displayed first
138     pub struct ThirdStruct;
139 }
140
141 //- /main.rs crate:main deps:dep
142 use dep::{FirstStruct, some_module::SecondStruct};
143
144 fn main() {
145     hir$0
146 }
147 "#,
148         expect![[r#"
149                 st ThirdStruct (use dep::some_module::ThirdStruct)
150                 st AfterThirdStruct (use dep::some_module::AfterThirdStruct)
151                 st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct)
152             "#]],
153     );
154 }
155
156 #[test]
157 fn trait_function_fuzzy_completion() {
158     let fixture = r#"
159         //- /lib.rs crate:dep
160         pub mod test_mod {
161             pub trait TestTrait {
162                 const SPECIAL_CONST: u8;
163                 type HumbleType;
164                 fn weird_function();
165                 fn random_method(&self);
166             }
167             pub struct TestStruct {}
168             impl TestTrait for TestStruct {
169                 const SPECIAL_CONST: u8 = 42;
170                 type HumbleType = ();
171                 fn weird_function() {}
172                 fn random_method(&self) {}
173             }
174         }
175
176         //- /main.rs crate:main deps:dep
177         fn main() {
178             dep::test_mod::TestStruct::wei$0
179         }
180         "#;
181
182     check(
183         fixture,
184         expect![[r#"
185                 fn weird_function() (use dep::test_mod::TestTrait) fn()
186             "#]],
187     );
188
189     check_edit(
190         "weird_function",
191         fixture,
192         r#"
193 use dep::test_mod::TestTrait;
194
195 fn main() {
196     dep::test_mod::TestStruct::weird_function()$0
197 }
198 "#,
199     );
200 }
201
202 #[test]
203 fn trait_const_fuzzy_completion() {
204     let fixture = r#"
205         //- /lib.rs crate:dep
206         pub mod test_mod {
207             pub trait TestTrait {
208                 const SPECIAL_CONST: u8;
209                 type HumbleType;
210                 fn weird_function();
211                 fn random_method(&self);
212             }
213             pub struct TestStruct {}
214             impl TestTrait for TestStruct {
215                 const SPECIAL_CONST: u8 = 42;
216                 type HumbleType = ();
217                 fn weird_function() {}
218                 fn random_method(&self) {}
219             }
220         }
221
222         //- /main.rs crate:main deps:dep
223         fn main() {
224             dep::test_mod::TestStruct::spe$0
225         }
226         "#;
227
228     check(
229         fixture,
230         expect![[r#"
231             ct SPECIAL_CONST (use dep::test_mod::TestTrait)
232         "#]],
233     );
234
235     check_edit(
236         "SPECIAL_CONST",
237         fixture,
238         r#"
239 use dep::test_mod::TestTrait;
240
241 fn main() {
242     dep::test_mod::TestStruct::SPECIAL_CONST
243 }
244 "#,
245     );
246 }
247
248 #[test]
249 fn trait_method_fuzzy_completion() {
250     let fixture = r#"
251         //- /lib.rs crate:dep
252         pub mod test_mod {
253             pub trait TestTrait {
254                 const SPECIAL_CONST: u8;
255                 type HumbleType;
256                 fn weird_function();
257                 fn random_method(&self);
258             }
259             pub struct TestStruct {}
260             impl TestTrait for TestStruct {
261                 const SPECIAL_CONST: u8 = 42;
262                 type HumbleType = ();
263                 fn weird_function() {}
264                 fn random_method(&self) {}
265             }
266         }
267
268         //- /main.rs crate:main deps:dep
269         fn main() {
270             let test_struct = dep::test_mod::TestStruct {};
271             test_struct.ran$0
272         }
273         "#;
274
275     check(
276         fixture,
277         expect![[r#"
278                 me random_method() (use dep::test_mod::TestTrait) fn(&self)
279             "#]],
280     );
281
282     check_edit(
283         "random_method",
284         fixture,
285         r#"
286 use dep::test_mod::TestTrait;
287
288 fn main() {
289     let test_struct = dep::test_mod::TestStruct {};
290     test_struct.random_method()$0
291 }
292 "#,
293     );
294 }
295
296 #[test]
297 fn no_trait_type_fuzzy_completion() {
298     check(
299         r#"
300 //- /lib.rs crate:dep
301 pub mod test_mod {
302     pub trait TestTrait {
303         const SPECIAL_CONST: u8;
304         type HumbleType;
305         fn weird_function();
306         fn random_method(&self);
307     }
308     pub struct TestStruct {}
309     impl TestTrait for TestStruct {
310         const SPECIAL_CONST: u8 = 42;
311         type HumbleType = ();
312         fn weird_function() {}
313         fn random_method(&self) {}
314     }
315 }
316
317 //- /main.rs crate:main deps:dep
318 fn main() {
319     dep::test_mod::TestStruct::hum$0
320 }
321 "#,
322         expect![[r#""#]],
323     );
324 }
325
326 #[test]
327 fn does_not_propose_names_in_scope() {
328     check(
329         r#"
330 //- /lib.rs crate:dep
331 pub mod test_mod {
332     pub trait TestTrait {
333         const SPECIAL_CONST: u8;
334         type HumbleType;
335         fn weird_function();
336         fn random_method(&self);
337     }
338     pub struct TestStruct {}
339     impl TestTrait for TestStruct {
340         const SPECIAL_CONST: u8 = 42;
341         type HumbleType = ();
342         fn weird_function() {}
343         fn random_method(&self) {}
344     }
345 }
346
347 //- /main.rs crate:main deps:dep
348 use dep::test_mod::TestStruct;
349 fn main() {
350     TestSt$0
351 }
352 "#,
353         expect![[r#""#]],
354     );
355 }
356
357 #[test]
358 fn does_not_propose_traits_in_scope() {
359     check(
360         r#"
361 //- /lib.rs crate:dep
362 pub mod test_mod {
363     pub trait TestTrait {
364         const SPECIAL_CONST: u8;
365         type HumbleType;
366         fn weird_function();
367         fn random_method(&self);
368     }
369     pub struct TestStruct {}
370     impl TestTrait for TestStruct {
371         const SPECIAL_CONST: u8 = 42;
372         type HumbleType = ();
373         fn weird_function() {}
374         fn random_method(&self) {}
375     }
376 }
377
378 //- /main.rs crate:main deps:dep
379 use dep::test_mod::{TestStruct, TestTrait};
380 fn main() {
381     dep::test_mod::TestStruct::hum$0
382 }
383 "#,
384         expect![[r#""#]],
385     );
386 }
387
388 #[test]
389 fn blanket_trait_impl_import() {
390     check_edit(
391         "another_function",
392         r#"
393 //- /lib.rs crate:dep
394 pub mod test_mod {
395     pub struct TestStruct {}
396     pub trait TestTrait {
397         fn another_function();
398     }
399     impl<T> TestTrait for T {
400         fn another_function() {}
401     }
402 }
403
404 //- /main.rs crate:main deps:dep
405 fn main() {
406     dep::test_mod::TestStruct::ano$0
407 }
408 "#,
409         r#"
410 use dep::test_mod::TestTrait;
411
412 fn main() {
413     dep::test_mod::TestStruct::another_function()$0
414 }
415 "#,
416     );
417 }
418
419 #[test]
420 fn zero_input_deprecated_assoc_item_completion() {
421     check(
422         r#"
423 //- /lib.rs crate:dep
424 pub mod test_mod {
425     #[deprecated]
426     pub trait TestTrait {
427         const SPECIAL_CONST: u8;
428         type HumbleType;
429         fn weird_function();
430         fn random_method(&self);
431     }
432     pub struct TestStruct {}
433     impl TestTrait for TestStruct {
434         const SPECIAL_CONST: u8 = 42;
435         type HumbleType = ();
436         fn weird_function() {}
437         fn random_method(&self) {}
438     }
439 }
440
441 //- /main.rs crate:main deps:dep
442 fn main() {
443     let test_struct = dep::test_mod::TestStruct {};
444     test_struct.$0
445 }
446         "#,
447         expect![[r#"
448                 me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
449             "#]],
450     );
451
452     check(
453         r#"
454 //- /lib.rs crate:dep
455 pub mod test_mod {
456     #[deprecated]
457     pub trait TestTrait {
458         const SPECIAL_CONST: u8;
459         type HumbleType;
460         fn weird_function();
461         fn random_method(&self);
462     }
463     pub struct TestStruct {}
464     impl TestTrait for TestStruct {
465         const SPECIAL_CONST: u8 = 42;
466         type HumbleType = ();
467         fn weird_function() {}
468         fn random_method(&self) {}
469     }
470 }
471
472 //- /main.rs crate:main deps:dep
473 fn main() {
474     dep::test_mod::TestStruct::$0
475 }
476 "#,
477         expect![[r#"
478                 fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED
479                 ct SPECIAL_CONST (use dep::test_mod::TestTrait) DEPRECATED
480             "#]],
481     );
482 }
483
484 #[test]
485 fn no_completions_in_use_statements() {
486     check(
487         r#"
488 //- /lib.rs crate:dep
489 pub mod io {
490     pub fn stdin() {}
491 };
492
493 //- /main.rs crate:main deps:dep
494 use stdi$0
495
496 fn main() {}
497 "#,
498         expect![[]],
499     );
500 }
501
502 #[test]
503 fn prefix_config_usage() {
504     let fixture = r#"
505 mod foo {
506     pub mod bar {
507         pub struct Item;
508     }
509 }
510
511 use crate::foo::bar;
512
513 fn main() {
514     Ite$0
515 }"#;
516     let mut config = TEST_CONFIG;
517
518     config.insert_use.prefix_kind = hir::PrefixKind::ByCrate;
519     check_edit_with_config(
520         config.clone(),
521         "Item",
522         fixture,
523         r#"
524 mod foo {
525     pub mod bar {
526         pub struct Item;
527     }
528 }
529
530 use crate::foo::bar::{self, Item};
531
532 fn main() {
533     Item
534 }"#,
535     );
536
537     config.insert_use.prefix_kind = hir::PrefixKind::BySelf;
538     check_edit_with_config(
539         config.clone(),
540         "Item",
541         fixture,
542         r#"
543 mod foo {
544     pub mod bar {
545         pub struct Item;
546     }
547 }
548
549 use crate::foo::bar;
550
551 use self::foo::bar::Item;
552
553 fn main() {
554     Item
555 }"#,
556     );
557
558     config.insert_use.prefix_kind = hir::PrefixKind::Plain;
559     check_edit_with_config(
560         config,
561         "Item",
562         fixture,
563         r#"
564 mod foo {
565     pub mod bar {
566         pub struct Item;
567     }
568 }
569
570 use foo::bar::Item;
571
572 use crate::foo::bar;
573
574 fn main() {
575     Item
576 }"#,
577     );
578 }
579
580 #[test]
581 fn unresolved_qualifier() {
582     let fixture = r#"
583 mod foo {
584     pub mod bar {
585         pub mod baz {
586             pub struct Item;
587         }
588     }
589 }
590
591 fn main() {
592     bar::baz::Ite$0
593 }"#;
594
595     check(
596         fixture,
597         expect![[r#"
598         st Item (use foo::bar::baz::Item)
599         "#]],
600     );
601
602     check_edit(
603         "Item",
604         fixture,
605         r#"
606         use foo::bar;
607
608         mod foo {
609             pub mod bar {
610                 pub mod baz {
611                     pub struct Item;
612                 }
613             }
614         }
615
616         fn main() {
617             bar::baz::Item
618         }"#,
619     );
620 }
621
622 #[test]
623 fn unresolved_assoc_item_container() {
624     let fixture = r#"
625 mod foo {
626     pub struct Item;
627
628     impl Item {
629         pub const TEST_ASSOC: usize = 3;
630     }
631 }
632
633 fn main() {
634     Item::TEST_A$0
635 }"#;
636
637     check(
638         fixture,
639         expect![[r#"
640         ct TEST_ASSOC (use foo::Item)
641         "#]],
642     );
643
644     check_edit(
645         "TEST_ASSOC",
646         fixture,
647         r#"
648 use foo::Item;
649
650 mod foo {
651     pub struct Item;
652
653     impl Item {
654         pub const TEST_ASSOC: usize = 3;
655     }
656 }
657
658 fn main() {
659     Item::TEST_ASSOC
660 }"#,
661     );
662 }
663
664 #[test]
665 fn unresolved_assoc_item_container_with_path() {
666     let fixture = r#"
667 mod foo {
668     pub mod bar {
669         pub struct Item;
670
671         impl Item {
672             pub const TEST_ASSOC: usize = 3;
673         }
674     }
675 }
676
677 fn main() {
678     bar::Item::TEST_A$0
679 }"#;
680
681     check(
682         fixture,
683         expect![[r#"
684         ct TEST_ASSOC (use foo::bar::Item)
685     "#]],
686     );
687
688     check_edit(
689         "TEST_ASSOC",
690         fixture,
691         r#"
692 use foo::bar;
693
694 mod foo {
695     pub mod bar {
696         pub struct Item;
697
698         impl Item {
699             pub const TEST_ASSOC: usize = 3;
700         }
701     }
702 }
703
704 fn main() {
705     bar::Item::TEST_ASSOC
706 }"#,
707     );
708 }
709
710 #[test]
711 fn fuzzy_unresolved_path() {
712     check(
713         r#"
714 mod foo {
715     pub mod bar {
716         pub struct Item;
717
718         impl Item {
719             pub const TEST_ASSOC: usize = 3;
720         }
721     }
722 }
723
724 fn main() {
725     bar::ASS$0
726 }"#,
727         expect![[]],
728     )
729 }
730
731 #[test]
732 fn unqualified_assoc_items_are_omitted() {
733     check(
734         r#"
735 mod something {
736     pub trait BaseTrait {
737         fn test_function() -> i32;
738     }
739
740     pub struct Item1;
741     pub struct Item2;
742
743     impl BaseTrait for Item1 {
744         fn test_function() -> i32 {
745             1
746         }
747     }
748
749     impl BaseTrait for Item2 {
750         fn test_function() -> i32 {
751             2
752         }
753     }
754 }
755
756 fn main() {
757     test_f$0
758 }"#,
759         expect![[]],
760     )
761 }
762
763 #[test]
764 fn case_matters() {
765     check(
766         r#"
767 mod foo {
768     pub const TEST_CONST: usize = 3;
769     pub fn test_function() -> i32 {
770         4
771     }
772 }
773
774 fn main() {
775     TE$0
776 }"#,
777         expect![[r#"
778         ct TEST_CONST (use foo::TEST_CONST)
779     "#]],
780     );
781
782     check(
783         r#"
784 mod foo {
785     pub const TEST_CONST: usize = 3;
786     pub fn test_function() -> i32 {
787         4
788     }
789 }
790
791 fn main() {
792     te$0
793 }"#,
794         expect![[r#"
795         ct TEST_CONST (use foo::TEST_CONST)
796         fn test_function() (use foo::test_function) fn() -> i32
797     "#]],
798     );
799
800     check(
801         r#"
802 mod foo {
803     pub const TEST_CONST: usize = 3;
804     pub fn test_function() -> i32 {
805         4
806     }
807 }
808
809 fn main() {
810     Te$0
811 }"#,
812         expect![[]],
813     );
814 }
815
816 #[test]
817 fn no_fuzzy_during_fields_of_record_lit_syntax() {
818     check(
819         r#"
820 mod m {
821     pub fn some_fn() -> i32 {
822         42
823     }
824 }
825 struct Foo {
826     some_field: i32,
827 }
828 fn main() {
829     let _ = Foo { so$0 };
830 }
831 "#,
832         expect![[]],
833     );
834 }
835
836 #[test]
837 fn fuzzy_after_fields_of_record_lit_syntax() {
838     check(
839         r#"
840 mod m {
841     pub fn some_fn() -> i32 {
842         42
843     }
844 }
845 struct Foo {
846     some_field: i32,
847 }
848 fn main() {
849     let _ = Foo { some_field: so$0 };
850 }
851 "#,
852         expect![[r#"
853                 fn some_fn() (use m::some_fn) fn() -> i32
854             "#]],
855     );
856 }
857
858 #[test]
859 fn no_flyimports_in_traits_and_impl_declarations() {
860     check(
861         r#"
862 mod m {
863     pub fn some_fn() -> i32 {
864         42
865     }
866 }
867 trait Foo {
868     som$0
869 }
870 "#,
871         expect![[r#""#]],
872     );
873
874     check(
875         r#"
876 mod m {
877     pub fn some_fn() -> i32 {
878         42
879     }
880 }
881 struct Foo;
882 impl Foo {
883     som$0
884 }
885 "#,
886         expect![[r#""#]],
887     );
888
889     check(
890         r#"
891 mod m {
892     pub fn some_fn() -> i32 {
893         42
894     }
895 }
896 struct Foo;
897 trait Bar {}
898 impl Bar for Foo {
899     som$0
900 }
901 "#,
902         expect![[r#""#]],
903     );
904 }
905
906 #[test]
907 fn no_inherent_candidates_proposed() {
908     check(
909         r#"
910 mod baz {
911     pub trait DefDatabase {
912         fn method1(&self);
913     }
914     pub trait HirDatabase: DefDatabase {
915         fn method2(&self);
916     }
917 }
918
919 mod bar {
920     fn test(db: &dyn crate::baz::HirDatabase) {
921         db.metho$0
922     }
923 }
924             "#,
925         expect![[r#""#]],
926     );
927 }
928
929 #[test]
930 fn respects_doc_hidden() {
931     check(
932         r#"
933 //- /lib.rs crate:lib deps:dep
934 fn f() {
935     ().fro$0
936 }
937
938 //- /dep.rs crate:dep
939 #[doc(hidden)]
940 pub trait Private {
941     fn frob(&self) {}
942 }
943
944 impl<T> Private for T {}
945             "#,
946         expect![[r#""#]],
947     );
948     check(
949         r#"
950 //- /lib.rs crate:lib deps:dep
951 fn f() {
952     ().fro$0
953 }
954
955 //- /dep.rs crate:dep
956 pub trait Private {
957     #[doc(hidden)]
958     fn frob(&self) {}
959 }
960
961 impl<T> Private for T {}
962             "#,
963         expect![[r#""#]],
964     );
965 }
966
967 #[test]
968 fn regression_9760() {
969     check(
970         r#"
971 struct Struct;
972 fn main() {}
973
974 mod mud {
975     fn func() {
976         let struct_instance = Stru$0
977     }
978 }
979 "#,
980         expect![[r#"
981                 st Struct (use crate::Struct)
982             "#]],
983     );
984 }
985
986 #[test]
987 fn flyimport_pattern() {
988     check(
989         r#"
990 mod module {
991     pub struct Struct;
992 }
993 fn function() {
994     let Str$0
995 }
996 "#,
997         expect![[r#"
998                 st Struct (use module::Struct)
999             "#]],
1000     );
1001 }
1002
1003 #[test]
1004 fn flyimport_rename() {
1005     check(
1006         r#"
1007 mod module {
1008     pub struct Struct;
1009 }
1010 use self as Str$0;
1011     "#,
1012         expect![[r#""#]],
1013     );
1014 }