use std::collections::{BTreeMap, BTreeSet};
use std::path::{Path, PathBuf};
const EXEMPT: &[(&str, &str)] = &[
(
"BlurbMismatch",
"RESERVED BY DESIGN, not a gap. `validate.rs:40` records that the \
prose/structured blurb equality check (§10.11) is performed by the \
layer holding the raw markdown, and that this variant `stays reserved` \
for it. Nothing constructs it, so there is nothing to provoke.",
),
(
"UnauditedPrecision",
"DEAD CLAUSE — genuinely unreachable, and this gate is how it became \
visible. The variant appears NOWHERE outside `error.rs`: not \
constructed, not matched, not even named in a doc comment. This is the \
precision half of V-FKC-9, recorded as a wiring DECISION rather than a \
defect. It is exempted because no test can provoke an error no code \
emits — writing one would require wiring the validator first.",
),
(
"Io",
"Infrastructure, not a contract rule. Constructed on filesystem read \
failure in the loader. Provoking it in-process means an unreadable \
path, which is a harness-portability problem rather than a contract \
assertion. Low value, non-zero cost; deliberately deferred.",
),
(
"Yaml",
"Infrastructure, not a contract rule. Wraps the YAML parser's own \
error. The FKC-specific YAML restrictions that DO carry contract \
meaning have their own variants (`TabIndentation`, `AnchorDisallowed`, \
`AliasDisallowed`, `MergeKeyDisallowed`, `NorwayToken`) and every one \
of those IS covered — so the meaningful surface here is tested, and \
this variant is the uninteresting remainder.",
),
];
const MIN_EXPECTED_CLAUSES: usize = 40;
const MUST_DETECT_AS_COVERED: &[&str] = &[
"LayoutIncoherent",
"QuantIncoherent",
"MissingRequiredField",
];
fn crate_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}
fn derive_clauses() -> BTreeSet<String> {
let path = crate_root().join("src/fkc/error.rs");
let src = std::fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("cannot read the clause source {}: {e}", path.display()));
let start = src.find("pub enum FkcError").unwrap_or_else(|| {
panic!(
"`pub enum FkcError` not found in {} — the clause set moved; \
this gate must be repointed, NOT deleted",
path.display()
)
});
let body = &src[start..];
let mut out = BTreeSet::new();
for line in body.lines() {
let Some(rest) = line.strip_prefix(" ") else {
continue;
};
if rest.starts_with(' ') || rest.starts_with("//") || rest.starts_with('#') {
continue;
}
let name: String = rest.chars().take_while(|c| c.is_alphanumeric()).collect();
if name.is_empty() || !name.starts_with(|c: char| c.is_ascii_uppercase()) {
continue;
}
let after = rest[name.len()..].trim_start();
if after.starts_with('{') || after.starts_with('(') || after.starts_with(',') {
out.insert(name);
}
}
out
}
fn rust_sources() -> Vec<PathBuf> {
let mut files = Vec::new();
fn walk(dir: &Path, files: &mut Vec<PathBuf>) {
let rd = std::fs::read_dir(dir).unwrap_or_else(|e| {
panic!(
"rust_sources: read_dir({}) failed: {e} — the clause-coverage corpus must FAIL, not silently truncate",
dir.display()
)
});
for entry in rd.flatten() {
let p = entry.path();
if p.is_dir() {
if p.file_name().is_some_and(|n| n == "target") {
continue;
}
walk(&p, files);
} else if p.extension().is_some_and(|e| e == "rs") {
files.push(p);
}
}
}
walk(&crate_root().join("src"), &mut files);
walk(&crate_root().join("tests"), &mut files);
files
}
fn cited_by_tests(clauses: &BTreeSet<String>) -> BTreeMap<String, Vec<String>> {
let mut cited: BTreeMap<String, Vec<String>> = BTreeMap::new();
for file in rust_sources() {
let Ok(src) = std::fs::read_to_string(&file) else {
continue;
};
let label = file
.strip_prefix(crate_root())
.unwrap_or(&file)
.to_string_lossy()
.replace('\\', "/");
let (mut depth, mut in_test, mut arm, mut entered) = (0i32, false, 0i32, false);
for line in src.lines() {
let trimmed = line.trim_start();
if !in_test && (trimmed.starts_with("#[cfg(test)]") || trimmed.starts_with("#[test]")) {
in_test = true;
arm = depth;
entered = false;
}
if in_test && !trimmed.starts_with("//") {
for c in clauses {
if line.contains(&format!("FkcError::{c}"))
|| line.contains(&format!("Self::{c}"))
{
let entry = cited.entry(c.clone()).or_default();
if !entry.contains(&label) {
entry.push(label.clone());
}
}
}
}
depth += line.matches('{').count() as i32 - line.matches('}').count() as i32;
if in_test {
if depth > arm {
entered = true;
} else if entered {
in_test = false;
entered = false;
}
}
}
}
cited
}
#[test]
fn every_clause_is_cited_by_a_test() {
let clauses = derive_clauses();
let cited = cited_by_tests(&clauses);
assert!(
clauses.len() >= MIN_EXPECTED_CLAUSES,
"clause DERIVATION collapsed: found only {} clauses (expected >= {}). \
The scanner is broken, not the tree — a green here would have been vacuous.",
clauses.len(),
MIN_EXPECTED_CLAUSES
);
for probe in MUST_DETECT_AS_COVERED {
assert!(
cited.contains_key(*probe),
"SCANNER IS BLIND: `{probe}` is cited by tests in this crate, but the \
test-region scan did not see it. Every 'uncovered' result below is \
therefore untrustworthy. Suspect the #[cfg(test)] brace tracking."
);
}
let exempt: BTreeSet<&str> = EXEMPT.iter().map(|(v, _)| *v).collect();
let uncovered: Vec<&String> = clauses
.iter()
.filter(|c| !cited.contains_key(*c) && !exempt.contains(c.as_str()))
.collect();
assert!(
uncovered.is_empty(),
"FKC clause->test totality FAILED — {} clause(s) can be raised by the \
validator but no test provokes them:\n{}\n\n\
This is the 'existence != enforcement' class: a rejection nothing \
proves is reachable. Either add a test that provokes it, or add an \
entry to EXEMPT with a reason a reader can check.",
uncovered.len(),
uncovered
.iter()
.map(|c| format!(" - FkcError::{c}"))
.collect::<Vec<_>>()
.join("\n")
);
}
#[test]
fn no_orphan_exemptions() {
let clauses = derive_clauses();
assert!(
clauses.len() >= MIN_EXPECTED_CLAUSES,
"clause derivation collapsed"
);
let orphans: Vec<&str> = EXEMPT
.iter()
.map(|(v, _)| *v)
.filter(|v| !clauses.contains(*v))
.collect();
assert!(
orphans.is_empty(),
"orphan exemption(s) naming clauses that no longer exist: {orphans:?}\n\
Remove them. A stale exemption silently pre-authorises a future clause \
of the same name to skip coverage."
);
}
#[test]
fn exemptions_are_still_necessary_and_the_scanner_discriminates() {
let clauses = derive_clauses();
let cited = cited_by_tests(&clauses);
assert!(
clauses.len() >= MIN_EXPECTED_CLAUSES,
"clause derivation collapsed"
);
let now_covered: Vec<&str> = EXEMPT
.iter()
.map(|(v, _)| *v)
.filter(|v| cited.contains_key(*v))
.collect();
assert!(
now_covered.is_empty(),
"exemption(s) no longer needed — these are now cited by tests: {now_covered:?}\n\n\
Two possible causes, and they need opposite responses:\n\
(a) someone wrote the test — DELETE the entry from EXEMPT so the clause \
is held to real coverage from now on; or\n\
(b) the scanner is OVER-INCLUDING (counting production code as test \
code), in which case every 'covered' verdict in this file is worthless \
and the region tracking is broken. Rule out (b) before assuming (a)."
);
}
#[test]
fn every_exemption_states_a_reason() {
for (variant, reason) in EXEMPT {
let r = reason.trim();
assert!(
r.len() >= 40,
"exemption for `{variant}` has no substantive reason ({} chars). \
State why it cannot or should not be provoked.",
r.len()
);
assert!(
!r.to_ascii_uppercase().contains("TODO") && !r.to_ascii_uppercase().contains("FIXME"),
"exemption for `{variant}` is a placeholder, not a decision"
);
}
}