aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src/helpers')
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs639
-rw-r--r--crates/ide_db/src/helpers/insert_use/tests.rs620
2 files changed, 621 insertions, 638 deletions
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index 08d246c16..040843990 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -573,641 +573,4 @@ fn find_insert_position(
573} 573}
574 574
575#[cfg(test)] 575#[cfg(test)]
576mod tests { 576mod tests;
577 use super::*;
578
579 use test_utils::assert_eq_text;
580
581 #[test]
582 fn insert_existing() {
583 check_full("std::fs", "use std::fs;", "use std::fs;")
584 }
585
586 #[test]
587 fn insert_start() {
588 check_none(
589 "std::bar::AA",
590 r"
591use std::bar::B;
592use std::bar::D;
593use std::bar::F;
594use std::bar::G;",
595 r"
596use std::bar::AA;
597use std::bar::B;
598use std::bar::D;
599use std::bar::F;
600use std::bar::G;",
601 )
602 }
603
604 #[test]
605 fn insert_start_indent() {
606 mark::check!(insert_use_indent_after);
607 check_none(
608 "std::bar::AA",
609 r"
610 use std::bar::B;
611 use std::bar::D;",
612 r"
613 use std::bar::AA;
614 use std::bar::B;
615 use std::bar::D;",
616 )
617 }
618
619 #[test]
620 fn insert_middle() {
621 check_none(
622 "std::bar::EE",
623 r"
624use std::bar::A;
625use std::bar::D;
626use std::bar::F;
627use std::bar::G;",
628 r"
629use std::bar::A;
630use std::bar::D;
631use std::bar::EE;
632use std::bar::F;
633use std::bar::G;",
634 )
635 }
636
637 #[test]
638 fn insert_middle_indent() {
639 check_none(
640 "std::bar::EE",
641 r"
642 use std::bar::A;
643 use std::bar::D;
644 use std::bar::F;
645 use std::bar::G;",
646 r"
647 use std::bar::A;
648 use std::bar::D;
649 use std::bar::EE;
650 use std::bar::F;
651 use std::bar::G;",
652 )
653 }
654
655 #[test]
656 fn insert_end() {
657 check_none(
658 "std::bar::ZZ",
659 r"
660use std::bar::A;
661use std::bar::D;
662use std::bar::F;
663use std::bar::G;",
664 r"
665use std::bar::A;
666use std::bar::D;
667use std::bar::F;
668use std::bar::G;
669use std::bar::ZZ;",
670 )
671 }
672
673 #[test]
674 fn insert_end_indent() {
675 mark::check!(insert_use_indent_before);
676 check_none(
677 "std::bar::ZZ",
678 r"
679 use std::bar::A;
680 use std::bar::D;
681 use std::bar::F;
682 use std::bar::G;",
683 r"
684 use std::bar::A;
685 use std::bar::D;
686 use std::bar::F;
687 use std::bar::G;
688 use std::bar::ZZ;",
689 )
690 }
691
692 #[test]
693 fn insert_middle_nested() {
694 check_none(
695 "std::bar::EE",
696 r"
697use std::bar::A;
698use std::bar::{D, Z}; // example of weird imports due to user
699use std::bar::F;
700use std::bar::G;",
701 r"
702use std::bar::A;
703use std::bar::EE;
704use std::bar::{D, Z}; // example of weird imports due to user
705use std::bar::F;
706use std::bar::G;",
707 )
708 }
709
710 #[test]
711 fn insert_middle_groups() {
712 check_none(
713 "foo::bar::GG",
714 r"
715 use std::bar::A;
716 use std::bar::D;
717
718 use foo::bar::F;
719 use foo::bar::H;",
720 r"
721 use std::bar::A;
722 use std::bar::D;
723
724 use foo::bar::F;
725 use foo::bar::GG;
726 use foo::bar::H;",
727 )
728 }
729
730 #[test]
731 fn insert_first_matching_group() {
732 check_none(
733 "foo::bar::GG",
734 r"
735 use foo::bar::A;
736 use foo::bar::D;
737
738 use std;
739
740 use foo::bar::F;
741 use foo::bar::H;",
742 r"
743 use foo::bar::A;
744 use foo::bar::D;
745 use foo::bar::GG;
746
747 use std;
748
749 use foo::bar::F;
750 use foo::bar::H;",
751 )
752 }
753
754 #[test]
755 fn insert_missing_group_std() {
756 check_none(
757 "std::fmt",
758 r"
759 use foo::bar::A;
760 use foo::bar::D;",
761 r"
762 use std::fmt;
763
764 use foo::bar::A;
765 use foo::bar::D;",
766 )
767 }
768
769 #[test]
770 fn insert_missing_group_self() {
771 check_none(
772 "self::fmt",
773 r"
774use foo::bar::A;
775use foo::bar::D;",
776 r"
777use foo::bar::A;
778use foo::bar::D;
779
780use self::fmt;",
781 )
782 }
783
784 #[test]
785 fn insert_no_imports() {
786 check_full(
787 "foo::bar",
788 "fn main() {}",
789 r"use foo::bar;
790
791fn main() {}",
792 )
793 }
794
795 #[test]
796 fn insert_empty_file() {
797 // empty files will get two trailing newlines
798 // this is due to the test case insert_no_imports above
799 check_full(
800 "foo::bar",
801 "",
802 r"use foo::bar;
803
804",
805 )
806 }
807
808 #[test]
809 fn insert_empty_module() {
810 mark::check!(insert_use_no_indent_after);
811 check(
812 "foo::bar",
813 "mod x {}",
814 r"{
815 use foo::bar;
816}",
817 None,
818 true,
819 )
820 }
821
822 #[test]
823 fn insert_after_inner_attr() {
824 check_full(
825 "foo::bar",
826 r"#![allow(unused_imports)]",
827 r"#![allow(unused_imports)]
828
829use foo::bar;",
830 )
831 }
832
833 #[test]
834 fn insert_after_inner_attr2() {
835 check_full(
836 "foo::bar",
837 r"#![allow(unused_imports)]
838
839#![no_std]
840fn main() {}",
841 r"#![allow(unused_imports)]
842
843#![no_std]
844
845use foo::bar;
846fn main() {}",
847 );
848 }
849
850 #[test]
851 fn inserts_after_single_line_inner_comments() {
852 check_none(
853 "foo::bar::Baz",
854 "//! Single line inner comments do not allow any code before them.",
855 r#"//! Single line inner comments do not allow any code before them.
856
857use foo::bar::Baz;"#,
858 );
859 }
860
861 #[test]
862 fn inserts_after_multiline_inner_comments() {
863 check_none(
864 "foo::bar::Baz",
865 r#"/*! Multiline inner comments do not allow any code before them. */
866
867/*! Still an inner comment, cannot place any code before. */
868fn main() {}"#,
869 r#"/*! Multiline inner comments do not allow any code before them. */
870
871/*! Still an inner comment, cannot place any code before. */
872
873use foo::bar::Baz;
874fn main() {}"#,
875 )
876 }
877
878 #[test]
879 fn inserts_after_all_inner_items() {
880 check_none(
881 "foo::bar::Baz",
882 r#"#![allow(unused_imports)]
883/*! Multiline line comment 2 */
884
885
886//! Single line comment 1
887#![no_std]
888//! Single line comment 2
889fn main() {}"#,
890 r#"#![allow(unused_imports)]
891/*! Multiline line comment 2 */
892
893
894//! Single line comment 1
895#![no_std]
896//! Single line comment 2
897
898use foo::bar::Baz;
899fn main() {}"#,
900 )
901 }
902
903 #[test]
904 fn merge_groups() {
905 check_last("std::io", r"use std::fmt;", r"use std::{fmt, io};")
906 }
907
908 #[test]
909 fn merge_groups_last() {
910 check_last(
911 "std::io",
912 r"use std::fmt::{Result, Display};",
913 r"use std::fmt::{Result, Display};
914use std::io;",
915 )
916 }
917
918 #[test]
919 fn merge_last_into_self() {
920 check_last("foo::bar::baz", r"use foo::bar;", r"use foo::bar::{self, baz};");
921 }
922
923 #[test]
924 fn merge_groups_full() {
925 check_full(
926 "std::io",
927 r"use std::fmt::{Result, Display};",
928 r"use std::{fmt::{Result, Display}, io};",
929 )
930 }
931
932 #[test]
933 fn merge_groups_long_full() {
934 check_full(
935 "std::foo::bar::Baz",
936 r"use std::foo::bar::Qux;",
937 r"use std::foo::bar::{Baz, Qux};",
938 )
939 }
940
941 #[test]
942 fn merge_groups_long_last() {
943 check_last(
944 "std::foo::bar::Baz",
945 r"use std::foo::bar::Qux;",
946 r"use std::foo::bar::{Baz, Qux};",
947 )
948 }
949
950 #[test]
951 fn merge_groups_long_full_list() {
952 check_full(
953 "std::foo::bar::Baz",
954 r"use std::foo::bar::{Qux, Quux};",
955 r"use std::foo::bar::{Baz, Quux, Qux};",
956 )
957 }
958
959 #[test]
960 fn merge_groups_long_last_list() {
961 check_last(
962 "std::foo::bar::Baz",
963 r"use std::foo::bar::{Qux, Quux};",
964 r"use std::foo::bar::{Baz, Quux, Qux};",
965 )
966 }
967
968 #[test]
969 fn merge_groups_long_full_nested() {
970 check_full(
971 "std::foo::bar::Baz",
972 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
973 r"use std::foo::bar::{Baz, Qux, quux::{Fez, Fizz}};",
974 )
975 }
976
977 #[test]
978 fn merge_groups_long_last_nested() {
979 check_last(
980 "std::foo::bar::Baz",
981 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
982 r"use std::foo::bar::Baz;
983use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
984 )
985 }
986
987 #[test]
988 fn merge_groups_full_nested_deep() {
989 check_full(
990 "std::foo::bar::quux::Baz",
991 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
992 r"use std::foo::bar::{Qux, quux::{Baz, Fez, Fizz}};",
993 )
994 }
995
996 #[test]
997 fn merge_groups_full_nested_long() {
998 check_full(
999 "std::foo::bar::Baz",
1000 r"use std::{foo::bar::Qux};",
1001 r"use std::{foo::bar::{Baz, Qux}};",
1002 );
1003 }
1004
1005 #[test]
1006 fn merge_groups_last_nested_long() {
1007 check_full(
1008 "std::foo::bar::Baz",
1009 r"use std::{foo::bar::Qux};",
1010 r"use std::{foo::bar::{Baz, Qux}};",
1011 );
1012 }
1013
1014 #[test]
1015 fn merge_groups_skip_pub() {
1016 check_full(
1017 "std::io",
1018 r"pub use std::fmt::{Result, Display};",
1019 r"pub use std::fmt::{Result, Display};
1020use std::io;",
1021 )
1022 }
1023
1024 #[test]
1025 fn merge_groups_skip_pub_crate() {
1026 check_full(
1027 "std::io",
1028 r"pub(crate) use std::fmt::{Result, Display};",
1029 r"pub(crate) use std::fmt::{Result, Display};
1030use std::io;",
1031 )
1032 }
1033
1034 #[test]
1035 #[ignore] // FIXME: Support this
1036 fn split_out_merge() {
1037 check_last(
1038 "std::fmt::Result",
1039 r"use std::{fmt, io};",
1040 r"use std::fmt::{self, Result};
1041use std::io;",
1042 )
1043 }
1044
1045 #[test]
1046 fn merge_into_module_import() {
1047 check_full(
1048 "std::fmt::Result",
1049 r"use std::{fmt, io};",
1050 r"use std::{fmt::{self, Result}, io};",
1051 )
1052 }
1053
1054 #[test]
1055 fn merge_groups_self() {
1056 check_full("std::fmt::Debug", r"use std::fmt;", r"use std::fmt::{self, Debug};")
1057 }
1058
1059 #[test]
1060 fn merge_mod_into_glob() {
1061 check_full(
1062 "token::TokenKind",
1063 r"use token::TokenKind::*;",
1064 r"use token::TokenKind::{*, self};",
1065 )
1066 // FIXME: have it emit `use token::TokenKind::{self, *}`?
1067 }
1068
1069 #[test]
1070 fn merge_self_glob() {
1071 check_full("self", r"use self::*;", r"use self::{*, self};")
1072 // FIXME: have it emit `use {self, *}`?
1073 }
1074
1075 #[test]
1076 fn merge_glob_nested() {
1077 check_full(
1078 "foo::bar::quux::Fez",
1079 r"use foo::bar::{Baz, quux::*};",
1080 r"use foo::bar::{Baz, quux::{self::*, Fez}};",
1081 )
1082 }
1083
1084 #[test]
1085 fn merge_nested_considers_first_segments() {
1086 check_full(
1087 "hir_ty::display::write_bounds_like_dyn_trait",
1088 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter}, method_resolution};",
1089 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter, write_bounds_like_dyn_trait}, method_resolution};",
1090 );
1091 }
1092
1093 #[test]
1094 fn skip_merge_last_too_long() {
1095 check_last(
1096 "foo::bar",
1097 r"use foo::bar::baz::Qux;",
1098 r"use foo::bar;
1099use foo::bar::baz::Qux;",
1100 );
1101 }
1102
1103 #[test]
1104 fn skip_merge_last_too_long2() {
1105 check_last(
1106 "foo::bar::baz::Qux",
1107 r"use foo::bar;",
1108 r"use foo::bar;
1109use foo::bar::baz::Qux;",
1110 );
1111 }
1112
1113 #[test]
1114 fn insert_short_before_long() {
1115 check_none(
1116 "foo::bar",
1117 r"use foo::bar::baz::Qux;",
1118 r"use foo::bar;
1119use foo::bar::baz::Qux;",
1120 );
1121 }
1122
1123 #[test]
1124 fn merge_last_fail() {
1125 check_merge_only_fail(
1126 r"use foo::bar::{baz::{Qux, Fez}};",
1127 r"use foo::bar::{baaz::{Quux, Feez}};",
1128 MergeBehaviour::Last,
1129 );
1130 }
1131
1132 #[test]
1133 fn merge_last_fail1() {
1134 check_merge_only_fail(
1135 r"use foo::bar::{baz::{Qux, Fez}};",
1136 r"use foo::bar::baaz::{Quux, Feez};",
1137 MergeBehaviour::Last,
1138 );
1139 }
1140
1141 #[test]
1142 fn merge_last_fail2() {
1143 check_merge_only_fail(
1144 r"use foo::bar::baz::{Qux, Fez};",
1145 r"use foo::bar::{baaz::{Quux, Feez}};",
1146 MergeBehaviour::Last,
1147 );
1148 }
1149
1150 #[test]
1151 fn merge_last_fail3() {
1152 check_merge_only_fail(
1153 r"use foo::bar::baz::{Qux, Fez};",
1154 r"use foo::bar::baaz::{Quux, Feez};",
1155 MergeBehaviour::Last,
1156 );
1157 }
1158
1159 fn check(
1160 path: &str,
1161 ra_fixture_before: &str,
1162 ra_fixture_after: &str,
1163 mb: Option<MergeBehaviour>,
1164 module: bool,
1165 ) {
1166 let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone();
1167 if module {
1168 syntax = syntax.descendants().find_map(ast::Module::cast).unwrap().syntax().clone();
1169 }
1170 let file = super::ImportScope::from(syntax).unwrap();
1171 let path = ast::SourceFile::parse(&format!("use {};", path))
1172 .tree()
1173 .syntax()
1174 .descendants()
1175 .find_map(ast::Path::cast)
1176 .unwrap();
1177
1178 let rewriter = insert_use(&file, path, mb);
1179 let result = rewriter.rewrite(file.as_syntax_node()).to_string();
1180 assert_eq_text!(&result, ra_fixture_after);
1181 }
1182
1183 fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
1184 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Full), false)
1185 }
1186
1187 fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
1188 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Last), false)
1189 }
1190
1191 fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
1192 check(path, ra_fixture_before, ra_fixture_after, None, false)
1193 }
1194
1195 fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehaviour) {
1196 let use0 = ast::SourceFile::parse(ra_fixture0)
1197 .tree()
1198 .syntax()
1199 .descendants()
1200 .find_map(ast::Use::cast)
1201 .unwrap();
1202
1203 let use1 = ast::SourceFile::parse(ra_fixture1)
1204 .tree()
1205 .syntax()
1206 .descendants()
1207 .find_map(ast::Use::cast)
1208 .unwrap();
1209
1210 let result = try_merge_imports(&use0, &use1, mb);
1211 assert_eq!(result.map(|u| u.to_string()), None);
1212 }
1213}
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs
new file mode 100644
index 000000000..86bfa5b41
--- /dev/null
+++ b/crates/ide_db/src/helpers/insert_use/tests.rs
@@ -0,0 +1,620 @@
1use super::*;
2
3use test_utils::assert_eq_text;
4
5#[test]
6fn insert_existing() {
7 check_full("std::fs", "use std::fs;", "use std::fs;")
8}
9
10#[test]
11fn insert_start() {
12 check_none(
13 "std::bar::AA",
14 r"
15use std::bar::B;
16use std::bar::D;
17use std::bar::F;
18use std::bar::G;",
19 r"
20use std::bar::AA;
21use std::bar::B;
22use std::bar::D;
23use std::bar::F;
24use std::bar::G;",
25 )
26}
27
28#[test]
29fn insert_start_indent() {
30 mark::check!(insert_use_indent_after);
31 check_none(
32 "std::bar::AA",
33 r"
34 use std::bar::B;
35 use std::bar::D;",
36 r"
37 use std::bar::AA;
38 use std::bar::B;
39 use std::bar::D;",
40 )
41}
42
43#[test]
44fn insert_middle() {
45 check_none(
46 "std::bar::EE",
47 r"
48use std::bar::A;
49use std::bar::D;
50use std::bar::F;
51use std::bar::G;",
52 r"
53use std::bar::A;
54use std::bar::D;
55use std::bar::EE;
56use std::bar::F;
57use std::bar::G;",
58 )
59}
60
61#[test]
62fn insert_middle_indent() {
63 check_none(
64 "std::bar::EE",
65 r"
66 use std::bar::A;
67 use std::bar::D;
68 use std::bar::F;
69 use std::bar::G;",
70 r"
71 use std::bar::A;
72 use std::bar::D;
73 use std::bar::EE;
74 use std::bar::F;
75 use std::bar::G;",
76 )
77}
78
79#[test]
80fn insert_end() {
81 check_none(
82 "std::bar::ZZ",
83 r"
84use std::bar::A;
85use std::bar::D;
86use std::bar::F;
87use std::bar::G;",
88 r"
89use std::bar::A;
90use std::bar::D;
91use std::bar::F;
92use std::bar::G;
93use std::bar::ZZ;",
94 )
95}
96
97#[test]
98fn insert_end_indent() {
99 mark::check!(insert_use_indent_before);
100 check_none(
101 "std::bar::ZZ",
102 r"
103 use std::bar::A;
104 use std::bar::D;
105 use std::bar::F;
106 use std::bar::G;",
107 r"
108 use std::bar::A;
109 use std::bar::D;
110 use std::bar::F;
111 use std::bar::G;
112 use std::bar::ZZ;",
113 )
114}
115
116#[test]
117fn insert_middle_nested() {
118 check_none(
119 "std::bar::EE",
120 r"
121use std::bar::A;
122use std::bar::{D, Z}; // example of weird imports due to user
123use std::bar::F;
124use std::bar::G;",
125 r"
126use std::bar::A;
127use std::bar::EE;
128use std::bar::{D, Z}; // example of weird imports due to user
129use std::bar::F;
130use std::bar::G;",
131 )
132}
133
134#[test]
135fn insert_middle_groups() {
136 check_none(
137 "foo::bar::GG",
138 r"
139 use std::bar::A;
140 use std::bar::D;
141
142 use foo::bar::F;
143 use foo::bar::H;",
144 r"
145 use std::bar::A;
146 use std::bar::D;
147
148 use foo::bar::F;
149 use foo::bar::GG;
150 use foo::bar::H;",
151 )
152}
153
154#[test]
155fn insert_first_matching_group() {
156 check_none(
157 "foo::bar::GG",
158 r"
159 use foo::bar::A;
160 use foo::bar::D;
161
162 use std;
163
164 use foo::bar::F;
165 use foo::bar::H;",
166 r"
167 use foo::bar::A;
168 use foo::bar::D;
169 use foo::bar::GG;
170
171 use std;
172
173 use foo::bar::F;
174 use foo::bar::H;",
175 )
176}
177
178#[test]
179fn insert_missing_group_std() {
180 check_none(
181 "std::fmt",
182 r"
183 use foo::bar::A;
184 use foo::bar::D;",
185 r"
186 use std::fmt;
187
188 use foo::bar::A;
189 use foo::bar::D;",
190 )
191}
192
193#[test]
194fn insert_missing_group_self() {
195 check_none(
196 "self::fmt",
197 r"
198use foo::bar::A;
199use foo::bar::D;",
200 r"
201use foo::bar::A;
202use foo::bar::D;
203
204use self::fmt;",
205 )
206}
207
208#[test]
209fn insert_no_imports() {
210 check_full(
211 "foo::bar",
212 "fn main() {}",
213 r"use foo::bar;
214
215fn main() {}",
216 )
217}
218
219#[test]
220fn insert_empty_file() {
221 // empty files will get two trailing newlines
222 // this is due to the test case insert_no_imports above
223 check_full(
224 "foo::bar",
225 "",
226 r"use foo::bar;
227
228",
229 )
230}
231
232#[test]
233fn insert_empty_module() {
234 mark::check!(insert_use_no_indent_after);
235 check(
236 "foo::bar",
237 "mod x {}",
238 r"{
239 use foo::bar;
240}",
241 None,
242 true,
243 )
244}
245
246#[test]
247fn insert_after_inner_attr() {
248 check_full(
249 "foo::bar",
250 r"#![allow(unused_imports)]",
251 r"#![allow(unused_imports)]
252
253use foo::bar;",
254 )
255}
256
257#[test]
258fn insert_after_inner_attr2() {
259 check_full(
260 "foo::bar",
261 r"#![allow(unused_imports)]
262
263#![no_std]
264fn main() {}",
265 r"#![allow(unused_imports)]
266
267#![no_std]
268
269use foo::bar;
270fn main() {}",
271 );
272}
273
274#[test]
275fn inserts_after_single_line_inner_comments() {
276 check_none(
277 "foo::bar::Baz",
278 "//! Single line inner comments do not allow any code before them.",
279 r#"//! Single line inner comments do not allow any code before them.
280
281use foo::bar::Baz;"#,
282 );
283}
284
285#[test]
286fn inserts_after_multiline_inner_comments() {
287 check_none(
288 "foo::bar::Baz",
289 r#"/*! Multiline inner comments do not allow any code before them. */
290
291/*! Still an inner comment, cannot place any code before. */
292fn main() {}"#,
293 r#"/*! Multiline inner comments do not allow any code before them. */
294
295/*! Still an inner comment, cannot place any code before. */
296
297use foo::bar::Baz;
298fn main() {}"#,
299 )
300}
301
302#[test]
303fn inserts_after_all_inner_items() {
304 check_none(
305 "foo::bar::Baz",
306 r#"#![allow(unused_imports)]
307/*! Multiline line comment 2 */
308
309
310//! Single line comment 1
311#![no_std]
312//! Single line comment 2
313fn main() {}"#,
314 r#"#![allow(unused_imports)]
315/*! Multiline line comment 2 */
316
317
318//! Single line comment 1
319#![no_std]
320//! Single line comment 2
321
322use foo::bar::Baz;
323fn main() {}"#,
324 )
325}
326
327#[test]
328fn merge_groups() {
329 check_last("std::io", r"use std::fmt;", r"use std::{fmt, io};")
330}
331
332#[test]
333fn merge_groups_last() {
334 check_last(
335 "std::io",
336 r"use std::fmt::{Result, Display};",
337 r"use std::fmt::{Result, Display};
338use std::io;",
339 )
340}
341
342#[test]
343fn merge_last_into_self() {
344 check_last("foo::bar::baz", r"use foo::bar;", r"use foo::bar::{self, baz};");
345}
346
347#[test]
348fn merge_groups_full() {
349 check_full(
350 "std::io",
351 r"use std::fmt::{Result, Display};",
352 r"use std::{fmt::{Result, Display}, io};",
353 )
354}
355
356#[test]
357fn merge_groups_long_full() {
358 check_full("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};")
359}
360
361#[test]
362fn merge_groups_long_last() {
363 check_last("std::foo::bar::Baz", r"use std::foo::bar::Qux;", r"use std::foo::bar::{Baz, Qux};")
364}
365
366#[test]
367fn merge_groups_long_full_list() {
368 check_full(
369 "std::foo::bar::Baz",
370 r"use std::foo::bar::{Qux, Quux};",
371 r"use std::foo::bar::{Baz, Quux, Qux};",
372 )
373}
374
375#[test]
376fn merge_groups_long_last_list() {
377 check_last(
378 "std::foo::bar::Baz",
379 r"use std::foo::bar::{Qux, Quux};",
380 r"use std::foo::bar::{Baz, Quux, Qux};",
381 )
382}
383
384#[test]
385fn merge_groups_long_full_nested() {
386 check_full(
387 "std::foo::bar::Baz",
388 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
389 r"use std::foo::bar::{Baz, Qux, quux::{Fez, Fizz}};",
390 )
391}
392
393#[test]
394fn merge_groups_long_last_nested() {
395 check_last(
396 "std::foo::bar::Baz",
397 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
398 r"use std::foo::bar::Baz;
399use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
400 )
401}
402
403#[test]
404fn merge_groups_full_nested_deep() {
405 check_full(
406 "std::foo::bar::quux::Baz",
407 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
408 r"use std::foo::bar::{Qux, quux::{Baz, Fez, Fizz}};",
409 )
410}
411
412#[test]
413fn merge_groups_full_nested_long() {
414 check_full(
415 "std::foo::bar::Baz",
416 r"use std::{foo::bar::Qux};",
417 r"use std::{foo::bar::{Baz, Qux}};",
418 );
419}
420
421#[test]
422fn merge_groups_last_nested_long() {
423 check_full(
424 "std::foo::bar::Baz",
425 r"use std::{foo::bar::Qux};",
426 r"use std::{foo::bar::{Baz, Qux}};",
427 );
428}
429
430#[test]
431fn merge_groups_skip_pub() {
432 check_full(
433 "std::io",
434 r"pub use std::fmt::{Result, Display};",
435 r"pub use std::fmt::{Result, Display};
436use std::io;",
437 )
438}
439
440#[test]
441fn merge_groups_skip_pub_crate() {
442 check_full(
443 "std::io",
444 r"pub(crate) use std::fmt::{Result, Display};",
445 r"pub(crate) use std::fmt::{Result, Display};
446use std::io;",
447 )
448}
449
450#[test]
451#[ignore] // FIXME: Support this
452fn split_out_merge() {
453 check_last(
454 "std::fmt::Result",
455 r"use std::{fmt, io};",
456 r"use std::fmt::{self, Result};
457use std::io;",
458 )
459}
460
461#[test]
462fn merge_into_module_import() {
463 check_full("std::fmt::Result", r"use std::{fmt, io};", r"use std::{fmt::{self, Result}, io};")
464}
465
466#[test]
467fn merge_groups_self() {
468 check_full("std::fmt::Debug", r"use std::fmt;", r"use std::fmt::{self, Debug};")
469}
470
471#[test]
472fn merge_mod_into_glob() {
473 check_full("token::TokenKind", r"use token::TokenKind::*;", r"use token::TokenKind::{*, self};")
474 // FIXME: have it emit `use token::TokenKind::{self, *}`?
475}
476
477#[test]
478fn merge_self_glob() {
479 check_full("self", r"use self::*;", r"use self::{*, self};")
480 // FIXME: have it emit `use {self, *}`?
481}
482
483#[test]
484fn merge_glob_nested() {
485 check_full(
486 "foo::bar::quux::Fez",
487 r"use foo::bar::{Baz, quux::*};",
488 r"use foo::bar::{Baz, quux::{self::*, Fez}};",
489 )
490}
491
492#[test]
493fn merge_nested_considers_first_segments() {
494 check_full(
495 "hir_ty::display::write_bounds_like_dyn_trait",
496 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter}, method_resolution};",
497 r"use hir_ty::{autoderef, display::{HirDisplayError, HirFormatter, write_bounds_like_dyn_trait}, method_resolution};",
498 );
499}
500
501#[test]
502fn skip_merge_last_too_long() {
503 check_last(
504 "foo::bar",
505 r"use foo::bar::baz::Qux;",
506 r"use foo::bar;
507use foo::bar::baz::Qux;",
508 );
509}
510
511#[test]
512fn skip_merge_last_too_long2() {
513 check_last(
514 "foo::bar::baz::Qux",
515 r"use foo::bar;",
516 r"use foo::bar;
517use foo::bar::baz::Qux;",
518 );
519}
520
521#[test]
522fn insert_short_before_long() {
523 check_none(
524 "foo::bar",
525 r"use foo::bar::baz::Qux;",
526 r"use foo::bar;
527use foo::bar::baz::Qux;",
528 );
529}
530
531#[test]
532fn merge_last_fail() {
533 check_merge_only_fail(
534 r"use foo::bar::{baz::{Qux, Fez}};",
535 r"use foo::bar::{baaz::{Quux, Feez}};",
536 MergeBehaviour::Last,
537 );
538}
539
540#[test]
541fn merge_last_fail1() {
542 check_merge_only_fail(
543 r"use foo::bar::{baz::{Qux, Fez}};",
544 r"use foo::bar::baaz::{Quux, Feez};",
545 MergeBehaviour::Last,
546 );
547}
548
549#[test]
550fn merge_last_fail2() {
551 check_merge_only_fail(
552 r"use foo::bar::baz::{Qux, Fez};",
553 r"use foo::bar::{baaz::{Quux, Feez}};",
554 MergeBehaviour::Last,
555 );
556}
557
558#[test]
559fn merge_last_fail3() {
560 check_merge_only_fail(
561 r"use foo::bar::baz::{Qux, Fez};",
562 r"use foo::bar::baaz::{Quux, Feez};",
563 MergeBehaviour::Last,
564 );
565}
566
567fn check(
568 path: &str,
569 ra_fixture_before: &str,
570 ra_fixture_after: &str,
571 mb: Option<MergeBehaviour>,
572 module: bool,
573) {
574 let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone();
575 if module {
576 syntax = syntax.descendants().find_map(ast::Module::cast).unwrap().syntax().clone();
577 }
578 let file = super::ImportScope::from(syntax).unwrap();
579 let path = ast::SourceFile::parse(&format!("use {};", path))
580 .tree()
581 .syntax()
582 .descendants()
583 .find_map(ast::Path::cast)
584 .unwrap();
585
586 let rewriter = insert_use(&file, path, mb);
587 let result = rewriter.rewrite(file.as_syntax_node()).to_string();
588 assert_eq_text!(&result, ra_fixture_after);
589}
590
591fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
592 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Full), false)
593}
594
595fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
596 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Last), false)
597}
598
599fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
600 check(path, ra_fixture_before, ra_fixture_after, None, false)
601}
602
603fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehaviour) {
604 let use0 = ast::SourceFile::parse(ra_fixture0)
605 .tree()
606 .syntax()
607 .descendants()
608 .find_map(ast::Use::cast)
609 .unwrap();
610
611 let use1 = ast::SourceFile::parse(ra_fixture1)
612 .tree()
613 .syntax()
614 .descendants()
615 .find_map(ast::Use::cast)
616 .unwrap();
617
618 let result = try_merge_imports(&use0, &use1, mb);
619 assert_eq!(result.map(|u| u.to_string()), None);
620}