fn test_RUNNER_COV_021_detect_regressions_no_regressions() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(96.0, 92, 77, 9, 8, 97.0, 91.0, 89.0, 87);
let report = current.detect_regressions(&previous);
assert!(!report.has_regressions());
assert!(report.regressions.is_empty());
}
#[test]
fn test_RUNNER_COV_022_detect_regression_score_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(90.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report.regressions.iter().find(|r| r.dimension == "score");
assert!(reg.is_some());
let r = reg.unwrap();
assert!((r.previous - 95.0).abs() < 0.01);
assert!((r.current - 90.0).abs() < 0.01);
}
#[test]
fn test_RUNNER_COV_023_detect_regression_passed_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 85, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report.regressions.iter().find(|r| r.dimension == "passed");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_024_detect_regression_bash_passed_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 90, 70, 8, 7, 96.0, 90.0, 88.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report
.regressions
.iter()
.find(|r| r.dimension == "bash_passed");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_025_detect_regression_makefile_passed_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 90, 75, 6, 7, 96.0, 90.0, 88.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report
.regressions
.iter()
.find(|r| r.dimension == "makefile_passed");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_026_detect_regression_dockerfile_passed_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 90, 75, 8, 5, 96.0, 90.0, 88.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report
.regressions
.iter()
.find(|r| r.dimension == "dockerfile_passed");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_027_detect_regression_bash_score_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 90, 75, 8, 7, 90.0, 90.0, 88.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report
.regressions
.iter()
.find(|r| r.dimension == "bash_score");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_028_detect_regression_makefile_score_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 90, 75, 8, 7, 96.0, 85.0, 88.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report
.regressions
.iter()
.find(|r| r.dimension == "makefile_score");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_029_detect_regression_dockerfile_score_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 80.0, 85);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report
.regressions
.iter()
.find(|r| r.dimension == "dockerfile_score");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_030_detect_regression_lint_passed_dropped() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 80);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
let reg = report
.regressions
.iter()
.find(|r| r.dimension == "lint_passed");
assert!(reg.is_some());
}
#[test]
fn test_RUNNER_COV_031_detect_regression_multiple_dimensions() {
let previous = make_convergence(95.0, 90, 75, 8, 7, 96.0, 90.0, 88.0, 85);
let current = make_convergence(80.0, 70, 60, 5, 4, 85.0, 80.0, 75.0, 70);
let report = current.detect_regressions(&previous);
assert!(report.has_regressions());
assert!(report.regressions.len() >= 5);
}
#[test]
fn test_RUNNER_COV_032_regression_report_empty_no_regressions() {
let report = RegressionReport {
regressions: vec![],
};
assert!(!report.has_regressions());
}
#[test]
fn test_RUNNER_COV_033_regression_report_with_entry_has_regressions() {
use crate::corpus::runner::Regression;
let report = RegressionReport {
regressions: vec![Regression {
message: "Score dropped".to_string(),
dimension: "score".to_string(),
previous: 95.0,
current: 90.0,
}],
};
assert!(report.has_regressions());
}
#[test]
fn test_RUNNER_COV_034_format_score_fields() {
let fs = FormatScore {
format: CorpusFormat::Dockerfile,
total: 50,
passed: 45,
rate: 0.9,
score: 88.5,
grade: Grade::B,
};
assert_eq!(fs.format, CorpusFormat::Dockerfile);
assert_eq!(fs.total, 50);
assert_eq!(fs.passed, 45);
assert!((fs.rate - 0.9).abs() < 0.01);
assert!((fs.score - 88.5).abs() < 0.01);
}
#[test]
fn test_RUNNER_COV_035_corpus_result_default() {
let r = CorpusResult::default();
assert!(!r.transpiled);
assert!(!r.output_contains);
assert!(!r.output_exact);
assert!(!r.output_behavioral);
assert!(!r.has_test);
assert!((r.coverage_ratio - 0.0).abs() < 0.001);
assert!(!r.schema_valid);
assert!(!r.lint_clean);
assert!(!r.deterministic);
assert!(!r.metamorphic_consistent);
assert!(!r.cross_shell_agree);
assert!(r.actual_output.is_none());
assert!(r.error.is_none());
assert!(r.error_category.is_none());
assert!(r.decision_trace.is_none());
}
#[test]
fn test_RUNNER_COV_036_output_exact_true_adds_8_points() {
let result = CorpusResult {
transpiled: true,
schema_valid: true,
output_contains: true,
output_exact: true,
..Default::default()
};
let score = result.score();
assert!(
(score - 48.0).abs() < 0.01,
"Score should be 48.0, got {score}"
);
}
#[test]
fn test_RUNNER_COV_037_output_behavioral_true_adds_7_points() {
let result = CorpusResult {
transpiled: true,
schema_valid: true,
output_contains: true,
output_behavioral: true,
..Default::default()
};
let score = result.score();
assert!(
(score - 47.0).abs() < 0.01,
"Score should be 47.0, got {score}"
);
}
#[test]
fn test_RUNNER_COV_038_convergence_entry_default() {
let entry = ConvergenceEntry::default();
assert_eq!(entry.iteration, 0);
assert_eq!(entry.total, 0);
assert_eq!(entry.passed, 0);
assert_eq!(entry.failed, 0);
assert!((entry.rate - 0.0).abs() < 0.001);
assert!((entry.score - 0.0).abs() < 0.001);
assert_eq!(entry.bash_passed, 0);
assert_eq!(entry.makefile_passed, 0);
assert_eq!(entry.dockerfile_passed, 0);
assert_eq!(entry.lint_passed, 0);
}
#[test]
fn test_RUNNER_COV_039_regression_message_format() {
use crate::corpus::runner::Regression;
let reg = Regression {
message: "V2 score dropped: 95 → 90".to_string(),
dimension: "score".to_string(),
previous: 95.0,
current: 90.0,
};
assert!(reg.message.contains("95"));
assert!(reg.message.contains("90"));
assert_eq!(reg.dimension, "score");
assert!((reg.previous - 95.0).abs() < 0.01);
assert!((reg.current - 90.0).abs() < 0.01);
}
#[test]
fn test_RUNNER_COV_040_corpus_result_with_outputs() {
let result = CorpusResult {
id: "B-001".to_string(),
transpiled: true,
actual_output: Some("#!/bin/sh\necho hello".to_string()),
expected_output: Some("echo hello".to_string()),
schema_valid: true,
output_contains: true,
..Default::default()
};
assert_eq!(result.id, "B-001");
assert!(result.actual_output.is_some());
assert!(result.expected_output.is_some());
assert!(result.output_contains);
}