use anyrepair::{
csv, json, key_value, markdown, repair, toml,
traits::{Repair, Validator},
xml, yaml,
};
use proptest::prelude::*;
#[cfg(test)]
mod json_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_json_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = json::JsonRepairer::new().repair(&input);
}
#[test]
fn test_json_repair_improves_validity(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = json::JsonRepairer::new();
let validator = json::JsonValidator;
let original_valid = validator.is_valid(&input);
let repaired = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let repaired_valid = validator.is_valid(&repaired);
prop_assert!(repaired_valid || !original_valid);
}
#[test]
fn test_json_confidence_bounds(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = json::JsonRepairer::new();
let confidence = repairer.confidence(&input);
prop_assert!(confidence >= 0.0 && confidence <= 1.0);
}
#[test]
fn test_json_repair_idempotent(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = json::JsonRepairer::new();
let first_repair = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let second_repair = repairer.repair(&first_repair).unwrap_or_else(|_| first_repair.clone());
prop_assert!(first_repair == second_repair ||
(first_repair.len() as i32 - second_repair.len() as i32).abs() < 100);
}
}
}
#[cfg(test)]
mod yaml_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_yaml_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = yaml::YamlRepairer::new().repair(&input);
}
#[test]
fn test_yaml_repair_improves_validity(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = yaml::YamlRepairer::new();
let validator = yaml::YamlValidator;
let original_valid = validator.is_valid(&input);
let repaired = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let repaired_valid = validator.is_valid(&repaired);
prop_assert!(repaired_valid || !original_valid);
}
#[test]
fn test_yaml_confidence_bounds(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = yaml::YamlRepairer::new();
let confidence = repairer.confidence(&input);
prop_assert!(confidence >= 0.0 && confidence <= 1.0);
}
}
}
#[cfg(test)]
mod markdown_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_markdown_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = markdown::MarkdownRepairer::new().repair(&input);
}
#[test]
fn test_markdown_repair_improves_validity(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = markdown::MarkdownRepairer::new();
let validator = markdown::MarkdownValidator;
let original_valid = validator.is_valid(&input);
let repaired = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let repaired_valid = validator.is_valid(&repaired);
prop_assert!(repaired_valid || !original_valid);
}
#[test]
fn test_markdown_confidence_bounds(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = markdown::MarkdownRepairer::new();
let confidence = repairer.confidence(&input);
prop_assert!(confidence >= 0.0 && confidence <= 1.0);
}
}
}
#[cfg(test)]
mod xml_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_xml_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = xml::XmlRepairer::new().repair(&input);
}
#[test]
fn test_xml_repair_improves_validity(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = xml::XmlRepairer::new();
let validator = xml::XmlValidator;
let original_valid = validator.is_valid(&input);
let repaired = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let repaired_valid = validator.is_valid(&repaired);
prop_assert!(repaired_valid || !original_valid);
}
#[test]
fn test_xml_confidence_bounds(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = xml::XmlRepairer::new();
let confidence = repairer.confidence(&input);
prop_assert!(confidence >= 0.0 && confidence <= 1.0);
}
}
}
#[cfg(test)]
mod toml_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_toml_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = toml::TomlRepairer::new().repair(&input);
}
#[test]
fn test_toml_repair_improves_validity(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = toml::TomlRepairer::new();
let validator = toml::TomlValidator;
let original_valid = validator.is_valid(&input);
let repaired = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let repaired_valid = validator.is_valid(&repaired);
prop_assert!(repaired_valid || !original_valid);
}
#[test]
fn test_toml_confidence_bounds(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = toml::TomlRepairer::new();
let confidence = repairer.confidence(&input);
prop_assert!(confidence >= 0.0 && confidence <= 1.0);
}
}
}
#[cfg(test)]
mod csv_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_csv_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = csv::CsvRepairer::new().repair(&input);
}
#[test]
fn test_csv_repair_improves_validity(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = csv::CsvRepairer::new();
let validator = csv::CsvValidator;
let original_valid = validator.is_valid(&input);
let repaired = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let repaired_valid = validator.is_valid(&repaired);
prop_assert!(repaired_valid || !original_valid);
}
#[test]
fn test_csv_confidence_bounds(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = csv::CsvRepairer::new();
let confidence = repairer.confidence(&input);
prop_assert!(confidence >= 0.0 && confidence <= 1.0);
}
}
}
#[cfg(test)]
mod ini_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_ini_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = key_value::IniRepairer::new().repair(&input);
}
#[test]
fn test_ini_repair_improves_validity(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = key_value::IniRepairer::new();
let validator = key_value::IniValidator;
let original_valid = validator.is_valid(&input);
let repaired = repairer.repair(&input).unwrap_or_else(|_| input.clone());
let repaired_valid = validator.is_valid(&repaired);
prop_assert!(repaired_valid || !original_valid);
}
#[test]
fn test_ini_confidence_bounds(input in prop::string::string_regex(".*").unwrap()) {
let mut repairer = key_value::IniRepairer::new();
let confidence = repairer.confidence(&input);
prop_assert!(confidence >= 0.0 && confidence <= 1.0);
}
}
}
#[cfg(test)]
mod general_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_repair_never_panics(input in prop::string::string_regex(".*").unwrap()) {
let _ = repair(&input);
}
#[test]
fn test_repair_handles_empty_input(input in prop::string::string_regex("").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
#[test]
fn test_repair_handles_very_long_input(input in prop::string::string_regex(".{0,10000}").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
#[test]
fn test_repair_handles_unicode_input(input in prop::string::string_regex(".*").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
#[test]
fn test_repair_handles_binary_like_input(input in prop::string::string_regex("[\\x00-\\xFF]*").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
}
}
#[cfg(test)]
mod edge_case_fuzz_tests {
use super::*;
proptest! {
#[test]
fn test_repair_with_only_whitespace(input in prop::string::string_regex(r"\s*").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
#[test]
fn test_repair_with_only_special_chars(input in prop::string::string_regex("[!@#$%^&*()_+\\-=\\[\\]{}|;':\",./<>?]*").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
#[test]
fn test_repair_with_mixed_newlines(input in prop::string::string_regex("[\\r\\n]*").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
#[test]
fn test_repair_with_nested_quotes(input in prop::string::string_regex("[\"']*").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
#[test]
fn test_repair_with_repeated_chars(input in prop::string::string_regex("(.){1,100}").unwrap()) {
let result = repair(&input);
prop_assert!(result.is_ok());
}
}
}
#[cfg(test)]
mod performance_fuzz_tests {
use super::*;
use std::time::Instant;
proptest! {
#[test]
fn test_repair_performance_reasonable(input in prop::string::string_regex(".{0,1000}").unwrap()) {
let start = Instant::now();
let _ = repair(&input);
let duration = start.elapsed();
prop_assert!(duration.as_secs() < 1);
}
#[test]
fn test_repair_memory_usage_reasonable(input in prop::string::string_regex(".{0,5000}").unwrap()) {
let result = repair(&input).unwrap();
if input.is_empty() {
prop_assert!(result.len() <= 1);
} else {
prop_assert!(result.len() < input.len() * 10);
}
}
}
}