1#[cfg(test)]
2mod tests {
3 use crate::*;
4
5 fn create_test_function(name: &str, is_public: bool, has_test_attr: bool) -> FunctionUnit {
7 let mut attrs = Vec::new();
8 if has_test_attr {
9 attrs.push("#[test]".to_string());
10 }
11
12 FunctionUnit {
13 name: name.to_string(),
14 attributes: attrs,
15 visibility: if is_public {
16 Visibility::Public
17 } else {
18 Visibility::Private
19 },
20 doc: Some(format!("Documentation for {}", name)),
21 signature: Some(format!("fn {}()", name)),
22 body: Some("{ /* function body */ }".to_string()),
23 source: Some(format!("fn {}() {{ /* function body */ }}", name)),
24 }
25 }
26
27 fn create_test_struct(name: &str, is_public: bool) -> StructUnit {
29 let mut methods = Vec::new();
30 methods.push(create_test_function(
31 &format!("{}_method", name.to_lowercase()),
32 true,
33 false,
34 ));
35 methods.push(create_test_function(
37 &format!("{}_private_method", name.to_lowercase()),
38 false,
39 false,
40 ));
41
42 let visibility = if is_public {
43 Visibility::Public
44 } else {
45 Visibility::Private
46 };
47 StructUnit {
48 name: name.to_string(),
49 head: format!("{} struct {}", visibility.as_str(LanguageType::Rust), name),
50 attributes: Vec::new(),
51 visibility,
52 doc: Some(format!("Documentation for {}", name)),
53 fields: Vec::new(),
54 methods,
55 source: Some(format!("struct {} {{ field: i32 }}", name)),
56 }
57 }
58
59 fn create_test_module(name: &str, is_public: bool, is_test: bool) -> ModuleUnit {
61 let functions = vec![
62 create_test_function("module_function", true, false),
63 create_test_function("module_private_function", false, false),
65 ];
66
67 let structs = vec![create_test_struct("ModuleStruct", true)];
68
69 let mut attributes = Vec::new();
70 if is_test {
71 attributes.push("#[cfg(test)]".to_string());
72 }
73
74 let mut declares = Vec::new();
76 declares.push(DeclareStatements {
77 source: "use std::io;".to_string(),
78 kind: DeclareKind::Use,
79 });
80
81 ModuleUnit {
82 name: name.to_string(),
83 attributes,
84 doc: Some(format!("Documentation for module {}", name)),
85 visibility: if is_public {
86 Visibility::Public
87 } else {
88 Visibility::Private
89 },
90 functions,
91 structs,
92 traits: Vec::new(),
93 impls: Vec::new(),
94 submodules: Vec::new(),
95 declares,
96 source: Some(format!("mod {} {{ /* module contents */ }}", name)),
97 }
98 }
99
100 fn create_test_impl(is_trait_impl: bool) -> ImplUnit {
102 let methods = vec![
103 create_test_function("public_method", true, false),
105 create_test_function("private_method", false, false),
106 ];
107
108 let (head, source) = if is_trait_impl {
109 (
110 "impl SomeTrait for SomeStruct".to_string(),
111 "impl SomeTrait for SomeStruct { /* impl body */ }".to_string(),
112 )
113 } else {
114 (
115 "impl SomeStruct".to_string(),
116 "impl SomeStruct { /* impl body */ }".to_string(),
117 )
118 };
119
120 ImplUnit {
121 attributes: Vec::new(),
122 doc: Some("Documentation for implementation".to_string()),
123 head,
124 methods,
125 source: Some(source),
126 }
127 }
128
129 fn create_private_methods_impl() -> ImplUnit {
131 ImplUnit {
132 attributes: Vec::new(),
133 doc: Some("Documentation for implementation with private methods".to_string()),
134 head: "impl StructWithPrivateMethods".to_string(),
135 methods: vec![
136 create_test_function("private_method1", false, false),
137 create_test_function("private_method2", false, false),
138 ],
139 source: Some("impl StructWithPrivateMethods { /* impl body */ }".to_string()),
140 }
141 }
142
143 fn create_test_enum(name: &str, is_public: bool) -> StructUnit {
145 let visibility = if is_public {
146 Visibility::Public
147 } else {
148 Visibility::Private
149 };
150 let head = format!("{} enum {}", visibility.as_str(LanguageType::Rust), name);
151 let source = format!(
152 "/// Docs for {}\n{} {{
153 VariantA,
154 VariantB(String),
155}}",
156 name, head
157 );
158 StructUnit {
159 name: name.to_string(),
160 head,
161 visibility,
162 doc: Some(format!("Docs for {}", name)),
163 attributes: vec![],
164 fields: vec![], methods: vec![],
166 source: Some(source),
167 }
168 }
169
170 #[test]
171 fn test_function_formatter_default() {
172 let function = create_test_function("test_function", true, false);
173 let formatted = function
174 .format(&BankStrategy::Default, LanguageType::Rust)
175 .unwrap();
176 assert!(formatted.contains("fn test_function()"));
177 assert!(formatted.contains("/* function body */"));
178 }
179
180 #[test]
181 fn test_function_formatter_no_tests() {
182 let function = create_test_function("regular_function", true, false);
184 let formatted = function
185 .format(&BankStrategy::NoTests, LanguageType::Rust)
186 .unwrap();
187 assert!(formatted.contains("fn regular_function()"));
188 assert!(formatted.contains("/* function body */"));
189
190 let test_function = create_test_function("test_function", true, true);
192 let formatted = test_function
193 .format(&BankStrategy::NoTests, LanguageType::Rust)
194 .unwrap();
195 assert!(formatted.is_empty());
196 }
197
198 #[test]
199 fn test_function_formatter_summary() {
200 let public_function = create_test_function("public_function", true, false);
202 let formatted = public_function
203 .format(&BankStrategy::Summary, LanguageType::Rust)
204 .unwrap();
205 assert!(formatted.contains("fn public_function()"));
206 assert!(!formatted.contains("/* function body */"));
207 assert!(formatted.contains("{ ... }"));
208
209 let private_function = create_test_function("private_function", false, false);
211 let formatted = private_function
212 .format(&BankStrategy::Summary, LanguageType::Rust)
213 .unwrap();
214 assert!(formatted.is_empty());
215 }
216
217 #[test]
218 fn test_struct_formatter_default() {
219 let struct_unit = create_test_struct("TestStruct", true);
220 let formatted = struct_unit
221 .format(&BankStrategy::Default, LanguageType::Rust)
222 .unwrap();
223 assert!(formatted.contains("struct TestStruct"));
224 assert!(formatted.contains("field: i32"));
225 }
226
227 #[test]
228 fn test_struct_formatter_summary() {
229 let mut public_struct = create_test_struct("PublicStruct", true);
231
232 let field = FieldUnit {
234 name: "field".to_string(),
235 doc: Some("Field documentation".to_string()),
236 attributes: vec![],
237 source: Some("pub field: i32".to_string()),
238 };
239 public_struct.fields.push(field);
240
241 let formatted = public_struct
242 .format(&BankStrategy::Summary, LanguageType::Rust)
243 .unwrap();
244
245 assert!(formatted.contains("struct PublicStruct"));
246 assert!(
247 formatted.contains("pub field: i32"),
248 "Summary should include fields"
249 );
250 assert!(
251 formatted.contains("fn publicstruct_method"),
252 "Summary should include public methods"
253 );
254 assert!(
255 !formatted.contains("fn publicstruct_private_method"),
256 "Summary should not include private methods"
257 );
258
259 let private_struct = create_test_struct("PrivateStruct", false);
261 let formatted = private_struct
262 .format(&BankStrategy::Summary, LanguageType::Rust)
263 .unwrap();
264 assert!(
265 formatted.is_empty(),
266 "Private structs should be skipped in summary mode"
267 );
268 }
269
270 #[test]
271 fn test_module_formatter_default() {
272 let module = create_test_module("test_module", true, false);
273 let formatted = module
274 .format(&BankStrategy::Default, LanguageType::Rust)
275 .unwrap();
276 assert!(formatted.contains("mod test_module"));
277 assert!(formatted.contains("/* module contents */"));
278 }
279
280 #[test]
281 fn test_module_formatter_no_tests() {
282 let module = create_test_module("regular_module", true, false);
284 let formatted = module
285 .format(&BankStrategy::NoTests, LanguageType::Rust)
286 .unwrap();
287 assert!(formatted.contains("pub mod regular_module"));
288 assert!(formatted.contains("fn module_function"));
289 assert!(formatted.contains("fn module_private_function"));
290 assert!(formatted.contains("struct ModuleStruct"));
291 assert!(formatted.contains("use std::io;"));
292
293 let test_module = create_test_module("test_module", true, true);
295 let formatted = test_module
296 .format(&BankStrategy::NoTests, LanguageType::Rust)
297 .unwrap();
298 assert!(formatted.contains("#[cfg(test)]"));
299 assert!(formatted.contains("pub mod test_module"));
300 }
301
302 #[test]
303 fn test_module_formatter_summary() {
304 let public_module = create_test_module("public_module", true, false);
306 let formatted = public_module
307 .format(&BankStrategy::Summary, LanguageType::Rust)
308 .unwrap();
309 assert!(formatted.contains("pub mod public_module"));
310 assert!(formatted.contains("fn module_function()"));
311 assert!(!formatted.contains("/* function body */"));
313
314 let private_module = create_test_module("private_module", false, false);
316 let formatted = private_module
317 .format(&BankStrategy::Summary, LanguageType::Rust)
318 .unwrap();
319 assert!(formatted.is_empty());
320 }
321
322 #[test]
323 fn test_struct_formatter_no_tests() {
324 let struct_unit = create_test_struct("TestStruct", true);
326 let formatted = struct_unit
327 .format(&BankStrategy::NoTests, LanguageType::Rust)
328 .unwrap();
329
330 assert!(formatted.contains("struct TestStruct { field: i32 }"));
332 assert!(!formatted.contains("fn teststruct_method()"));
334 assert!(!formatted.contains("fn teststruct_private_method()"));
335 }
336
337 #[test]
338 fn test_regular_impl_formatter_summary() {
339 let impl_unit = create_test_impl(false);
341 let formatted = impl_unit
342 .format(&BankStrategy::Summary, LanguageType::Rust)
343 .unwrap();
344
345 assert!(formatted.contains("impl SomeStruct"));
348 assert!(formatted.contains("fn public_method"));
349 assert!(!formatted.contains("fn private_method"));
350 }
351
352 #[test]
353 fn test_trait_impl_formatter_summary() {
354 let impl_unit = create_test_impl(true);
356 let formatted = impl_unit
357 .format(&BankStrategy::Summary, LanguageType::Rust)
358 .unwrap();
359
360 assert!(formatted.contains("impl SomeTrait for SomeStruct"));
363 assert!(formatted.contains("fn public_method"));
364 assert!(
365 !formatted.contains("fn private_method"),
366 "Private method should be excluded in trait impl summary"
367 );
368 assert!(
370 formatted.contains("public_method() { ... }"),
371 "Public method body not summarized"
372 );
373 assert!(
374 !formatted.contains("/* function body */"),
375 "Full function body should not be present"
376 );
377 }
378
379 #[test]
380 fn test_impl_formatter_no_tests() {
381 let regular_impl = create_test_impl(false);
383 let formatted = regular_impl
384 .format(&BankStrategy::NoTests, LanguageType::Rust)
385 .unwrap();
386 assert!(formatted.contains("fn public_method"));
387 assert!(formatted.contains("fn private_method"));
388
389 let trait_impl = create_test_impl(true);
390 let formatted = trait_impl
391 .format(&BankStrategy::NoTests, LanguageType::Rust)
392 .unwrap();
393 assert!(formatted.contains("fn public_method"));
394 assert!(formatted.contains("fn private_method"));
395 }
396
397 #[test]
398 fn test_impl_with_only_private_methods_summary() {
399 let impl_unit = create_private_methods_impl();
401 let formatted = impl_unit
402 .format(&BankStrategy::Summary, LanguageType::Rust)
403 .unwrap();
404
405 assert!(formatted.is_empty());
407
408 let formatted = impl_unit
410 .format(&BankStrategy::NoTests, LanguageType::Rust)
411 .unwrap();
412 assert!(!formatted.is_empty());
413 assert!(formatted.contains("fn private_method1"));
414 assert!(formatted.contains("fn private_method2"));
415 }
416
417 #[test]
418 fn test_file_unit_formatter() {
419 let mut file_unit = FileUnit {
420 path: std::path::PathBuf::from("test_file.rs"),
421 ..Default::default()
422 };
423
424 file_unit
426 .modules
427 .push(create_test_module("public_module", true, false));
428 file_unit
429 .modules
430 .push(create_test_module("test_module", true, true));
431
432 file_unit
434 .functions
435 .push(create_test_function("public_function", true, false));
436 file_unit
437 .functions
438 .push(create_test_function("private_function", false, false));
439 file_unit
440 .functions
441 .push(create_test_function("test_function", true, true));
442
443 file_unit
445 .structs
446 .push(create_test_struct("PublicStruct", true));
447 file_unit
448 .structs
449 .push(create_test_struct("PrivateStruct", false));
450
451 file_unit.source = Some("// This is the entire file content".to_string());
453 let formatted = file_unit
454 .format(&BankStrategy::Default, LanguageType::Rust)
455 .unwrap();
456 assert_eq!(formatted, "// This is the entire file content");
457
458 let formatted = file_unit
460 .format(&BankStrategy::NoTests, LanguageType::Rust)
461 .unwrap();
462 assert!(formatted.contains("pub mod public_module"));
463 assert!(!formatted.contains("fn test_function"));
464 assert!(formatted.contains("fn public_function"));
465 assert!(formatted.contains("fn private_function"));
466 assert!(formatted.contains("struct PublicStruct"));
467 assert!(formatted.contains("struct PrivateStruct"));
468
469 let formatted = file_unit
471 .format(&BankStrategy::Summary, LanguageType::Rust)
472 .unwrap();
473 assert!(formatted.contains("pub mod public_module"));
474 assert!(!formatted.contains("mod private_module"));
475 assert!(formatted.contains("fn public_function()"));
476 assert!(!formatted.contains("fn private_function"));
477 assert!(formatted.contains("struct PublicStruct"));
478 assert!(!formatted.contains("struct PrivateStruct"));
479 }
480
481 #[test]
482 fn test_file_unit_no_tests_includes_all() {
483 let mut file_unit = FileUnit {
484 path: std::path::PathBuf::from("test_file.rs"),
485 ..Default::default()
486 };
487
488 file_unit
490 .modules
491 .push(create_test_module("public_module", true, false));
492 file_unit
493 .modules
494 .push(create_test_module("private_module", false, false));
495 file_unit
496 .modules
497 .push(create_test_module("test_module", true, true));
498
499 file_unit
501 .functions
502 .push(create_test_function("public_function", true, false));
503 file_unit
504 .functions
505 .push(create_test_function("private_function", false, false));
506 file_unit
507 .functions
508 .push(create_test_function("test_function", true, true));
509
510 file_unit
512 .structs
513 .push(create_test_struct("PublicStruct", true));
514 file_unit
515 .structs
516 .push(create_test_struct("PrivateStruct", false));
517
518 file_unit.declares.push(DeclareStatements {
520 source: "use std::collections::HashMap;".to_string(),
521 kind: DeclareKind::Use,
522 });
523
524 let formatted = file_unit
526 .format(&BankStrategy::NoTests, LanguageType::Rust)
527 .unwrap();
528
529 assert!(formatted.contains("pub mod public_module"));
531 assert!(formatted.contains("mod private_module"));
532 assert!(!formatted.contains("fn test_function"));
533 assert!(formatted.contains("fn public_function"));
534 assert!(formatted.contains("fn private_function"));
535 assert!(formatted.contains("struct PublicStruct"));
536 assert!(formatted.contains("struct PrivateStruct"));
537 assert!(formatted.contains("use std::collections::HashMap;"));
538
539 assert!(!formatted.contains("fn publicstruct_private_method()"));
541 }
542
543 #[test]
544 fn test_enum_formatter_summary() {
545 let public_enum = create_test_enum("PublicEnum", true);
546 let formatted = public_enum
547 .format(&BankStrategy::Summary, LanguageType::Rust)
548 .unwrap();
549
550 assert!(formatted.contains("/// Docs for PublicEnum"));
552 assert!(formatted.contains("pub enum PublicEnum"));
553 assert!(!formatted.contains("VariantA,"));
555 assert!(!formatted.contains("VariantB(String),"));
556
557 let private_enum = create_test_enum("PrivateEnum", false);
558 let formatted = private_enum
559 .format(&BankStrategy::Summary, LanguageType::Rust)
560 .unwrap();
561 assert!(formatted.is_empty());
563 }
564}