use super::gates::GateConfig;
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn generate_default_config() -> String {
r#"# PMAT Quality Gate Configuration
# Generated by: pmat quality-gates init
[gates]
# Run clippy linter
run_clippy = true
# Enforce strict clippy (-D warnings)
clippy_strict = true
# Run test suite
run_tests = true
# Test timeout in seconds
test_timeout = 300
# Check code coverage
check_coverage = true
# Minimum coverage percentage (0-100)
min_coverage = 80.0
# Check cyclomatic complexity
check_complexity = true
# Maximum cyclomatic complexity per function
max_complexity = 10
"#
.to_string()
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn validate_config(config: &GateConfig) -> Result<(), Vec<String>> {
let mut errors = Vec::new();
if config.min_coverage < 0.0 || config.min_coverage > 100.0 {
errors.push(format!(
"min_coverage must be 0-100, got {}",
config.min_coverage
));
}
if config.test_timeout == 0 {
errors.push("test_timeout must be > 0".to_string());
}
if config.max_complexity == 0 {
errors.push("max_complexity must be > 0".to_string());
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn generate_config_toml(config: &GateConfig) -> String {
format!(
r#"[gates]
run_clippy = {}
clippy_strict = {}
run_tests = {}
test_timeout = {}
check_coverage = {}
min_coverage = {}
check_complexity = {}
max_complexity = {}
"#,
config.run_clippy,
config.clippy_strict,
config.run_tests,
config.test_timeout,
config.check_coverage,
config.min_coverage,
config.check_complexity,
config.max_complexity
)
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generate_default_config() {
let config = generate_default_config();
assert!(config.contains("[gates]"));
assert!(config.contains("run_clippy = true"));
assert!(config.contains("min_coverage = 80.0"));
assert!(config.contains("max_complexity = 10"));
assert!(config.contains("# PMAT Quality Gate Configuration"));
}
#[test]
fn test_validate_valid_config() {
let config = GateConfig::default();
assert!(validate_config(&config).is_ok());
}
#[test]
#[allow(clippy::field_reassign_with_default)]
fn test_validate_invalid_coverage_too_high() {
let mut config = GateConfig::default();
config.min_coverage = 150.0;
let result = validate_config(&config);
assert!(result.is_err());
let errors = result.unwrap_err();
assert_eq!(errors.len(), 1);
assert!(errors[0].contains("min_coverage"));
assert!(errors[0].contains("150"));
}
#[test]
#[allow(clippy::field_reassign_with_default)]
fn test_validate_invalid_coverage_negative() {
let mut config = GateConfig::default();
config.min_coverage = -10.0;
let result = validate_config(&config);
assert!(result.is_err());
let errors = result.unwrap_err();
assert!(errors[0].contains("min_coverage"));
}
#[test]
fn test_validate_zero_timeout() {
let config = GateConfig {
test_timeout: 0,
..Default::default()
};
let result = validate_config(&config);
assert!(result.is_err());
let errors = result.unwrap_err();
assert!(errors.iter().any(|e| e.contains("test_timeout")));
}
#[test]
fn test_validate_zero_complexity() {
let config = GateConfig {
max_complexity: 0,
..Default::default()
};
let result = validate_config(&config);
assert!(result.is_err());
let errors = result.unwrap_err();
assert!(errors.iter().any(|e| e.contains("max_complexity")));
}
#[test]
fn test_validate_multiple_errors() {
let config = GateConfig {
run_clippy: true,
clippy_strict: true,
run_tests: true,
test_timeout: 0,
check_coverage: true,
min_coverage: 150.0,
check_complexity: true,
max_complexity: 0,
};
let result = validate_config(&config);
assert!(result.is_err());
let errors = result.unwrap_err();
assert_eq!(errors.len(), 3); }
#[test]
fn test_generate_config_toml() {
let config = GateConfig {
run_clippy: true,
clippy_strict: false,
run_tests: true,
test_timeout: 120,
check_coverage: true,
min_coverage: 85.0,
check_complexity: true,
max_complexity: 8,
};
let toml = generate_config_toml(&config);
assert!(toml.contains("[gates]"));
assert!(toml.contains("run_clippy = true"));
assert!(toml.contains("clippy_strict = false"));
assert!(toml.contains("test_timeout = 120"));
assert!(toml.contains("min_coverage = 85"));
assert!(toml.contains("max_complexity = 8"));
}
#[test]
fn test_generate_config_toml_all_disabled() {
let config = GateConfig {
run_clippy: false,
clippy_strict: false,
run_tests: false,
test_timeout: 60,
check_coverage: false,
min_coverage: 50.0,
check_complexity: false,
max_complexity: 20,
};
let toml = generate_config_toml(&config);
assert!(toml.contains("run_clippy = false"));
assert!(toml.contains("run_tests = false"));
assert!(toml.contains("check_coverage = false"));
assert!(toml.contains("check_complexity = false"));
}
}