use super::*;
#[test]
fn test_ml_004_tarantula_basic() {
let mut localizer = FaultLocalizer::with_tarantula();
localizer.set_test_counts(10, 2);
let coverage = CoverageData::new(2, 2, 8, 0);
let score = localizer.calculate_suspiciousness(&coverage);
assert!(score > 0.5);
}
#[test]
fn test_ml_004_ochiai_basic() {
let mut localizer = FaultLocalizer::with_ochiai();
localizer.set_test_counts(10, 2);
let coverage = CoverageData::new(0, 2, 10, 0);
let score = localizer.calculate_suspiciousness(&coverage);
assert_eq!(score, 1.0);
}
#[test]
fn test_ml_004_ochiai_no_fails() {
let mut localizer = FaultLocalizer::with_ochiai();
localizer.set_test_counts(10, 0);
let coverage = CoverageData::new(5, 0, 5, 0);
let score = localizer.calculate_suspiciousness(&coverage);
assert_eq!(score, 0.0);
}
#[test]
fn test_ml_004_jaccard() {
let localizer = FaultLocalizer::new(SbflFormula::Jaccard);
let _coverage = CoverageData::new(0, 2, 0, 0);
let score = localizer.jaccard(2.0, 0.0, 2.0);
assert_eq!(score, 1.0);
}
#[test]
fn test_ml_004_ranking() {
let mut localizer = FaultLocalizer::with_ochiai();
localizer.set_test_counts(8, 2);
localizer.add_coverage("file.rs:10".to_string(), CoverageData::new(0, 2, 8, 0));
localizer.add_coverage("file.rs:20".to_string(), CoverageData::new(4, 1, 4, 1));
localizer.add_coverage("file.rs:30".to_string(), CoverageData::new(5, 0, 3, 2));
let rankings = localizer.rank();
assert_eq!(rankings.len(), 3);
assert_eq!(rankings[0].location, "file.rs:10");
assert_eq!(rankings[0].rank, 1);
assert!(rankings[0].score > rankings[1].score);
assert!(rankings[1].score > rankings[2].score);
}
#[test]
fn test_ml_004_top_n() {
let mut localizer = FaultLocalizer::with_ochiai();
localizer.set_test_counts(10, 2);
for i in 0..10 {
localizer.add_coverage(
format!("file.rs:{}", i * 10),
CoverageData::new(i as u32, (10 - i) as u32, 0, 0),
);
}
let top_3 = localizer.top_n(3);
assert_eq!(top_3.len(), 3);
assert!(top_3[0].coverage.failed_covering >= top_3[1].coverage.failed_covering);
}
#[test]
fn test_ml_004_localize_faults() {
let coverage_data = vec![
(
"test1".to_string(),
true,
vec!["a.rs:1".to_string(), "a.rs:2".to_string()],
),
(
"test2".to_string(),
true,
vec!["a.rs:1".to_string(), "a.rs:3".to_string()],
),
(
"test3".to_string(),
false,
vec!["a.rs:2".to_string(), "a.rs:3".to_string()],
),
];
let rankings = localize_faults(&coverage_data, SbflFormula::Ochiai);
assert!(!rankings.is_empty());
let suspicious: Vec<_> = rankings.iter().filter(|r| r.score > 0.0).collect();
assert!(!suspicious.is_empty());
}
#[test]
fn test_ml_004_suspiciousness_ranking_traits() {
let ranking = SuspiciousnessRanking {
location: "test.rs:10".to_string(),
score: 0.85,
coverage: CoverageData::default(),
rank: 1,
};
assert!(ranking.is_highly_suspicious());
assert!(ranking.is_moderately_suspicious());
let low_ranking = SuspiciousnessRanking {
location: "test.rs:20".to_string(),
score: 0.3,
coverage: CoverageData::default(),
rank: 5,
};
assert!(!low_ranking.is_highly_suspicious());
assert!(!low_ranking.is_moderately_suspicious());
}
#[test]
fn test_ml_004_dstar_formula() {
let localizer = FaultLocalizer::new(SbflFormula::DStar { power: 2 });
let score = localizer.dstar(2.0, 0.0, 2.0, 2);
assert!(score.is_infinite());
let score2 = localizer.dstar(2.0, 2.0, 4.0, 2);
assert_eq!(score2, 1.0);
}
#[test]
fn test_ml_004_formula_display() {
assert_eq!(format!("{}", SbflFormula::Tarantula), "Tarantula");
assert_eq!(format!("{}", SbflFormula::Ochiai), "Ochiai");
assert_eq!(format!("{}", SbflFormula::DStar { power: 2 }), "D*2");
}
#[test]
fn test_formula_display_jaccard() {
assert_eq!(format!("{}", SbflFormula::Jaccard), "Jaccard");
}
#[test]
fn test_formula_display_wong2() {
assert_eq!(format!("{}", SbflFormula::Wong2), "Wong-II");
}
#[test]
fn test_formula_default() {
let formula = SbflFormula::default();
assert_eq!(formula, SbflFormula::Ochiai);
}
#[test]
fn test_coverage_data_default() {
let coverage = CoverageData::default();
assert_eq!(coverage.passed_covering, 0);
assert_eq!(coverage.failed_covering, 0);
assert_eq!(coverage.passed_not_covering, 0);
assert_eq!(coverage.failed_not_covering, 0);
}
#[test]
fn test_coverage_data_total_passed() {
let coverage = CoverageData::new(3, 2, 7, 1);
assert_eq!(coverage.total_passed(), 10);
}
#[test]
fn test_coverage_data_total_failed() {
let coverage = CoverageData::new(3, 2, 7, 1);
assert_eq!(coverage.total_failed(), 3);
}
#[test]
fn test_coverage_data_total_covering() {
let coverage = CoverageData::new(3, 2, 7, 1);
assert_eq!(coverage.total_covering(), 5);
}
#[test]
fn test_wong2_formula() {
let localizer = FaultLocalizer::new(SbflFormula::Wong2);
let score = localizer.wong2(5.0, 3.0);
assert_eq!(score, 2.0);
let score_negative = localizer.wong2(2.0, 5.0);
assert_eq!(score_negative, -3.0);
}
#[test]
fn test_tarantula_zero_passed() {
let mut localizer = FaultLocalizer::with_tarantula();
localizer.set_test_counts(0, 5);
let coverage = CoverageData::new(0, 3, 0, 2);
let score = localizer.calculate_suspiciousness(&coverage);
assert!(score >= 0.0);
}
#[test]
fn test_tarantula_zero_denom() {
let localizer = FaultLocalizer::with_tarantula();
let score = localizer.tarantula(0.0, 0.0, 2.0, 2.0);
assert_eq!(score, 0.0);
}
#[test]
fn test_jaccard_zero_denom() {
let localizer = FaultLocalizer::new(SbflFormula::Jaccard);
let score = localizer.jaccard(0.0, 0.0, 0.0);
assert_eq!(score, 0.0);
}
#[test]
fn test_dstar_zero_ef() {
let localizer = FaultLocalizer::new(SbflFormula::DStar { power: 2 });
let score = localizer.dstar(0.0, 5.0, 5.0, 2);
assert_eq!(score, 0.0);
}
#[test]
fn test_dstar_power_3() {
let localizer = FaultLocalizer::new(SbflFormula::DStar { power: 3 });
let score = localizer.dstar(2.0, 2.0, 4.0, 3);
assert_eq!(score, 2.0); }
#[test]
fn test_record_coverage() {
let mut localizer = FaultLocalizer::with_ochiai();
localizer.record_coverage("file.rs:10", true);
localizer.record_coverage("file.rs:10", true);
localizer.record_coverage("file.rs:10", false);
let rankings = localizer.rank();
assert_eq!(rankings.len(), 1);
assert_eq!(rankings[0].coverage.passed_covering, 2);
assert_eq!(rankings[0].coverage.failed_covering, 1);
}
#[test]
fn test_above_threshold() {
let mut localizer = FaultLocalizer::with_ochiai();
localizer.set_test_counts(10, 2);
localizer.add_coverage("high.rs:1".to_string(), CoverageData::new(0, 2, 10, 0));
localizer.add_coverage("medium.rs:1".to_string(), CoverageData::new(5, 1, 5, 1));
localizer.add_coverage("low.rs:1".to_string(), CoverageData::new(8, 0, 2, 2));
let above_half = localizer.above_threshold(0.5);
assert!(!above_half.is_empty());
assert!(above_half.iter().all(|r| r.score >= 0.5));
}
#[test]
fn test_suspiciousness_ranking_clone() {
let ranking = SuspiciousnessRanking {
location: "test.rs:5".to_string(),
score: 0.75,
coverage: CoverageData::new(1, 2, 3, 4),
rank: 2,
};
let cloned = ranking.clone();
assert_eq!(cloned.location, "test.rs:5");
assert_eq!(cloned.score, 0.75);
assert_eq!(cloned.rank, 2);
}
#[test]
fn test_fault_localizer_empty() {
let localizer = FaultLocalizer::with_ochiai();
let rankings = localizer.rank();
assert!(rankings.is_empty());
}
#[test]
fn test_localize_faults_empty() {
let coverage_data: Vec<(String, bool, Vec<String>)> = vec![];
let rankings = localize_faults(&coverage_data, SbflFormula::Ochiai);
assert!(rankings.is_empty());
}
#[test]
fn test_localize_faults_all_passing() {
let coverage_data = vec![
("test1".to_string(), true, vec!["a.rs:1".to_string()]),
("test2".to_string(), true, vec!["a.rs:1".to_string()]),
];
let rankings = localize_faults(&coverage_data, SbflFormula::Ochiai);
assert!(rankings.iter().all(|r| r.score == 0.0));
}
#[test]
fn test_formula_hash() {
use std::collections::HashSet;
let mut set = HashSet::new();
set.insert(SbflFormula::Tarantula);
set.insert(SbflFormula::Ochiai);
set.insert(SbflFormula::Jaccard);
set.insert(SbflFormula::Wong2);
set.insert(SbflFormula::DStar { power: 2 });
assert_eq!(set.len(), 5);
}
#[test]
fn test_formula_clone() {
let formula = SbflFormula::DStar { power: 3 };
let cloned = formula;
assert_eq!(cloned, SbflFormula::DStar { power: 3 });
}
#[test]
fn test_coverage_data_clone() {
let coverage = CoverageData::new(1, 2, 3, 4);
let cloned = coverage.clone();
assert_eq!(cloned.passed_covering, 1);
assert_eq!(cloned.failed_covering, 2);
assert_eq!(cloned.passed_not_covering, 3);
assert_eq!(cloned.failed_not_covering, 4);
}