#[tokio::test]
async fn test_handle_analyze_provability_with_output_file() {
let temp_dir = TempDir::new().unwrap();
let output_path = temp_dir.path().join("analysis.json");
let src_dir = temp_dir.path().join("src");
std::fs::create_dir_all(&src_dir).unwrap();
std::fs::write(src_dir.join("main.rs"), "fn main() {}").unwrap();
let config = ProvabilityConfig {
project_path: temp_dir.path().to_path_buf(),
functions: vec!["main".to_string()],
analysis_depth: 3,
format: ProvabilityOutputFormat::Json,
high_confidence_only: false,
include_evidence: true,
output: Some(output_path.clone()),
top_files: 5,
};
let result = handle_analyze_provability(config).await;
assert!(result.is_ok());
assert!(output_path.exists());
}
#[tokio::test]
async fn test_handle_analyze_provability_summary_format() {
let temp_dir = TempDir::new().unwrap();
let config = ProvabilityConfig {
project_path: temp_dir.path().to_path_buf(),
functions: vec!["test_func".to_string()],
analysis_depth: 5,
format: ProvabilityOutputFormat::Summary,
high_confidence_only: false,
include_evidence: false,
output: None,
top_files: 10,
};
let result = handle_analyze_provability(config).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_handle_analyze_provability_sarif_format() {
let temp_dir = TempDir::new().unwrap();
let output_path = temp_dir.path().join("analysis.sarif");
let config = ProvabilityConfig {
project_path: temp_dir.path().to_path_buf(),
functions: vec!["main".to_string()],
analysis_depth: 3,
format: ProvabilityOutputFormat::Sarif,
high_confidence_only: false,
include_evidence: false,
output: Some(output_path.clone()),
top_files: 5,
};
let result = handle_analyze_provability(config).await;
assert!(result.is_ok());
let content = std::fs::read_to_string(&output_path).unwrap();
assert!(content.contains("sarif-schema"));
}
#[tokio::test]
async fn test_handle_analyze_provability_full_format_with_evidence() {
let temp_dir = TempDir::new().unwrap();
let config = ProvabilityConfig {
project_path: temp_dir.path().to_path_buf(),
functions: vec!["complex_fn".to_string()],
analysis_depth: 10,
format: ProvabilityOutputFormat::Full,
high_confidence_only: false,
include_evidence: true,
output: None,
top_files: 15,
};
let result = handle_analyze_provability(config).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_handle_analyze_provability_markdown_format() {
let temp_dir = TempDir::new().unwrap();
let output_path = temp_dir.path().join("analysis.md");
let config = ProvabilityConfig {
project_path: temp_dir.path().to_path_buf(),
functions: vec!["test".to_string()],
analysis_depth: 3,
format: ProvabilityOutputFormat::Markdown,
high_confidence_only: false,
include_evidence: true,
output: Some(output_path.clone()),
top_files: 5,
};
let result = handle_analyze_provability(config).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_handle_analyze_provability_high_confidence_filter() {
let temp_dir = TempDir::new().unwrap();
let config = ProvabilityConfig {
project_path: temp_dir.path().to_path_buf(),
functions: vec!["fn1".to_string(), "fn2".to_string()],
analysis_depth: 3,
format: ProvabilityOutputFormat::Json,
high_confidence_only: true, include_evidence: false,
output: None,
top_files: 5,
};
let result = handle_analyze_provability(config).await;
assert!(result.is_ok());
}
#[test]
fn test_all_output_formats_display() {
let formats = vec![
ProvabilityOutputFormat::Json,
ProvabilityOutputFormat::Summary,
ProvabilityOutputFormat::Full,
ProvabilityOutputFormat::Sarif,
ProvabilityOutputFormat::Markdown,
];
for format in formats {
let config = ProvabilityConfig {
project_path: PathBuf::from("/test"),
functions: vec![],
analysis_depth: 3,
format: format.clone(),
high_confidence_only: false,
include_evidence: false,
output: None,
top_files: 5,
};
let function_ids = vec![create_test_function_id("test.rs", "test_fn", 1)];
let summaries = vec![create_test_summary(0.75)];
let result = format_provability_output(&function_ids, &summaries, &config);
assert!(
result.is_ok(),
"Format {:?} should produce valid output",
format
);
}
}
#[test]
fn test_format_with_empty_function_ids() {
let config = ProvabilityConfig {
project_path: PathBuf::from("/test"),
functions: vec![],
analysis_depth: 3,
format: ProvabilityOutputFormat::Summary,
high_confidence_only: false,
include_evidence: false,
output: None,
top_files: 5,
};
let function_ids: Vec<FunctionId> = vec![];
let summaries: Vec<ProofSummary> = vec![];
let result = format_provability_output(&function_ids, &summaries, &config);
assert!(result.is_ok());
let content = strip_ansi(&result.unwrap());
assert!(content.contains("Total functions analyzed: 0"));
}
#[test]
fn test_format_with_zero_top_files() {
let config = ProvabilityConfig {
project_path: PathBuf::from("/test"),
functions: vec![],
analysis_depth: 3,
format: ProvabilityOutputFormat::Summary,
high_confidence_only: false,
include_evidence: false,
output: None,
top_files: 0, };
let function_ids = vec![create_test_function_id("test.rs", "fn", 1)];
let summaries = vec![create_test_summary(0.8)];
let result = format_provability_output(&function_ids, &summaries, &config);
assert!(result.is_ok());
}
#[test]
fn test_format_json_with_evidence() {
let config = ProvabilityConfig {
project_path: PathBuf::from("/test"),
functions: vec![],
analysis_depth: 3,
format: ProvabilityOutputFormat::Json,
high_confidence_only: false,
include_evidence: true, output: None,
top_files: 5,
};
let function_ids = vec![create_test_function_id("test.rs", "tested_fn", 42)];
let summaries = vec![create_test_summary_with_properties(
0.92,
vec![
VerifiedProperty {
property_type: PropertyType::NullSafety,
confidence: 0.95,
evidence: "Comprehensive null checks".to_string(),
},
VerifiedProperty {
property_type: PropertyType::BoundsCheck,
confidence: 0.88,
evidence: "Array bounds verified".to_string(),
},
],
)];
let result = format_provability_output(&function_ids, &summaries, &config);
assert!(result.is_ok());
let content = result.unwrap();
assert!(content.contains("properties"));
assert!(content.contains("NullSafety"));
}
#[test]
fn test_format_json_without_evidence() {
let config = ProvabilityConfig {
project_path: PathBuf::from("/test"),
functions: vec![],
analysis_depth: 3,
format: ProvabilityOutputFormat::Json,
high_confidence_only: false,
include_evidence: false, output: None,
top_files: 5,
};
let function_ids = vec![create_test_function_id("test.rs", "tested_fn", 42)];
let summaries = vec![create_test_summary_with_properties(
0.92,
vec![VerifiedProperty {
property_type: PropertyType::PureFunction,
confidence: 0.99,
evidence: "No side effects".to_string(),
}],
)];
let result = format_provability_output(&function_ids, &summaries, &config);
assert!(result.is_ok());
let content = result.unwrap();
assert!(content.contains("verified_properties"));
}
#[test]
fn test_sarif_output_all_score_levels() {
let config = ProvabilityConfig {
project_path: PathBuf::from("/test"),
functions: vec![],
analysis_depth: 3,
format: ProvabilityOutputFormat::Sarif,
high_confidence_only: false,
include_evidence: false,
output: None,
top_files: 5,
};
let function_ids = vec![
create_test_function_id("test.rs", "low_fn", 10),
create_test_function_id("test.rs", "medium_fn", 20),
create_test_function_id("test.rs", "high_fn", 30),
];
let summaries = vec![
create_test_summary(0.3), create_test_summary(0.65), create_test_summary(0.9), ];
let result = format_provability_output(&function_ids, &summaries, &config);
assert!(result.is_ok());
let content = result.unwrap();
assert!(content.contains("low-provability"));
assert!(content.contains("medium-provability"));
assert!(content.contains("high-provability"));
assert!(content.contains("\"level\": \"warning\""));
assert!(content.contains("\"level\": \"note\""));
assert!(content.contains("\"level\": \"none\""));
}