brick/tests/policy_cli.rs
trvon 3fec92f10c
Some checks failed
build / build-linux (push) Successful in 1m3s
build / build-macos (push) Has been cancelled
build / release (push) Has been cancelled
feat: make source graphs accurate across C++ JS TS Dart and Rust
Use pinned grammar frontends and scoped heuristic resolution to recover declarations and prevent false dependencies. Constrain filesystem traversal and normalize Fold root aliases.

Add exact multilingual fixtures, seventeen regression tests, and a three-repeat benchmark to the quality gate.
2026-09-04 23:05:06 -06:00

135 lines
4.5 KiB
Rust

use brick::scan;
use serde_json::Value;
use std::fs;
use std::path::Path;
use std::process::Command;
fn fixture(name: &str) -> String {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/policy")
.join(name)
.display()
.to_string()
}
#[test]
fn check_evaluates_policy_with_complete_evidence_and_clean_negative() {
let directory = tempfile::tempdir().unwrap();
let project = directory.path().join("project");
fs::create_dir_all(project.join("src/api")).unwrap();
fs::create_dir_all(project.join("src/storage")).unwrap();
fs::write(
project.join("src/api/handler.rs"),
"fn handle() { crate::storage::db::query(); }\n",
)
.unwrap();
fs::write(project.join("src/storage/db.rs"), "pub fn query() {}\n").unwrap();
let model = scan::scan(&project).unwrap();
let graph = directory.path().join("graph.json");
fs::write(&graph, serde_json::to_vec_pretty(&model).unwrap()).unwrap();
let violation_result = directory.path().join("violation-result.json");
let violating = Command::new(env!("CARGO_BIN_EXE_brick"))
.args([
"check",
graph.to_str().unwrap(),
"--min-score",
"101",
"--policy",
&fixture("forbid-api-storage.json"),
"--policy-result-json",
violation_result.to_str().unwrap(),
])
.output()
.unwrap();
assert!(!violating.status.success());
let violation_stderr = String::from_utf8_lossy(&violating.stderr);
assert!(violation_stderr.contains("score"));
assert!(violation_stderr.contains("api-must-not-call-storage matched 1 dependencies; max 0"));
let result: Value = serde_json::from_slice(&fs::read(violation_result).unwrap()).unwrap();
assert_eq!(result["policy_result_schema_version"], 1);
assert_eq!(result["policy_schema_version"], 1);
assert_eq!(result["building_schema_version"], 4);
assert_eq!(result["passed"], false);
assert_eq!(
result["rules"][0]["matched_edges"]
.as_array()
.unwrap()
.len(),
1
);
assert_eq!(
result["rules"][0]["matched_edges"][0]["edge"]["evidence"][0]["backend"],
"tree-sitter-rust:0.24.2:brick-source-v1:heuristic-resolver-v2"
);
let clean_result = directory.path().join("clean-result.json");
let clean = Command::new(env!("CARGO_BIN_EXE_brick"))
.args([
"check",
graph.to_str().unwrap(),
"--min-score",
"0",
"--policy",
&fixture("clean-ui-storage.json"),
"--policy-result-json",
clean_result.to_str().unwrap(),
])
.output()
.unwrap();
assert!(
clean.status.success(),
"{}",
String::from_utf8_lossy(&clean.stderr)
);
let clean_value: Value = serde_json::from_slice(&fs::read(clean_result).unwrap()).unwrap();
assert_eq!(clean_value["passed"], true);
assert!(
clean_value["rules"][0]["matched_edges"]
.as_array()
.unwrap()
.is_empty()
);
}
#[test]
fn check_rejects_policy_output_without_policy_and_unknown_wire_values() {
let directory = tempfile::tempdir().unwrap();
fs::write(directory.path().join("lib.rs"), "fn example() {}\n").unwrap();
let graph = directory.path().join("graph.json");
fs::write(
&graph,
serde_json::to_vec_pretty(&scan::scan(directory.path()).unwrap()).unwrap(),
)
.unwrap();
let missing = Command::new(env!("CARGO_BIN_EXE_brick"))
.args([
"check",
graph.to_str().unwrap(),
"--min-score",
"0",
"--policy-result-json",
directory.path().join("result.json").to_str().unwrap(),
])
.output()
.unwrap();
assert!(!missing.status.success());
assert!(String::from_utf8_lossy(&missing.stderr).contains("requires --policy"));
for invalid in ["invalid-unknown-kind.json", "invalid-unknown-key.json"] {
let output = Command::new(env!("CARGO_BIN_EXE_brick"))
.args([
"check",
graph.to_str().unwrap(),
"--min-score",
"0",
"--policy",
&fixture(invalid),
])
.output()
.unwrap();
assert!(!output.status.success(), "{invalid}");
assert!(String::from_utf8_lossy(&output.stderr).contains("invalid architecture policy"));
}
}