use crate::cli::DefectPredictionOutputFormat;
use anyhow::Result;
use std::path::PathBuf;
#[allow(clippy::too_many_arguments)]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub async fn handle_analyze_defect_prediction(
project_path: PathBuf,
confidence_threshold: f32,
min_lines: usize,
include_low_confidence: bool,
format: DefectPredictionOutputFormat,
high_risk_only: bool,
include_recommendations: bool,
include: Option<String>,
exclude: Option<String>,
output: Option<PathBuf>,
perf: bool,
top_files: usize,
) -> Result<()> {
use crate::cli::handlers::defect_prediction_handler::{
handle_analyze_defect_prediction as wired, DefectPredictionConfig,
};
wired(DefectPredictionConfig {
project_path,
confidence_threshold,
min_lines,
include_low_confidence,
format,
high_risk_only,
include_recommendations,
include: non_empty(include),
exclude: non_empty(exclude),
output,
perf,
top_files,
})
.await
}
fn non_empty(value: Option<String>) -> Option<String> {
value.filter(|v| !v.trim().is_empty())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_empty_filter_string_is_not_a_filter() {
assert_eq!(non_empty(Some(String::new())), None);
assert_eq!(non_empty(Some(" ".to_string())), None);
assert_eq!(non_empty(None), None);
assert_eq!(
non_empty(Some("*.rs".to_string())),
Some("*.rs".to_string())
);
}
#[tokio::test]
async fn the_library_entry_point_renders_the_wired_report() {
let dir = tempfile::TempDir::new().expect("tempdir");
std::fs::create_dir_all(dir.path().join("src")).expect("mkdir");
std::fs::write(
dir.path().join("src/lib.rs"),
(0..40)
.map(|i| {
format!("pub fn f{i}(a: i32) -> i32 {{ if a > {i} {{ a }} else {{ -a }} }}")
})
.collect::<Vec<_>>()
.join("\n"),
)
.expect("write");
let out = dir.path().join("report.json");
handle_analyze_defect_prediction(
dir.path().to_path_buf(),
0.0,
1,
true,
DefectPredictionOutputFormat::Json,
false,
false,
Some(String::new()),
Some(String::new()),
Some(out.clone()),
false,
0,
)
.await
.expect("library entry point runs");
let doc: serde_json::Value =
serde_json::from_str(&std::fs::read_to_string(&out).expect("read"))
.expect("valid json");
assert!(
doc.get("churn_source").is_some(),
"the wired document names its churn yardstick: {doc}"
);
assert!(
doc.get("duplication_source").is_some(),
"the wired document says duplication was not measured: {doc}"
);
}
}