use std::collections::BTreeSet;
use std::fs;
fn cited_test_names(doc: &str) -> BTreeSet<String> {
let mut names = BTreeSet::new();
for line in doc.lines() {
if !line.starts_with('|') {
continue;
}
let cells: Vec<&str> = line.split('|').map(str::trim).collect();
if cells.len() != 5 {
continue;
}
let test_cell = cells[2];
if let Some(name) = test_cell.strip_prefix('`').and_then(|c| c.strip_suffix('`')) {
if name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') && name.contains('_') {
names.insert(name.to_string());
}
}
}
names
}
#[test]
fn the_mutation_ids_match_the_script() {
let doc = fs::read_to_string("THREAT_MODEL.md").expect("THREAT_MODEL.md is missing");
let script = fs::read_to_string("verify-guarantees.sh").expect("verify-guarantees.sh is missing");
let mut cited = BTreeSet::new();
for line in doc.lines().filter(|l| l.starts_with('|')) {
let cells: Vec<&str> = line.split('|').map(str::trim).collect();
if cells.len() != 5 {
continue;
}
if let Some(id) = cells[3].strip_prefix('`').and_then(|c| c.strip_suffix('`')) {
if id.contains('-') {
cited.insert(id.to_string());
}
}
}
let defined: BTreeSet<String> = script
.lines()
.filter_map(|l| l.strip_prefix("check "))
.filter_map(|rest| rest.split_whitespace().next())
.map(str::to_string)
.collect();
assert_eq!(
cited, defined,
"THREAT_MODEL.md's mutation ids and verify-guarantees.sh's checks have diverged"
);
}
#[test]
fn every_test_cited_by_the_threat_model_exists() {
let doc = fs::read_to_string("THREAT_MODEL.md").expect("THREAT_MODEL.md is missing");
let cited = cited_test_names(&doc);
assert!(
cited.len() >= 10,
"only {} citations parsed — the table format probably changed and this check has \
stopped guarding anything: {cited:?}",
cited.len()
);
let mut defined = BTreeSet::new();
let dirs = ["tests", "tests/unit"];
for dir in dirs {
let Ok(entries) = fs::read_dir(dir) else {
continue;
};
for entry in entries.flatten() {
let path = entry.path();
if path.extension().is_none_or(|e| e != "rs") {
continue;
}
let Ok(source) = fs::read_to_string(&path) else {
continue;
};
for line in source.lines() {
let line = line.trim();
let Some(rest) = line.strip_prefix("async fn ").or_else(|| line.strip_prefix("fn ")) else {
continue;
};
if let Some(name) = rest.split('(').next() {
defined.insert(name.trim().to_string());
}
}
}
}
let missing: Vec<&String> = cited.iter().filter(|name| !defined.contains(*name)).collect();
assert!(
missing.is_empty(),
"THREAT_MODEL.md cites tests that no longer exist: {missing:?}\n\
Either restore the test or remove the guarantee's row — a cited test that is gone \
means the guarantee is no longer proven."
);
}