workspacer_consolidate/
lib.rs1#[macro_use] mod imports; use imports::*;
3
4x!{compute_effective_range}
5x!{formatting}
6x!{consolidate_crate_interface}
7x!{consolidated_crate_interface}
8x!{consolidated_item}
9x!{consolidation_options}
10x!{crate_interface_item_serde}
11x!{crate_interface_item}
12x!{gather_all_attrs}
13x!{gather_assoc_type_aliases}
14x!{gather_crate_items}
15x!{gather_fn_item}
16x!{gather_impl_methods}
17x!{gather_items_in_node}
18x!{gather_module}
19x!{generate_impl_signature}
20x!{guess_is_function}
21x!{has_cfg_test_attr}
22x!{impl_block_interface}
23x!{interstitial_segment}
24x!{is_in_test_module}
25x!{leading_spaces}
26x!{maybe_build_enum}
27x!{maybe_build_function}
28x!{maybe_build_impl_block_node}
29x!{maybe_build_macro_call}
30x!{maybe_build_macro_rules}
31x!{maybe_build_module}
32x!{maybe_build_struct}
33x!{maybe_build_trait}
34x!{maybe_build_type_alias}
35x!{merge_doc_attrs}
36x!{merge}
37x!{module_interface}
38x!{skip_checks}
39x!{trim_to_60}
40x!{try_cast_and_build_item}
41
42#[cfg(test)]
43mod test_text_range {
44 use super::*;
45
46 fn gather_single_file_items(snippet: &str) -> Vec<ConsolidatedItem> {
48 let parse = SourceFile::parse(snippet, Edition::Edition2021);
50 let sf = parse.tree();
51
52 let opts = ConsolidationOptions::new()
54 .with_private_items()
55 .with_test_items()
56 .with_docs()
57 .with_fn_bodies()
58 .with_fn_bodies_in_tests();
59
60 let file_path = PathBuf::from("TEST_ONLY_file.rs");
62 let crate_path = PathBuf::from("TEST_ONLY_crate_root");
63
64 gather_crate_items(&sf, &opts, &file_path, &crate_path)
66 }
67
68 fn assert_ranges_match(
72 syntax_range: TextRange,
73 consolidated_range: TextRange,
74 context: &str,
75 ) {
76 assert_eq!(
77 syntax_range, consolidated_range,
78 "Mismatch in text_range for {}. Syntax node range = {:?}, item range = {:?}",
79 context, syntax_range, consolidated_range
80 );
81 }
82
83 #[test]
84 fn test_fn_text_range() {
85 let snippet = r#"
86 fn example_fn() {
87 let x = 10;
88 }
89 "#;
90 let items = gather_single_file_items(snippet);
91
92 assert_eq!(items.len(), 1, "Expected exactly one item (fn). Found: {:?}", items);
94 match &items[0] {
95 ConsolidatedItem::Fn(ci) => {
96 let syntax_range = ci.item().syntax().text_range();
98 let item_range = ci.text_range();
99 assert_ranges_match(syntax_range, *item_range, "fn example_fn");
100 },
101 other => panic!("Expected a single fn item, got {:?}", other),
102 }
103 }
104
105 #[test]
106 fn test_struct_text_range() {
107 let snippet = r#"
108 struct MyStruct {
109 field: i32,
110 }
111 "#;
112 let items = gather_single_file_items(snippet);
113 assert_eq!(items.len(), 1, "Expected one struct item");
114 match &items[0] {
115 ConsolidatedItem::Struct(ci) => {
116 let syntax_range = ci.item().syntax().text_range();
117 let item_range = ci.text_range();
118 assert_ranges_match(syntax_range, *item_range, "struct MyStruct");
119 },
120 other => panic!("Expected struct, got {:?}", other),
121 }
122 }
123
124 #[test]
125 fn test_enum_text_range() {
126 let snippet = r#"
127 enum Color {
128 Red,
129 Green,
130 Blue,
131 }
132 "#;
133 let items = gather_single_file_items(snippet);
134 assert_eq!(items.len(), 1, "Expected one enum item");
135 match &items[0] {
136 ConsolidatedItem::Enum(ci) => {
137 let syntax_range = ci.item().syntax().text_range();
138 assert_ranges_match(syntax_range, *ci.text_range(), "enum Color");
139 },
140 other => panic!("Expected enum, got {:?}", other),
141 }
142 }
143
144 #[test]
145 fn test_trait_text_range() {
146 let snippet = r#"
147 trait Example {
148 fn do_stuff(&self);
149 }
150 "#;
151 let items = gather_single_file_items(snippet);
152 assert_eq!(items.len(), 1);
153 match &items[0] {
154 ConsolidatedItem::Trait(ci) => {
155 let syntax_range = ci.item().syntax().text_range();
156 assert_ranges_match(syntax_range, *ci.text_range(), "trait Example");
157 },
158 other => panic!("Expected trait, got {:?}", other),
159 }
160 }
161
162 #[test]
163 fn test_type_alias_text_range() {
164 let snippet = r#"
165 type AliasA = i64;
166 "#;
167 let items = gather_single_file_items(snippet);
168 assert_eq!(items.len(), 1);
169 match &items[0] {
170 ConsolidatedItem::TypeAlias(ci) => {
171 let syntax_range = ci.item().syntax().text_range();
172 assert_ranges_match(syntax_range, *ci.text_range(), "type AliasA");
173 },
174 other => panic!("Expected type alias, got {:?}", other),
175 }
176 }
177
178 #[test]
179 fn test_macro_rules_text_range() {
180 let snippet = r#"
181 macro_rules! my_macro {
182 () => {};
183 }
184 "#;
185 let items = gather_single_file_items(snippet);
186 assert_eq!(items.len(), 1);
187 match &items[0] {
188 ConsolidatedItem::Macro(ci) => {
189 let syntax_range = ci.item().syntax().text_range();
190 assert_ranges_match(syntax_range, *ci.text_range(), "macro_rules my_macro");
191 },
192 other => panic!("Expected macro_rules, got {:?}", other),
193 }
194 }
195
196 #[test]
197 fn test_module_text_range() {
198 let snippet = r#"
199 mod submod {
200 fn inside() {}
201 }
202 "#;
203 let items = gather_single_file_items(snippet);
204 assert_eq!(items.len(), 1);
205 match &items[0] {
206 ConsolidatedItem::Module(mi) => {
207 let actual_range = mi.text_range();
215 let text = snippet;
218 let trimmed_len = text.trim().len() as u32;
219 assert!(actual_range.len() > 0.into());
221 },
222 other => panic!("Expected module, got {:?}", other),
223 }
224 }
225
226 #[test]
227 fn test_impl_block_text_range() {
228 let snippet = r#"
229 impl SomeTrait for Foo {
230 fn method(&self) {}
231 }
232 "#;
233 let items = gather_single_file_items(snippet);
234 assert_eq!(items.len(), 1);
235 match &items[0] {
236 ConsolidatedItem::ImplBlock(ib) => {
237 let actual_range = ib.text_range();
238 assert!(actual_range.len() > 0.into(), "Impl block range should be > 0");
240 },
241 other => panic!("Expected impl block, got {:?}", other),
242 }
243 }
244}