use super::*;
use serde_json::json;
#[test]
fn test_uniform_complexity_contract() {
let _expected = AnalyzeComplexityContract {
base: BaseAnalysisContract {
path: PathBuf::from("."),
format: OutputFormat::Json,
output: Some(PathBuf::from("output.json")),
top_files: Some(10),
include_tests: false,
timeout: 60,
},
max_cyclomatic: Some(20),
max_cognitive: Some(15),
max_halstead: Some(10.0),
};
let mcp_params = json!({
"path": ".",
"format": "json",
"output": "output.json",
"top_files": 10,
"include_tests": false,
"timeout": 60,
"max_cyclomatic": 20,
"max_cognitive": 15,
"max_halstead": 10.0
});
let http_body = json!({
"path": ".",
"format": "json",
"output": "output.json",
"top_files": 10,
"include_tests": false,
"timeout": 60,
"max_cyclomatic": 20,
"max_cognitive": 15,
"max_halstead": 10.0
});
assert_eq!(
mcp_params, http_body,
"MCP and HTTP must use identical parameter names"
);
}
#[test]
fn test_parameter_name_consistency() {
let _standard_params = [
"path", "format", "output", "top_files", "include_tests", "timeout", ];
let forbidden_variations = vec![
(
"path",
vec!["project_path", "file_path", "dir", "directory"],
),
("format", vec!["output_format", "fmt", "out_format"]),
("output", vec!["output_file", "out", "output_path"]),
("top_files", vec!["top_n", "limit", "max_files", "n"]),
("include_tests", vec!["with_tests", "tests", "include_test"]),
("timeout", vec!["max_time", "time_limit", "deadline"]),
];
for (correct, wrong_variants) in forbidden_variations {
for variant in wrong_variants {
assert_ne!(
correct, variant,
"Parameter '{}' must be used, not '{}'",
correct, variant
);
}
}
}
#[test]
fn test_base_parameters_required() {
let commands = vec![
"analyze_complexity",
"analyze_satd",
"analyze_dead_code",
"analyze_tdg",
"analyze_lint_hotspot",
"quality_gate",
];
for _command in commands {
let required_params = vec![
"path",
"format",
"output",
"top_files",
"include_tests",
"timeout",
];
for _param in required_params {
}
}
}
#[test]
fn test_consistent_defaults() {
let defaults = BaseAnalysisContract::default();
assert_eq!(defaults.path, PathBuf::from("."));
assert_eq!(defaults.format, OutputFormat::Table);
assert_eq!(defaults.output, None);
assert_eq!(defaults.top_files, Some(10));
assert!(!defaults.include_tests);
assert_eq!(defaults.timeout, 60);
}
#[test]
fn test_validation_consistency() {
let mut contract = AnalyzeComplexityContract {
base: BaseAnalysisContract::default(),
max_cyclomatic: Some(20),
max_cognitive: Some(15),
max_halstead: Some(10.0),
};
assert!(contract.validate().is_ok());
contract.base.path = PathBuf::from("/nonexistent/path");
assert!(contract.validate().is_err());
contract.base.path = PathBuf::from(".");
contract.base.timeout = 0;
assert!(contract.validate().is_err());
contract.base.timeout = 60;
contract.max_halstead = Some(-1.0);
assert!(contract.validate().is_err());
}
#[test]
fn test_contract_serialization() {
let contract = AnalyzeComplexityContract {
base: BaseAnalysisContract {
path: PathBuf::from("src"),
format: OutputFormat::Json,
output: None,
top_files: Some(5),
include_tests: true,
timeout: 120,
},
max_cyclomatic: Some(10),
max_cognitive: None,
max_halstead: Some(5.0),
};
let json = serde_json::to_value(&contract).unwrap();
assert_eq!(json["path"], "src");
assert_eq!(json["format"], "json");
assert_eq!(json["top_files"], 5);
assert_eq!(json["include_tests"], true);
assert_eq!(json["timeout"], 120);
assert_eq!(json["max_cyclomatic"], 10);
assert_eq!(json["max_halstead"], 5.0);
assert!(json["max_cognitive"].is_null());
let deserialized: AnalyzeComplexityContract = serde_json::from_value(json).unwrap();
assert_eq!(deserialized, contract);
}
#[test]
fn test_contract_type_safety() {
}
#[test]
fn test_contract_error_messages() {
let mut contract = AnalyzeComplexityContract {
base: BaseAnalysisContract::default(),
max_cyclomatic: None,
max_cognitive: None,
max_halstead: Some(-1.0),
};
let nonexistent_path =
PathBuf::from("/___this_path_definitely_does_not_exist_pmat_test_12345___");
contract.base.path = nonexistent_path.clone();
match contract.validate() {
Err(ContractError::PathNotFound(path)) => {
assert_eq!(path, nonexistent_path);
}
other => panic!("Expected PathNotFound error, got {:?}", other),
}
contract.base.path = PathBuf::from(".");
contract.base.timeout = 0;
match contract.validate() {
Err(ContractError::InvalidTimeout) => {}
_ => panic!("Expected InvalidTimeout error"),
}
contract.base.timeout = 60;
contract.max_halstead = Some(-1.0);
match contract.validate() {
Err(ContractError::InvalidValue(msg)) => {
assert!(msg.contains("halstead"));
}
_ => panic!("Expected InvalidValue error"),
}
}
#[test]
fn test_contract_integration() {
let contract = AnalyzeComplexityContract {
base: BaseAnalysisContract::default(),
max_cyclomatic: Some(20),
max_cognitive: Some(15),
max_halstead: None,
};
assert!(contract.validate().is_ok());
let json = serde_json::to_value(&contract).unwrap();
assert!(json.is_object());
let deserialized: AnalyzeComplexityContract = serde_json::from_value(json).unwrap();
assert_eq!(deserialized, contract);
let _path = &contract.base.path;
let _format = &contract.base.format;
let _max_cyclo = contract.max_cyclomatic.unwrap_or(30);
}