use std::collections::BTreeSet;
use std::path::PathBuf;
fn workspace_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..")
}
fn read(rel: &str) -> String {
let path = workspace_root().join(rel);
std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("read {}: {e}", path.display()))
}
fn recorded(marker: &str) -> BTreeSet<String> {
let doc = read("docs/architecture/REASON-CODE-VOCABULARIES.md");
let needle = format!("<!-- machine-checked: {marker} -->");
let after = doc
.split_once(&needle)
.unwrap_or_else(|| panic!("inventory has no `{needle}` marker"))
.1;
let block = after
.split_once("```text\n")
.unwrap_or_else(|| panic!("marker `{marker}` is not followed by a ```text block"))
.1;
let block = block
.split_once("\n```")
.unwrap_or_else(|| panic!("marker `{marker}` block is unterminated"))
.0;
block
.lines()
.map(str::trim)
.filter(|line| !line.is_empty())
.map(str::to_owned)
.collect()
}
fn diagnostic_codes() -> BTreeSet<String> {
let src = read("crates/assay-core/src/errors/diagnostic.rs");
let body = module_body(&src, "pub mod codes {");
let mut found = BTreeSet::new();
for line in body.lines() {
let line = line.trim();
let Some(rest) = line.strip_prefix("pub const ") else {
continue;
};
let value = rest
.split_once('=')
.and_then(|(_, v)| string_literal(v))
.unwrap_or_else(|| panic!("`pub const` in `codes` is not a string literal: {line}"));
assert!(
found.insert(value.clone()),
"duplicate code value {value:?} in `codes`"
);
}
assert!(!found.is_empty(), "parsed no codes; the module shape moved");
found
}
fn policy_engine_codes() -> BTreeSet<String> {
let src = read("crates/assay-core/src/policy_engine.rs");
let mut found = BTreeSet::new();
for line in src.lines() {
let trimmed = line.trim();
if trimmed.starts_with("//") || trimmed.starts_with("pub reason_code") {
continue;
}
let Some(rest) = trimmed.strip_prefix("reason_code:") else {
continue;
};
let value = string_literal(rest).unwrap_or_else(|| {
panic!(
"policy_engine `reason_code:` is not a string literal, so the inventory cannot \
cover it: {trimmed}"
)
});
found.insert(value);
}
assert!(
!found.is_empty(),
"parsed no policy-engine reason codes; the construction shape moved"
);
found
}
fn module_body<'a>(src: &'a str, header: &str) -> &'a str {
let start = src
.find(header)
.unwrap_or_else(|| panic!("source has no `{header}`"))
+ header.len();
let rest = &src[start..];
let mut depth = 1usize;
for (idx, ch) in rest.char_indices() {
match ch {
'{' => depth += 1,
'}' => {
depth -= 1;
if depth == 0 {
return &rest[..idx];
}
}
_ => {}
}
}
panic!("`{header}` is unterminated");
}
fn string_literal(s: &str) -> Option<String> {
let start = s.find('"')? + 1;
let end = s[start..].find('"')? + start;
Some(s[start..end].to_owned())
}
fn run_json_warning_codes() -> BTreeSet<String> {
const NOT_A_CODE: &[&str] = &[
"assertions_not_exercised",
];
let src = read("crates/assay-core/src/report/exercised.rs");
let mut found = BTreeSet::new();
for line in src.lines() {
let line = line.trim();
let Some(rest) = line.strip_prefix("pub const ") else {
continue;
};
let Some((_, value)) = rest.split_once('=') else {
continue;
};
let Some(value) = string_literal(value) else {
continue;
};
if NOT_A_CODE.contains(&value.as_str()) {
continue;
}
assert!(
found.insert(value.clone()),
"duplicate warning code value {value:?}"
);
}
assert!(
!found.is_empty(),
"parsed no run.json warning codes; the module shape moved"
);
found
}
fn lint_rule_ids() -> BTreeSet<String> {
assay_evidence::lint::rules::RULES
.iter()
.map(|rule| rule.id.to_owned())
.collect()
}
#[test]
fn inventory_records_every_diagnostic_code() {
assert_eq!(
diagnostic_codes(),
recorded("diagnostic-codes"),
"`assay_core::errors::diagnostic::codes` and the inventory disagree. A code that reaches \
a SARIF ruleId must be recorded in docs/architecture/REASON-CODE-VOCABULARIES.md, and \
recording it is where the decision about the other vocabularies on that surface goes."
);
}
#[test]
fn inventory_records_every_policy_engine_code() {
assert_eq!(
policy_engine_codes(),
recorded("policy-engine-codes"),
"`assay_core::policy_engine` verdict codes and the inventory disagree. These are forwarded \
verbatim into `Diagnostic::new` at validate/mod.rs:219 and become SARIF ruleIds under the \
same tool driver as `codes::`, so a new one is a new public id."
);
}
#[test]
fn inventory_records_every_lint_rule_id() {
assert_eq!(
lint_rule_ids(),
recorded("lint-rule-ids"),
"`assay_evidence::lint::rules::RULES` and the inventory disagree."
);
}
#[test]
fn inventory_records_every_run_json_warning_code() {
assert_eq!(
run_json_warning_codes(),
recorded("run-json-warning-codes"),
"`assay_core::report::exercised` and the inventory disagree. A code reaching the \
`warnings` array of run.json is a published id and belongs in \
docs/architecture/REASON-CODE-VOCABULARIES.md."
);
}
#[test]
fn the_run_json_warning_codes_are_not_in_the_sarif_registry() {
let warnings = run_json_warning_codes();
let sarif = diagnostic_codes();
let overlap: Vec<&String> = warnings.intersection(&sarif).collect();
assert!(
overlap.is_empty(),
"these codes are in both `report::exercised` and `codes::`, so the inventory records them \
on a SARIF surface they do not reach: {overlap:?}"
);
}
#[test]
fn the_two_sarif_rule_id_spaces_stay_disjoint() {
let assay_driver: BTreeSet<String> = diagnostic_codes()
.union(&policy_engine_codes())
.cloned()
.collect();
let lint_driver = lint_rule_ids();
let overlap: Vec<&String> = assay_driver.intersection(&lint_driver).collect();
assert!(
overlap.is_empty(),
"these ids exist in both SARIF ruleId vocabularies: {overlap:?}"
);
}
#[test]
fn the_generic_test_result_rule_id_shadows_nothing() {
const GENERIC: &str = "assay";
assert!(
!diagnostic_codes().contains(GENERIC),
"a `codes::` member is spelled {GENERIC:?}, which is the generic test-result ruleId"
);
assert!(
!policy_engine_codes().contains(GENERIC),
"a policy-engine reason code is spelled {GENERIC:?}, which is the generic test-result ruleId"
);
assert!(
!lint_rule_ids().contains(GENERIC),
"a lint rule id is spelled {GENERIC:?}, which is the generic test-result ruleId"
);
}