#![cfg(feature = "mutation-testing")]
#![cfg(not(feature = "skip-slow-tests"))]
use pmat::cli::commands::MutateArgs;
use pmat::cli::handlers::mutate::handle;
use pmat::stateless_server::StatelessTemplateServer;
use std::io::Write;
use std::path::PathBuf;
use std::sync::Arc;
use tempfile::{tempdir, NamedTempFile};
#[tokio::test]
async fn test_target_file_not_found() {
let args = MutateArgs {
target: PathBuf::from("/nonexistent/file.rs"),
language: None,
timeout: 30,
jobs: None,
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
assert!(result.is_err(), "Expected error for nonexistent file");
let err_msg = result.unwrap_err().to_string();
assert!(
err_msg.contains("Target file not found") || err_msg.contains("No such file"),
"Error message should indicate file not found, got: {}",
err_msg
);
}
#[tokio::test]
async fn test_target_directory_instead_of_file() {
let temp_dir = tempdir().unwrap();
let args = MutateArgs {
target: temp_dir.path().to_path_buf(),
language: None,
timeout: 30,
jobs: None,
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
assert!(result.is_err(), "Expected error when target is a directory");
}
#[tokio::test]
async fn test_relative_path_canonicalization() {
let temp_file = NamedTempFile::new().unwrap();
let file_path = temp_file.path();
writeln!(
temp_file.as_file(),
"fn add(a: i32, b: i32) -> i32 {{ a + b }}"
)
.unwrap();
let current_dir = std::env::current_dir().unwrap();
let relative_path = if let Ok(rel) = file_path.strip_prefix(¤t_dir) {
rel.to_path_buf()
} else {
file_path.to_path_buf()
};
let args = MutateArgs {
target: relative_path,
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {} Err(e) => {
let msg = e.to_string();
assert!(
!msg.contains("Target file not found") && !msg.contains("No such file"),
"Should not fail due to path resolution, got: {}",
msg
);
}
}
}
#[tokio::test]
#[cfg(unix)] async fn test_symlink_resolution() {
use std::os::unix::fs::symlink;
let temp_dir = tempdir().unwrap();
let real_file = temp_dir.path().join("real.rs");
std::fs::write(&real_file, "fn test() { }").unwrap();
let symlink_file = temp_dir.path().join("link.rs");
symlink(&real_file, &symlink_file).unwrap();
let args = MutateArgs {
target: symlink_file,
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(
!msg.contains("Target file not found") && !msg.contains("No such file"),
"Should resolve symlink, got: {}",
msg
);
}
}
}
#[tokio::test]
async fn test_invalid_threshold_above_100() {
let temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file.as_file(), "fn test() {{ }}").unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: Some(150.0), failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
if result.is_err() {
let msg = result.unwrap_err().to_string();
assert!(
msg.contains("threshold") || msg.contains("below"),
"Should indicate threshold issue, got: {}",
msg
);
}
}
#[tokio::test]
async fn test_negative_threshold() {
let temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file.as_file(), "fn test() {{ }}").unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: Some(-10.0), failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {} }
}
#[tokio::test]
async fn test_invalid_output_format() {
let temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file.as_file(), "fn test() {{ }}").unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "invalid_format".to_string(), output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {} }
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_jobs_parameter_values() {
let temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file.as_file(), "fn test() {{ }}").unwrap();
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let args_zero = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(0),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_zero = handle(args_zero, server.clone()).await;
let args_one = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_one = handle(args_one, server.clone()).await;
let max_cpus = num_cpus::get();
let args_max = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(max_cpus),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_max = handle(args_max, server.clone()).await;
match (result_zero, result_one, result_max) {
(_, _, _) => {} }
}
#[tokio::test]
async fn test_timeout_parameter() {
let temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file.as_file(), "fn test() {{ }}").unwrap();
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let args_short = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 1, jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_short = handle(args_short, server.clone()).await;
let args_long = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 3600, jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_long = handle(args_long, server.clone()).await;
match (result_short, result_long) {
(_, _) => {} }
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_combined_arguments() {
let temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file.as_file(), "fn test() {{ }}").unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: Some("rust".to_string()),
timeout: 60,
jobs: Some(2),
output_format: "json".to_string(),
output: None,
threshold: Some(80.0),
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {} Err(e) => {
let msg = e.to_string();
assert!(
!msg.contains("invalid") || msg.contains("threshold") || msg.contains("below"),
"Should not fail due to argument validation, got: {}",
msg
);
}
}
}
#[tokio::test]
async fn test_json_output_structure() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {} Err(e) => {
let msg = e.to_string();
assert!(
!msg.contains("invalid") && !msg.contains("format"),
"Should not fail due to output format, got: {}",
msg
);
}
}
}
#[tokio::test]
async fn test_json_failures_only_true() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: true, use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {} }
}
#[tokio::test]
async fn test_json_failures_only_false() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false, use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {} }
}
#[tokio::test]
async fn test_markdown_output_structure() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "markdown".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(
!msg.contains("invalid") && !msg.contains("format"),
"Should not fail due to markdown format, got: {}",
msg
);
}
}
}
#[tokio::test]
async fn test_text_output_default() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_output_format_selection() {
let temp_file = create_test_rust_file();
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let args_json = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_json = handle(args_json, server.clone()).await;
let args_md = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "markdown".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_md = handle(args_md, server.clone()).await;
let args_text = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let result_text = handle(args_text, server.clone()).await;
match (result_json, result_md, result_text) {
(_, _, _) => {} }
}
#[tokio::test]
async fn test_empty_results_output() {
let temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file.as_file(), "// Empty comment").unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_text_output_no_color() {
std::env::set_var("NO_COLOR", "1");
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
std::env::remove_var("NO_COLOR");
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_json_code_snippet_inclusion() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_markdown_summary_table() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "markdown".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_markdown_mutant_details() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "markdown".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
#[ignore] async fn test_large_results_output() {
}
#[allow(dead_code)]
#[tokio::test]
async fn test_failures_only_true() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: true, use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(!msg.contains("failures_only") && !msg.contains("invalid"));
}
}
}
#[tokio::test]
async fn test_failures_only_false() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false, use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(!msg.contains("failures_only") && !msg.contains("invalid"));
}
}
}
#[tokio::test]
async fn test_failures_only_with_json_output() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(!msg.contains("incompatible") && !msg.contains("invalid"));
}
}
}
#[tokio::test]
async fn test_failures_only_with_markdown_output() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "markdown".to_string(),
output: None,
threshold: None,
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(!msg.contains("incompatible") && !msg.contains("invalid"));
}
}
}
#[tokio::test]
async fn test_failures_only_with_text_output() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(!msg.contains("incompatible") && !msg.contains("invalid"));
}
}
}
#[tokio::test]
async fn test_failures_only_all_formats() {
let temp_file = create_test_rust_file();
let formats = vec!["json", "markdown", "text"];
for format in formats {
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: format.to_string(),
output: None,
threshold: None,
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
assert!(
!msg.contains("incompatible") && !msg.contains("invalid"),
"Format {} failed with failures_only: {}",
format,
msg
);
}
}
}
}
#[tokio::test]
async fn test_failures_only_flag_preserved() {
let temp_file = create_test_rust_file();
let args_true = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server_true = Arc::new(StatelessTemplateServer::new().unwrap());
let args_false = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server_false = Arc::new(StatelessTemplateServer::new().unwrap());
let result_true = handle(args_true, server_true).await;
let result_false = handle(args_false, server_false).await;
if let Err(e) = result_true {
assert!(!e.to_string().contains("failures_only"));
}
if let Err(e) = result_false {
assert!(!e.to_string().contains("failures_only"));
}
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_failures_only_with_combined_flags() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(2),
output_format: "json".to_string(),
output: None,
threshold: Some(80.0),
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
match result {
Ok(_) => {}
Err(e) => {
let msg = e.to_string();
if msg.contains("threshold") {
} else {
assert!(
!msg.contains("failures_only") && !msg.contains("incompatible"),
"Should not fail due to failures_only flag: {}",
msg
);
}
}
}
}
#[tokio::test]
async fn test_progress_with_single_job() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_progress_with_multiple_jobs() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(4),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_progress_with_default_jobs() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: None, output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_progress_sequential_execution() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1), output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_progress_parallel_execution() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(8), output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_progress_all_formats() {
let temp_file = create_test_rust_file();
let formats = vec!["json", "markdown", "text"];
for format in formats {
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(2),
output_format: format.to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
}
#[tokio::test]
async fn test_code_snippets_json() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_code_snippets_markdown() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "markdown".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_code_snippets_text() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "text".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_code_snippets_failures_only() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_code_snippets_multiline() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(
temp_file,
r#"
fn complex_function(x: i32, y: i32) -> i32 {{
let result = if x > y {{
x - y
}} else {{
y - x
}};
result * 2
}}
"#
)
.unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_code_snippets_empty_file() {
let temp_file = NamedTempFile::new().unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_code_snippets_unicode() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(
temp_file,
r#"
// Test with Unicode: ä½ å¥½ä¸–ç•Œ 🦀
fn hello() -> &'static str {{
"Hello, 世界!"
}}
"#
)
.unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
#[tokio::test]
async fn test_code_snippets_all_formats() {
let temp_file = create_test_rust_file();
let formats = vec!["json", "markdown", "text"];
for format in formats {
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: format.to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let _ = handle(args, server).await;
}
}
#[tokio::test]
async fn test_error_invalid_rust_syntax() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file, "fn invalid_syntax( {{ {{ }}").unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
if let Err(e) = result {
let msg = e.to_string();
assert!(!msg.is_empty(), "Error message should not be empty");
}
}
#[tokio::test]
async fn test_error_directory_instead_of_file() {
let temp_dir = tempdir().unwrap();
let args = MutateArgs {
target: temp_dir.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
assert!(
result.is_err(),
"Should error when given directory instead of file"
);
}
#[tokio::test]
async fn test_error_invalid_output_path() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: Some(PathBuf::from("/nonexistent/dir/output.json")),
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
let _ = result; }
#[tokio::test]
async fn test_error_zero_jobs() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(0), output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
let _ = result;
}
#[tokio::test]
async fn test_error_short_timeout() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 1, jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
let _ = result;
}
#[tokio::test]
async fn test_error_unsupported_language() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(temp_file, "This is not Rust code").unwrap();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: Some("nonexistent_language".to_string()),
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
let _ = result;
}
#[tokio::test]
async fn test_error_multiple_invalid_args() {
let args = MutateArgs {
target: PathBuf::from("/nonexistent/file.rs"),
language: Some("invalid_lang".to_string()),
timeout: 0, jobs: Some(0), output_format: "invalid_format".to_string(),
output: Some(PathBuf::from("/nonexistent/output.json")),
threshold: Some(150.0), failures_only: true,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
assert!(
result.is_err(),
"Should error with multiple invalid arguments"
);
}
#[tokio::test]
async fn test_error_threshold_violation() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: Some(100.0), failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
let _ = result;
}
#[tokio::test]
#[ignore = "mutation handler unit test"]
async fn test_error_concurrent_execution() {
let temp_file = create_test_rust_file();
let args = MutateArgs {
target: temp_file.path().to_path_buf(),
language: None,
timeout: 30,
jobs: Some(100), output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
let _ = result;
}
#[tokio::test]
async fn test_error_useful_messages() {
let args = MutateArgs {
target: PathBuf::from("/definitely/does/not/exist/file.rs"),
language: None,
timeout: 30,
jobs: Some(1),
output_format: "json".to_string(),
output: None,
threshold: None,
failures_only: false,
use_cargo_mutants: false,
features: None,
all_features: false,
no_default_features: false,
no_shuffle: false,
};
let server = Arc::new(StatelessTemplateServer::new().unwrap());
let result = handle(args, server).await;
assert!(result.is_err(), "Should error on non-existent file");
if let Err(e) = result {
let msg = e.to_string();
assert!(msg.len() > 10, "Error message should be descriptive");
assert!(
msg.to_lowercase().contains("file")
|| msg.to_lowercase().contains("path")
|| msg.to_lowercase().contains("not found")
|| msg.to_lowercase().contains("exist"),
"Error should mention file/path issue: {}",
msg
);
}
}
fn create_test_rust_file() -> NamedTempFile {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(
temp_file,
r#"
fn add(a: i32, b: i32) -> i32 {{
a + b
}}
fn subtract(a: i32, b: i32) -> i32 {{
a - b
}}
fn multiply(a: i32, b: i32) -> i32 {{
a * b
}}
"#
)
.unwrap();
temp_file
}