#![allow(deprecated)]
use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use tempfile::tempdir;
#[test]
#[ignore = "Quality gate output format changed - test needs updating"]
fn test_quality_gate_fails_on_high_complexity() {
let dir = tempdir().unwrap();
let complex_file = dir.path().join("complex.rs");
fs::write(
&complex_file,
r#"
fn very_complex_function(x: i32) -> i32 {
if x > 0 {
if x > 10 {
if x > 20 {
if x > 30 {
if x > 40 {
if x > 50 {
if x > 60 {
if x > 70 {
if x > 80 {
if x > 90 {
return x * 2;
}
}
}
}
}
}
}
}
}
}
x
}
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("pmat").unwrap();
cmd.arg("quality-gate")
.arg("-p")
.arg(dir.path())
.arg("--checks")
.arg("complexity")
.arg("--max-complexity-p99")
.arg("5") .arg("--fail-on-violation");
cmd.assert()
.failure()
.code(1)
.stderr(predicate::str::contains("Quality gate FAILED"));
}
#[test]
#[ignore] fn test_quality_gate_fails_on_satd() {
let dir = tempdir().unwrap();
let file1 = dir.path().join("main.rs");
let test_content = format!(
r#"
// {}: This is technical debt that needs fixing
fn main() {{
// {}: This is a hack
println!("Hello");
// {}: Quick workaround
}}
"#,
"TODO", "FIXME", "HACK"
);
fs::write(&file1, test_content).unwrap();
let file2 = dir.path().join("lib.rs");
let test_content2 = format!(
r#"
// {}: Refactor this mess
pub fn process() {{
// {}: Memory leak here
// {}: Security issue
}}
"#,
"TODO", "FIXME", "XXX"
);
fs::write(&file2, test_content2).unwrap();
let mut cmd = Command::cargo_bin("pmat").unwrap();
cmd.arg("quality-gate")
.arg("-p")
.arg(dir.path())
.arg("--checks")
.arg("satd")
.arg("--fail-on-violation");
cmd.assert()
.failure()
.code(1)
.stderr(predicate::str::contains("Quality gate FAILED"));
}
#[test]
#[ignore] fn test_quality_gate_fails_on_security() {
let dir = tempdir().unwrap();
let file = dir.path().join("config.rs");
fs::write(
&file,
r#"
const API_KEY = "sk-1234567890abcdef";
const PASSWORD = "admin123";
const SECRET = "very-secret-key";
fn connect() {
let password = "hardcoded_password";
// Connect with hardcoded credentials
}
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("pmat").unwrap();
cmd.arg("quality-gate")
.arg("-p")
.arg(dir.path())
.arg("--checks")
.arg("security")
.arg("--fail-on-violation");
cmd.assert()
.failure()
.code(1)
.stderr(predicate::str::contains("Quality gate FAILED"));
}
#[test]
#[ignore] fn test_quality_gate_passes_clean_code() {
let dir = tempdir().unwrap();
let file = dir.path().join("clean.rs");
fs::write(
&file,
r#"
/// Main entry point with all logic inline
fn main() {
let a = 2;
let b = 3;
let result = a + b;
println!("Result: {}", result);
// Additional code to ensure low dead code percentage
if result > 0 {
println!("Positive result");
} else {
println!("Non-positive result");
}
}
"#,
)
.unwrap();
let readme = dir.path().join("README.md");
fs::write(
&readme,
r#"# Test Project
## Installation
Install via cargo.
## Usage
Run the main function.
## Contributing
Pull requests welcome.
## License
MIT License.
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("pmat").unwrap();
cmd.arg("quality-gate")
.arg("-p")
.arg(dir.path())
.arg("--checks")
.arg("complexity,satd,security,dead-code")
.arg("--format")
.arg("human");
cmd.assert()
.success()
.stderr(predicate::str::contains("Quality gate PASSED"));
}
#[test]
#[ignore] fn test_quality_gate_json_output() {
let dir = tempdir().unwrap();
let file = dir.path().join("issues.rs");
let test_debt_content = format!(
r#"
// {}: Fix this
fn complex() {{
if true {{
if false {{
// Nested complexity
}}
}}
}}
"#,
"TODO"
);
fs::write(&file, test_debt_content).unwrap();
let mut cmd = Command::cargo_bin("pmat").unwrap();
cmd.arg("quality-gate")
.arg("-p")
.arg(dir.path())
.arg("--format")
.arg("json")
.arg("--checks")
.arg("all");
cmd.assert()
.success()
.stdout(predicate::str::contains("\"passed\":"))
.stdout(predicate::str::contains("\"violations\":"));
}
#[test]
#[ignore = "Quality gate output format changed - test needs updating"]
fn test_quality_gate_ci_integration() {
let dir = tempdir().unwrap();
fs::write(
dir.path().join("complex.rs"),
r#"
fn nested() {
if true { if true { if true { if true { if true {
// Too deeply nested
}}}}}
}
"#,
)
.unwrap();
let debt_content = format!(
r#"
// {}: Critical bug here
// {}: Needs refactoring
fn debt() {{}}
"#,
"FIXME", "TODO"
);
fs::write(dir.path().join("debt.rs"), debt_content).unwrap();
let mut cmd = Command::cargo_bin("pmat").unwrap();
cmd.arg("quality-gate")
.arg("-p")
.arg(dir.path())
.arg("--format")
.arg("human")
.arg("--checks")
.arg("complexity,satd")
.arg("--max-complexity-p99")
.arg("3")
.arg("--fail-on-violation");
cmd.assert()
.failure()
.code(1)
.stdout(predicate::str::contains("# Quality Gate Report"))
.stdout(predicate::str::contains("Status: ❌ FAILED"))
.stdout(predicate::str::contains("## Violations:"));
}