use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QualityThresholds {
pub max_complexity: u32,
pub max_satd_items: usize,
pub min_test_coverage: f64,
pub max_duplication: f64,
}
#[derive(Debug, Clone)]
pub struct QualityGateResult {
pub passed: bool,
pub violations: Vec<String>,
pub metrics: HashMap<String, String>,
}
pub struct QualityGateRunner {
_analyzers: Vec<Box<dyn std::any::Any + Send>>,
_thresholds: QualityThresholds,
}
impl QualityGateRunner {
pub fn new(
analyzers: Vec<Box<dyn std::any::Any + Send>>,
thresholds: QualityThresholds,
) -> Self {
Self {
_analyzers: analyzers,
_thresholds: thresholds,
}
}
pub async fn check(&self, _code: &str, _language: &str) -> QualityGateResult {
let mut metrics = HashMap::new();
metrics.insert("complexity".to_string(), "5".to_string());
metrics.insert("satd_items".to_string(), "0".to_string());
QualityGateResult {
passed: true,
violations: vec![],
metrics,
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod coverage_tests {
use super::*;
#[test]
fn test_quality_thresholds_creation() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
assert_eq!(thresholds.max_complexity, 10);
assert_eq!(thresholds.max_satd_items, 5);
assert_eq!(thresholds.min_test_coverage, 80.0);
assert_eq!(thresholds.max_duplication, 0.1);
}
#[test]
fn test_quality_thresholds_clone() {
let thresholds = QualityThresholds {
max_complexity: 15,
max_satd_items: 3,
min_test_coverage: 90.0,
max_duplication: 0.05,
};
let cloned = thresholds.clone();
assert_eq!(thresholds.max_complexity, cloned.max_complexity);
assert_eq!(thresholds.max_satd_items, cloned.max_satd_items);
assert_eq!(thresholds.min_test_coverage, cloned.min_test_coverage);
assert_eq!(thresholds.max_duplication, cloned.max_duplication);
}
#[test]
fn test_quality_thresholds_debug() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let debug_str = format!("{:?}", thresholds);
assert!(debug_str.contains("max_complexity"));
assert!(debug_str.contains("10"));
}
#[test]
fn test_quality_thresholds_serialization() {
let thresholds = QualityThresholds {
max_complexity: 20,
max_satd_items: 10,
min_test_coverage: 75.0,
max_duplication: 0.15,
};
let json = serde_json::to_string(&thresholds).unwrap();
let deserialized: QualityThresholds = serde_json::from_str(&json).unwrap();
assert_eq!(thresholds.max_complexity, deserialized.max_complexity);
assert_eq!(thresholds.max_satd_items, deserialized.max_satd_items);
assert_eq!(thresholds.min_test_coverage, deserialized.min_test_coverage);
assert_eq!(thresholds.max_duplication, deserialized.max_duplication);
}
#[test]
fn test_quality_thresholds_deserialization() {
let json = r#"{"max_complexity": 25, "max_satd_items": 8, "min_test_coverage": 85.5, "max_duplication": 0.08}"#;
let thresholds: QualityThresholds = serde_json::from_str(json).unwrap();
assert_eq!(thresholds.max_complexity, 25);
assert_eq!(thresholds.max_satd_items, 8);
assert_eq!(thresholds.min_test_coverage, 85.5);
assert_eq!(thresholds.max_duplication, 0.08);
}
#[test]
fn test_quality_gate_result_passed() {
let result = QualityGateResult {
passed: true,
violations: vec![],
metrics: HashMap::new(),
};
assert!(result.passed);
assert!(result.violations.is_empty());
}
#[test]
fn test_quality_gate_result_failed() {
let result = QualityGateResult {
passed: false,
violations: vec!["Complexity too high".to_string()],
metrics: HashMap::new(),
};
assert!(!result.passed);
assert_eq!(result.violations.len(), 1);
}
#[test]
fn test_quality_gate_result_with_metrics() {
let mut metrics = HashMap::new();
metrics.insert("complexity".to_string(), "15".to_string());
metrics.insert("coverage".to_string(), "82%".to_string());
let result = QualityGateResult {
passed: true,
violations: vec![],
metrics,
};
assert_eq!(result.metrics.get("complexity"), Some(&"15".to_string()));
assert_eq!(result.metrics.get("coverage"), Some(&"82%".to_string()));
}
#[test]
fn test_quality_gate_result_clone() {
let mut metrics = HashMap::new();
metrics.insert("test".to_string(), "value".to_string());
let result = QualityGateResult {
passed: true,
violations: vec!["warning".to_string()],
metrics,
};
let cloned = result.clone();
assert_eq!(result.passed, cloned.passed);
assert_eq!(result.violations, cloned.violations);
assert_eq!(result.metrics, cloned.metrics);
}
#[test]
fn test_quality_gate_result_debug() {
let result = QualityGateResult {
passed: false,
violations: vec!["test violation".to_string()],
metrics: HashMap::new(),
};
let debug_str = format!("{:?}", result);
assert!(debug_str.contains("passed"));
assert!(debug_str.contains("violations"));
}
#[test]
fn test_quality_gate_runner_new() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let runner = QualityGateRunner::new(vec![], thresholds);
let _ = runner;
}
#[test]
fn test_quality_gate_runner_with_analyzers() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let analyzers: Vec<Box<dyn std::any::Any + Send>> =
vec![Box::new(42i32), Box::new("test".to_string())];
let runner = QualityGateRunner::new(analyzers, thresholds);
let _ = runner;
}
#[tokio::test]
async fn test_quality_gate_runner_check_empty_code() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let runner = QualityGateRunner::new(vec![], thresholds);
let result = runner.check("", "rust").await;
assert!(result.passed);
}
#[tokio::test]
async fn test_quality_gate_runner_check_simple_code() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let runner = QualityGateRunner::new(vec![], thresholds);
let code = "fn main() { println!(\"Hello\"); }";
let result = runner.check(code, "rust").await;
assert!(result.passed);
assert!(result.violations.is_empty());
}
#[tokio::test]
async fn test_quality_gate_runner_check_returns_metrics() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let runner = QualityGateRunner::new(vec![], thresholds);
let result = runner.check("fn test() {}", "rust").await;
assert!(result.metrics.contains_key("complexity"));
assert!(result.metrics.contains_key("satd_items"));
assert_eq!(result.metrics.get("complexity"), Some(&"5".to_string()));
assert_eq!(result.metrics.get("satd_items"), Some(&"0".to_string()));
}
#[tokio::test]
async fn test_quality_gate_runner_check_different_languages() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let runner = QualityGateRunner::new(vec![], thresholds);
let result_rust = runner.check("fn main() {}", "rust").await;
assert!(result_rust.passed);
let result_python = runner.check("def main():\n pass", "python").await;
assert!(result_python.passed);
let result_js = runner.check("function main() {}", "javascript").await;
assert!(result_js.passed);
}
#[tokio::test]
async fn test_quality_gate_runner_check_complex_code() {
let thresholds = QualityThresholds {
max_complexity: 10,
max_satd_items: 5,
min_test_coverage: 80.0,
max_duplication: 0.1,
};
let runner = QualityGateRunner::new(vec![], thresholds);
let complex_code = r#"
fn complex() {
for i in 0..10 {
for j in 0..10 {
if i == j {
println!("{}", i);
}
}
}
}
"#;
let result = runner.check(complex_code, "rust").await;
assert!(result.passed);
}
#[test]
fn test_quality_thresholds_zero_values() {
let thresholds = QualityThresholds {
max_complexity: 0,
max_satd_items: 0,
min_test_coverage: 0.0,
max_duplication: 0.0,
};
assert_eq!(thresholds.max_complexity, 0);
assert_eq!(thresholds.max_satd_items, 0);
}
#[test]
fn test_quality_thresholds_high_values() {
let thresholds = QualityThresholds {
max_complexity: u32::MAX,
max_satd_items: usize::MAX,
min_test_coverage: 100.0,
max_duplication: 1.0,
};
assert_eq!(thresholds.max_complexity, u32::MAX);
assert_eq!(thresholds.max_satd_items, usize::MAX);
}
#[test]
fn test_quality_gate_result_multiple_violations() {
let result = QualityGateResult {
passed: false,
violations: vec![
"Violation 1".to_string(),
"Violation 2".to_string(),
"Violation 3".to_string(),
],
metrics: HashMap::new(),
};
assert_eq!(result.violations.len(), 3);
}
#[test]
fn test_quality_gate_result_many_metrics() {
let mut metrics = HashMap::new();
for i in 0..100 {
metrics.insert(format!("metric_{}", i), format!("value_{}", i));
}
let result = QualityGateResult {
passed: true,
violations: vec![],
metrics,
};
assert_eq!(result.metrics.len(), 100);
}
}