#![allow(clippy::unwrap_used, clippy::expect_used)]
use std::collections::BTreeSet;
use std::fs;
use std::path::{Path, PathBuf};
use mcp_conformance_core::requirement::{Registry, Verification};
const WITHOUT_A_PASSING_TRACE: &[(&str, &str)] = &[];
fn corpus_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../corpus")
}
fn passing_ids(directory: &Path) -> BTreeSet<String> {
#[derive(serde::Deserialize)]
struct Golden {
requirements: Vec<Row>,
}
#[derive(serde::Deserialize)]
struct Row {
id: String,
outcome: String,
}
let mut passing = BTreeSet::new();
let entries = fs::read_dir(directory)
.unwrap_or_else(|error| panic!("cannot read {}: {error}", directory.display()));
let mut seen = 0_usize;
for entry in entries {
let path = entry.unwrap().path();
if path.extension().is_none_or(|ext| ext != "json") {
continue;
}
seen += 1;
let text = fs::read_to_string(&path).unwrap();
let golden: Golden = serde_json::from_str(&text)
.unwrap_or_else(|error| panic!("{} is not a golden report: {error}", path.display()));
for row in golden.requirements {
if row.outcome == "pass" {
passing.insert(row.id);
}
}
}
assert!(seen > 0, "no goldens under {}", directory.display());
passing
}
fn judged_ids(registry: &Registry) -> BTreeSet<String> {
registry
.requirements()
.iter()
.filter(|requirement| matches!(requirement.verification, Verification::Checks { .. }))
.map(|requirement| requirement.id.to_string())
.collect()
}
fn gap(registry: &Registry, goldens: &Path) -> BTreeSet<String> {
&judged_ids(registry) - &passing_ids(goldens)
}
fn corpora() -> Vec<(Registry, PathBuf)> {
#[cfg(feature = "draft-2026-07-28")]
let draft = vec![(
mcp_conformance_core::requirement::RegistrySet::builtin()
.unwrap()
.registry("2026-07-28".parse().unwrap())
.expect("the draft feature describes 2026-07-28"),
corpus_root().join("golden/draft"),
)];
#[cfg(not(feature = "draft-2026-07-28"))]
let draft = Vec::new();
core::iter::once((
Registry::builtin_2025_11_25().unwrap(),
corpus_root().join("golden"),
))
.chain(draft)
.collect()
}
#[test]
fn the_ledger_of_clauses_without_a_passing_trace_is_exact() {
let measured: BTreeSet<String> = corpora()
.iter()
.flat_map(|(registry, goldens)| gap(registry, goldens))
.collect();
let ledger: BTreeSet<String> = WITHOUT_A_PASSING_TRACE
.iter()
.map(|&(id, _)| id.to_owned())
.filter(|id| cfg!(feature = "draft-2026-07-28") || id_is_shipped(id))
.collect();
let unlisted: Vec<&String> = measured.difference(&ledger).collect();
assert!(
unlisted.is_empty(),
"these judged clauses have no trace that passes them, and no ledger row \
says why — add a conforming trace, or a row: {unlisted:#?}"
);
let retired: Vec<&String> = ledger.difference(&measured).collect();
assert!(
retired.is_empty(),
"these clauses now have a passing trace; delete their ledger rows: {retired:#?}"
);
}
fn id_is_shipped(id: &str) -> bool {
judged_ids(&Registry::builtin_2025_11_25().unwrap()).contains(id)
}
#[test]
fn every_ledger_row_names_a_judged_clause_and_gives_a_reason() {
let judged: BTreeSet<String> = corpora()
.iter()
.flat_map(|(registry, _)| judged_ids(registry))
.collect();
let ids: BTreeSet<&str> = WITHOUT_A_PASSING_TRACE.iter().map(|&(id, _)| id).collect();
assert_eq!(
ids.len(),
WITHOUT_A_PASSING_TRACE.len(),
"duplicate ledger row"
);
for &(id, reason) in WITHOUT_A_PASSING_TRACE {
assert!(
judged.contains(id),
"{id} is not a clause any built registry judges, so no trace could pass it"
);
assert!(
reason.len() > 30,
"{id}'s row must say what conforming trace is missing, not just that one is"
);
}
}