use super::bootstrap::{get_bootstrap_patterns, BootstrapStats};
use std::collections::{HashMap, HashSet};
#[test]
fn deep_bootstrap_returns_vec_not_empty() {
let patterns = get_bootstrap_patterns();
assert!(!patterns.is_empty());
}
#[test]
fn deep_bootstrap_exact_count_25() {
let patterns = get_bootstrap_patterns();
assert_eq!(patterns.len(), 25);
}
#[test]
fn deep_bootstrap_all_error_codes_start_with_e() {
for p in get_bootstrap_patterns() {
assert!(p.error_code.starts_with('E'), "Bad error_code: {}", p.error_code);
}
}
#[test]
fn deep_bootstrap_all_error_codes_are_5_chars() {
for p in get_bootstrap_patterns() {
assert_eq!(p.error_code.len(), 5, "Bad length: {}", p.error_code);
}
}
#[test]
fn deep_bootstrap_all_error_codes_numeric_suffix() {
for p in get_bootstrap_patterns() {
let suffix = &p.error_code[1..];
assert!(
suffix.chars().all(|c| c.is_ascii_digit()),
"Non-numeric suffix in: {}",
p.error_code
);
}
}
#[test]
fn deep_e0308_count() {
let count = get_bootstrap_patterns().iter().filter(|p| p.error_code == "E0308").count();
assert_eq!(count, 12);
}
#[test]
fn deep_e0133_count() {
let count = get_bootstrap_patterns().iter().filter(|p| p.error_code == "E0133").count();
assert_eq!(count, 3);
}
#[test]
fn deep_e0382_count() {
let count = get_bootstrap_patterns().iter().filter(|p| p.error_code == "E0382").count();
assert_eq!(count, 3);
}
#[test]
fn deep_e0499_count() {
let count = get_bootstrap_patterns().iter().filter(|p| p.error_code == "E0499").count();
assert_eq!(count, 2);
}
#[test]
fn deep_e0506_count() {
let count = get_bootstrap_patterns().iter().filter(|p| p.error_code == "E0506").count();
assert_eq!(count, 1);
}
#[test]
fn deep_e0597_count() {
let count = get_bootstrap_patterns().iter().filter(|p| p.error_code == "E0597").count();
assert_eq!(count, 2);
}
#[test]
fn deep_e0515_count() {
let count = get_bootstrap_patterns().iter().filter(|p| p.error_code == "E0515").count();
assert_eq!(count, 2);
}
#[test]
fn deep_exactly_7_distinct_error_codes() {
let codes: HashSet<&str> = get_bootstrap_patterns().iter().map(|p| p.error_code).collect();
assert_eq!(codes.len(), 7);
}
#[test]
fn deep_error_code_sum_equals_total() {
let patterns = get_bootstrap_patterns();
let mut by_code: HashMap<&str, usize> = HashMap::new();
for p in &patterns {
*by_code.entry(p.error_code).or_default() += 1;
}
let sum: usize = by_code.values().sum();
assert_eq!(sum, patterns.len());
}
#[test]
fn deep_exactly_21_distinct_decisions() {
let decisions: HashSet<&str> = get_bootstrap_patterns().iter().map(|p| p.decision).collect();
assert_eq!(decisions.len(), 21);
}
#[test]
fn deep_decision_type_coercion() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "type_coercion").collect();
assert_eq!(ps.len(), 2);
assert!(ps.iter().all(|p| p.error_code == "E0308"));
}
#[test]
fn deep_decision_pointer_to_reference() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "pointer_to_reference")
.collect();
assert_eq!(ps.len(), 2);
assert!(ps.iter().any(|p| p.fix_diff.contains("*mut")));
assert!(ps.iter().any(|p| p.fix_diff.contains("*const")));
}
#[test]
fn deep_decision_mutable_reference() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "mutable_reference")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("&mut"));
}
#[test]
fn deep_decision_unsafe_deref() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "unsafe_deref").collect();
assert_eq!(ps.len(), 2);
for p in &ps {
assert_eq!(p.error_code, "E0133");
assert!(p.fix_diff.contains("unsafe"));
}
}
#[test]
fn deep_decision_unsafe_extern() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "unsafe_extern").collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("extern_fn"));
}
#[test]
fn deep_decision_clone_before_move() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "clone_before_move")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains(".clone()"));
assert_eq!(ps[0].error_code, "E0382");
}
#[test]
fn deep_decision_borrow_instead_of_move() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "borrow_instead_of_move")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("&x"));
}
#[test]
fn deep_decision_borrow_parameter() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "borrow_parameter").collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("&String"));
}
#[test]
fn deep_decision_sequential_mutable_borrow() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "sequential_mutable_borrow")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("drop"));
}
#[test]
fn deep_decision_use_stdlib_method() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "use_stdlib_method")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("arr.swap"));
}
#[test]
fn deep_decision_reorder_borrow() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "reorder_borrow").collect();
assert_eq!(ps.len(), 1);
assert_eq!(ps[0].error_code, "E0506");
}
#[test]
fn deep_decision_extend_lifetime() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "extend_lifetime").collect();
assert_eq!(ps.len(), 1);
assert_eq!(ps[0].error_code, "E0597");
assert!(ps[0].description.contains("outer scope"));
}
#[test]
fn deep_decision_return_owned() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "return_owned").collect();
assert_eq!(ps.len(), 2);
let codes: HashSet<&str> = ps.iter().map(|p| p.error_code).collect();
assert!(codes.contains("E0597"));
assert!(codes.contains("E0515"));
}
#[test]
fn deep_decision_clone_return() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "clone_return").collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains(".clone()"));
assert_eq!(ps[0].error_code, "E0515");
}
#[test]
fn deep_decision_array_to_slice() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "array_to_slice").collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("&[i32]"));
}
#[test]
fn deep_decision_bounds_checked_access() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "bounds_checked_access")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains(".get(i)"));
assert!(ps[0].fix_diff.contains("unwrap_or"));
}
#[test]
fn deep_decision_safe_pointer_arithmetic() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "safe_pointer_arithmetic")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("wrapping_add"));
}
#[test]
fn deep_decision_malloc_to_box() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "malloc_to_box").collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("Box::new"));
assert!(ps[0].fix_diff.contains("malloc"));
}
#[test]
fn deep_decision_malloc_array_to_vec() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "malloc_array_to_vec")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("Vec::with_capacity"));
}
#[test]
fn deep_decision_arrow_to_dot() {
let ps: Vec<_> =
get_bootstrap_patterns().into_iter().filter(|p| p.decision == "arrow_to_dot").collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("p->field"));
assert!(ps[0].fix_diff.contains("p.field"));
}
#[test]
fn deep_decision_nullable_to_option() {
let ps: Vec<_> = get_bootstrap_patterns()
.into_iter()
.filter(|p| p.decision == "nullable_to_option")
.collect();
assert_eq!(ps.len(), 1);
assert!(ps[0].fix_diff.contains("Option<Box<Node>>"));
}
#[test]
fn deep_all_fix_diffs_nonempty() {
for p in get_bootstrap_patterns() {
assert!(!p.fix_diff.is_empty(), "Empty fix_diff for {}", p.decision);
}
}
#[test]
fn deep_all_fix_diffs_have_minus_line() {
for p in get_bootstrap_patterns() {
assert!(
p.fix_diff.contains("- ") || p.fix_diff.starts_with('-'),
"fix_diff missing minus line for {}: {}",
p.decision,
p.fix_diff
);
}
}
#[test]
fn deep_all_fix_diffs_have_plus_line() {
for p in get_bootstrap_patterns() {
assert!(
p.fix_diff.contains("+ ") || p.fix_diff.starts_with('+'),
"fix_diff missing plus line for {}: {}",
p.decision,
p.fix_diff
);
}
}
#[test]
fn deep_all_fix_diffs_contain_newline() {
for p in get_bootstrap_patterns() {
assert!(
p.fix_diff.contains('\n'),
"fix_diff should have newline for {}: {}",
p.decision,
p.fix_diff
);
}
}
#[test]
fn deep_all_descriptions_nonempty() {
for p in get_bootstrap_patterns() {
assert!(!p.description.is_empty(), "Empty description for {}", p.decision);
}
}
#[test]
fn deep_all_descriptions_start_uppercase() {
for p in get_bootstrap_patterns() {
let first = p.description.chars().next().unwrap();
assert!(first.is_uppercase(), "Description should start uppercase: '{}'", p.description);
}
}
#[test]
fn deep_all_decisions_snake_case() {
for p in get_bootstrap_patterns() {
assert!(
p.decision.chars().all(|c| c.is_lowercase() || c == '_'),
"Decision not snake_case: '{}'",
p.decision
);
}
}
#[test]
fn deep_pattern_0_type_cast() {
let p = &get_bootstrap_patterns()[0];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "type_coercion");
assert!(p.fix_diff.contains("as i32"));
assert!(p.description.contains("explicit type cast"));
}
#[test]
fn deep_pattern_1_mut_ptr_to_ref() {
let p = &get_bootstrap_patterns()[1];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "pointer_to_reference");
assert!(p.fix_diff.contains("*mut i32"));
assert!(p.fix_diff.contains("&mut i32"));
assert!(p.description.contains("mutable reference"));
}
#[test]
fn deep_pattern_2_const_ptr_to_ref() {
let p = &get_bootstrap_patterns()[2];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "pointer_to_reference");
assert!(p.fix_diff.contains("*const i32"));
assert!(p.fix_diff.contains("&i32"));
assert!(p.description.contains("immutable reference"));
}
#[test]
fn deep_pattern_3_mutable_swap_ref() {
let p = &get_bootstrap_patterns()[3];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "mutable_reference");
assert!(p.fix_diff.contains("swap"));
assert!(p.fix_diff.contains("&mut x"));
}
#[test]
fn deep_pattern_4_exit_coercion() {
let p = &get_bootstrap_patterns()[4];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "type_coercion");
assert!(p.fix_diff.contains("std::process::exit"));
assert!(p.fix_diff.contains("as i32"));
}
#[test]
fn deep_pattern_5_unsafe_write() {
let p = &get_bootstrap_patterns()[5];
assert_eq!(p.error_code, "E0133");
assert_eq!(p.decision, "unsafe_deref");
assert!(p.fix_diff.contains("*ptr = value"));
assert!(p.fix_diff.contains("unsafe"));
}
#[test]
fn deep_pattern_6_unsafe_read() {
let p = &get_bootstrap_patterns()[6];
assert_eq!(p.error_code, "E0133");
assert_eq!(p.decision, "unsafe_deref");
assert!(p.fix_diff.contains("let x = *ptr"));
assert!(p.fix_diff.contains("unsafe { *ptr }"));
}
#[test]
fn deep_pattern_7_unsafe_extern_fn() {
let p = &get_bootstrap_patterns()[7];
assert_eq!(p.error_code, "E0133");
assert_eq!(p.decision, "unsafe_extern");
assert!(p.fix_diff.contains("extern_fn()"));
assert!(p.fix_diff.contains("unsafe { extern_fn(); }"));
}
#[test]
fn deep_pattern_8_clone_move() {
let p = &get_bootstrap_patterns()[8];
assert_eq!(p.error_code, "E0382");
assert_eq!(p.decision, "clone_before_move");
assert!(p.fix_diff.contains("value.clone()"));
}
#[test]
fn deep_pattern_9_borrow_not_move() {
let p = &get_bootstrap_patterns()[9];
assert_eq!(p.error_code, "E0382");
assert_eq!(p.decision, "borrow_instead_of_move");
assert!(p.fix_diff.contains("let y = &x"));
}
#[test]
fn deep_pattern_10_borrow_param() {
let p = &get_bootstrap_patterns()[10];
assert_eq!(p.error_code, "E0382");
assert_eq!(p.decision, "borrow_parameter");
assert!(p.fix_diff.contains("fn take(s: &String)"));
}
#[test]
fn deep_pattern_11_seq_mut_borrow() {
let p = &get_bootstrap_patterns()[11];
assert_eq!(p.error_code, "E0499");
assert_eq!(p.decision, "sequential_mutable_borrow");
assert!(p.fix_diff.contains("drop(a)"));
}
#[test]
fn deep_pattern_12_stdlib_swap() {
let p = &get_bootstrap_patterns()[12];
assert_eq!(p.error_code, "E0499");
assert_eq!(p.decision, "use_stdlib_method");
assert!(p.fix_diff.contains("arr.swap(i, j)"));
}
#[test]
fn deep_pattern_13_reorder() {
let p = &get_bootstrap_patterns()[13];
assert_eq!(p.error_code, "E0506");
assert_eq!(p.decision, "reorder_borrow");
assert!(p.fix_diff.contains("x = 5"));
}
#[test]
fn deep_pattern_14_extend_life() {
let p = &get_bootstrap_patterns()[14];
assert_eq!(p.error_code, "E0597");
assert_eq!(p.decision, "extend_lifetime");
assert!(p.description.contains("outer scope"));
}
#[test]
fn deep_pattern_15_return_owned_e0597() {
let p = &get_bootstrap_patterns()[15];
assert_eq!(p.error_code, "E0597");
assert_eq!(p.decision, "return_owned");
assert!(p.fix_diff.contains("-> i32"));
}
#[test]
fn deep_pattern_16_return_owned_e0515() {
let p = &get_bootstrap_patterns()[16];
assert_eq!(p.error_code, "E0515");
assert_eq!(p.decision, "return_owned");
assert!(p.fix_diff.contains("-> Vec<i32>"));
}
#[test]
fn deep_pattern_17_clone_return_local() {
let p = &get_bootstrap_patterns()[17];
assert_eq!(p.error_code, "E0515");
assert_eq!(p.decision, "clone_return");
assert!(p.fix_diff.contains("local.clone()"));
}
#[test]
fn deep_pattern_18_array_to_slice_conv() {
let p = &get_bootstrap_patterns()[18];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "array_to_slice");
assert!(p.fix_diff.contains("&[i32]"));
assert!(p.description.contains("slice"));
}
#[test]
fn deep_pattern_19_bounds_check() {
let p = &get_bootstrap_patterns()[19];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "bounds_checked_access");
assert!(p.fix_diff.contains("arr.get(i).copied().unwrap_or(0)"));
}
#[test]
fn deep_pattern_20_safe_ptr_arith() {
let p = &get_bootstrap_patterns()[20];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "safe_pointer_arithmetic");
assert!(p.fix_diff.contains("ptr.wrapping_add(offset)"));
}
#[test]
fn deep_pattern_21_malloc_box() {
let p = &get_bootstrap_patterns()[21];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "malloc_to_box");
assert!(p.fix_diff.contains("Box::new(value)"));
assert!(p.fix_diff.contains("malloc(size)"));
}
#[test]
fn deep_pattern_22_malloc_vec() {
let p = &get_bootstrap_patterns()[22];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "malloc_array_to_vec");
assert!(p.fix_diff.contains("Vec::with_capacity(n)"));
}
#[test]
fn deep_pattern_23_arrow_dot() {
let p = &get_bootstrap_patterns()[23];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "arrow_to_dot");
assert!(p.fix_diff.contains("p->field"));
assert!(p.fix_diff.contains("p.field"));
}
#[test]
fn deep_pattern_24_nullable_option() {
let p = &get_bootstrap_patterns()[24];
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "nullable_to_option");
assert!(p.fix_diff.contains("Option<Box<Node>>"));
assert!(p.fix_diff.contains("struct Node *next"));
}
#[test]
fn deep_stats_from_patterns_total() {
let stats = BootstrapStats::from_patterns();
assert_eq!(stats.total_patterns, 25);
}
#[test]
fn deep_stats_error_code_map_size() {
let stats = BootstrapStats::from_patterns();
assert_eq!(stats.by_error_code.len(), 7);
}
#[test]
fn deep_stats_decision_map_size() {
let stats = BootstrapStats::from_patterns();
assert_eq!(stats.by_decision.len(), 21);
}
#[test]
fn deep_stats_error_e0308_is_12() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_error_code.get("E0308").unwrap(), 12);
}
#[test]
fn deep_stats_error_e0133_is_3() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_error_code.get("E0133").unwrap(), 3);
}
#[test]
fn deep_stats_error_e0382_is_3() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_error_code.get("E0382").unwrap(), 3);
}
#[test]
fn deep_stats_error_e0499_is_2() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_error_code.get("E0499").unwrap(), 2);
}
#[test]
fn deep_stats_error_e0506_is_1() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_error_code.get("E0506").unwrap(), 1);
}
#[test]
fn deep_stats_error_e0597_is_2() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_error_code.get("E0597").unwrap(), 2);
}
#[test]
fn deep_stats_error_e0515_is_2() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_error_code.get("E0515").unwrap(), 2);
}
#[test]
fn deep_stats_decision_type_coercion_is_2() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_decision.get("type_coercion").unwrap(), 2);
}
#[test]
fn deep_stats_decision_return_owned_is_2() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_decision.get("return_owned").unwrap(), 2);
}
#[test]
fn deep_stats_decision_pointer_to_reference_is_2() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_decision.get("pointer_to_reference").unwrap(), 2);
}
#[test]
fn deep_stats_decision_unsafe_deref_is_2() {
let stats = BootstrapStats::from_patterns();
assert_eq!(*stats.by_decision.get("unsafe_deref").unwrap(), 2);
}
#[test]
fn deep_stats_singleton_decisions_all_have_count_1() {
let stats = BootstrapStats::from_patterns();
let singletons = [
"mutable_reference",
"unsafe_extern",
"clone_before_move",
"borrow_instead_of_move",
"borrow_parameter",
"sequential_mutable_borrow",
"use_stdlib_method",
"reorder_borrow",
"extend_lifetime",
"clone_return",
"array_to_slice",
"bounds_checked_access",
"safe_pointer_arithmetic",
"malloc_to_box",
"malloc_array_to_vec",
"arrow_to_dot",
"nullable_to_option",
];
for name in singletons {
assert_eq!(
*stats.by_decision.get(name).unwrap(),
1,
"Decision {} should have count 1",
name
);
}
}
#[test]
fn deep_stats_pretty_contains_header() {
let pretty = BootstrapStats::from_patterns().to_string_pretty();
assert!(pretty.contains("Bootstrap Patterns: 25"));
}
#[test]
fn deep_stats_pretty_contains_error_section() {
let pretty = BootstrapStats::from_patterns().to_string_pretty();
assert!(pretty.contains("By Error Code:"));
}
#[test]
fn deep_stats_pretty_contains_decision_section() {
let pretty = BootstrapStats::from_patterns().to_string_pretty();
assert!(pretty.contains("By Decision Type:"));
}
#[test]
fn deep_stats_pretty_error_codes_sorted() {
let pretty = BootstrapStats::from_patterns().to_string_pretty();
let pos_133 = pretty.find("E0133").unwrap();
let pos_308 = pretty.find("E0308").unwrap();
let pos_382 = pretty.find("E0382").unwrap();
let pos_499 = pretty.find("E0499").unwrap();
let pos_506 = pretty.find("E0506").unwrap();
let pos_597 = pretty.find("E0597").unwrap();
assert!(pos_133 < pos_308);
assert!(pos_308 < pos_382);
assert!(pos_382 < pos_499);
assert!(pos_499 < pos_506);
assert!(pos_506 < pos_597);
}
#[test]
fn deep_stats_pretty_has_e0308_12() {
let pretty = BootstrapStats::from_patterns().to_string_pretty();
assert!(pretty.contains("E0308: 12"));
}
#[test]
fn deep_stats_pretty_has_e0133_3() {
let pretty = BootstrapStats::from_patterns().to_string_pretty();
assert!(pretty.contains("E0133: 3"));
}
#[test]
fn deep_stats_pretty_decisions_descending() {
let pretty = BootstrapStats::from_patterns().to_string_pretty();
let dec_start = pretty.find("By Decision Type:").unwrap();
let section = &pretty[dec_start..];
let tc_pos = section.find("type_coercion").unwrap();
let ad_pos = section.find("arrow_to_dot").unwrap();
assert!(tc_pos < ad_pos);
}
#[test]
fn deep_stats_default_zeroed() {
let stats = BootstrapStats::default();
assert_eq!(stats.total_patterns, 0);
assert!(stats.by_error_code.is_empty());
assert!(stats.by_decision.is_empty());
}
#[test]
fn deep_stats_debug_output() {
let stats = BootstrapStats::from_patterns();
let dbg = format!("{:?}", stats);
assert!(dbg.contains("BootstrapStats"));
assert!(dbg.contains("total_patterns"));
assert!(dbg.contains("by_error_code"));
assert!(dbg.contains("by_decision"));
}
#[test]
fn deep_pattern_debug_output() {
let p = &get_bootstrap_patterns()[0];
let dbg = format!("{:?}", p);
assert!(dbg.contains("BootstrapPattern"));
assert!(dbg.contains("E0308"));
assert!(dbg.contains("type_coercion"));
}
#[test]
fn deep_pattern_clone_preserves_fields() {
let p = get_bootstrap_patterns()[0].clone();
assert_eq!(p.error_code, "E0308");
assert_eq!(p.decision, "type_coercion");
assert!(!p.fix_diff.is_empty());
assert!(!p.description.is_empty());
}
#[test]
fn deep_all_e0133_patterns_mention_unsafe_in_diff() {
for p in get_bootstrap_patterns() {
if p.error_code == "E0133" {
assert!(
p.fix_diff.contains("unsafe"),
"E0133 pattern should have 'unsafe' in diff: {}",
p.decision
);
}
}
}
#[test]
fn deep_all_e0382_patterns_relate_to_ownership() {
let ownership_decisions = ["clone_before_move", "borrow_instead_of_move", "borrow_parameter"];
for p in get_bootstrap_patterns() {
if p.error_code == "E0382" {
assert!(
ownership_decisions.contains(&p.decision),
"E0382 pattern should have ownership decision, got: {}",
p.decision
);
}
}
}
#[test]
fn deep_no_duplicate_patterns() {
let patterns = get_bootstrap_patterns();
for (i, a) in patterns.iter().enumerate() {
for (j, b) in patterns.iter().enumerate() {
if i != j {
let same = a.error_code == b.error_code
&& a.decision == b.decision
&& a.fix_diff == b.fix_diff;
assert!(!same, "Duplicate pattern found at indices {} and {}", i, j);
}
}
}
}
#[test]
fn deep_iterate_all_fields_for_coverage() {
let patterns = get_bootstrap_patterns();
let mut total_diff_len = 0;
let mut total_desc_len = 0;
for p in &patterns {
total_diff_len += p.fix_diff.len();
total_desc_len += p.description.len();
let _ = p.error_code.len();
let _ = p.decision.len();
}
assert!(total_diff_len > 0);
assert!(total_desc_len > 0);
}
#[test]
fn deep_stats_error_sum_matches_total() {
let stats = BootstrapStats::from_patterns();
let sum: usize = stats.by_error_code.values().sum();
assert_eq!(sum, stats.total_patterns);
}
#[test]
fn deep_stats_decision_sum_matches_total() {
let stats = BootstrapStats::from_patterns();
let sum: usize = stats.by_decision.values().sum();
assert_eq!(sum, stats.total_patterns);
}