use std::process::Command;
fn boundary_cmd() -> Command {
Command::new(env!("CARGO_BIN_EXE_boundary"))
}
fn fixture(name: &str) -> String {
format!("{}/tests/fixtures/{name}", env!("CARGO_MANIFEST_DIR"))
}
fn analyze_json(fixture_name: &str) -> serde_json::Value {
let output = boundary_cmd()
.args(["analyze", &fixture(fixture_name), "--format", "json"])
.output()
.expect("failed to run boundary analyze");
let stdout = String::from_utf8_lossy(&output.stdout);
serde_json::from_str(&stdout).expect("output should be valid JSON")
}
#[test]
fn test_l006_violations_detected() {
let parsed = analyze_json("l006-framework-in-domain");
let violations = parsed["violations"]
.as_array()
.expect("should have violations array");
let l006_violations: Vec<_> = violations
.iter()
.filter(|v| v["rule"].as_str() == Some("L006"))
.collect();
assert!(
!l006_violations.is_empty(),
"should detect L006 violations for framework imports in domain, got violations: {violations:?}"
);
let has_gorm = l006_violations
.iter()
.any(|v| v["message"].as_str().unwrap_or("").contains("gorm"));
assert!(
has_gorm,
"L006 should detect gorm.io import in domain: {l006_violations:?}"
);
let has_gin = l006_violations
.iter()
.any(|v| v["message"].as_str().unwrap_or("").contains("gin"));
assert!(
has_gin,
"L006 should detect gin import in domain: {l006_violations:?}"
);
}
#[test]
fn test_l006_allowed_stdlib_not_flagged() {
let parsed = analyze_json("l006-framework-in-domain");
let violations = parsed["violations"]
.as_array()
.expect("should have violations array");
let l006_violations: Vec<_> = violations
.iter()
.filter(|v| v["rule"].as_str() == Some("L006"))
.collect();
let has_time = l006_violations
.iter()
.any(|v| v["message"].as_str().unwrap_or("").contains("\"time\""));
assert!(
!has_time,
"L006 should not flag allowed stdlib 'time': {l006_violations:?}"
);
}
#[test]
fn test_l006_infrastructure_not_flagged() {
let parsed = analyze_json("l006-framework-in-domain");
let violations = parsed["violations"]
.as_array()
.expect("should have violations array");
let l006_violations: Vec<_> = violations
.iter()
.filter(|v| v["rule"].as_str() == Some("L006"))
.collect();
let infra_gorm = l006_violations.iter().any(|v| {
let msg = v["message"].as_str().unwrap_or("");
msg.contains("GormInvoiceRepository")
});
assert!(
!infra_gorm,
"L006 should not flag infrastructure-layer gorm imports: {l006_violations:?}"
);
}
#[test]
fn test_l006_severity_and_doc_url() {
let parsed = analyze_json("l006-framework-in-domain");
let violations = parsed["violations"]
.as_array()
.expect("should have violations array");
let l006 = violations
.iter()
.find(|v| v["rule"].as_str() == Some("L006"))
.expect("should have at least one L006 violation");
assert_eq!(
l006["severity"].as_str(),
Some("error"),
"L006 default severity should be error"
);
assert_eq!(
l006["doc_url"].as_str(),
Some("https://rebelopsio.github.io/boundary/features/rules.html#l006"),
"L006 should have correct doc URL"
);
}