1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! Every built-in scenario kind must ship a runnable example.
//!
//! WHY
//! An enumeration of the 59 kinds against the bundled `scenarios/` directory found
//! five kinds with no file at all, and four of the five were capabilities this
//! programme had just built: the Fisher-information station covariance that removes a
//! published paper's modelled link, the campaign-driven Helmert datum, the datum from
//! real archived laser ranging, and the independent estimator that arbitrates another
//! paper's observability threshold. The engine gained the capabilities the papers
//! depend on and left a reader no way to run any of them by example.
//!
//! Documentation describes a capability; a scenario file *is* one. The difference
//! matters to anyone trying to believe a number: a bundled file can be run, diffed and
//! pointed at, and it is the unit an arXiv package can ship beside a manuscript.
//!
//! This is the enumeration itself, wired as a gate, so a new kind cannot be added
//! without an example. It is deliberately a coverage test and not a content test: it
//! asserts that every kind is reachable from a bundled document, nothing about what
//! that document contains.
use std::collections::{BTreeMap, BTreeSet};
/// Read every bundled `.toml` and map it to the kind it classifies as.
fn bundled_examples() -> BTreeMap<String, Vec<String>> {
let mut by_kind: BTreeMap<String, Vec<String>> = BTreeMap::new();
let dir = std::fs::read_dir("scenarios").expect("scenarios/ must exist");
let mut paths: Vec<std::path::PathBuf> = dir
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("toml"))
.collect();
paths.sort();
for p in paths {
let src = std::fs::read_to_string(&p).expect("readable scenario");
// An unparseable or unknown-kind document is a separate failure, reported by
// name rather than silently skipped — that silence is what this campaign's
// other findings kept turning out to be.
let kind = kshana::api::ScenarioKind::classify(&src).unwrap_or_else(|e| {
panic!("{} does not classify: {e}", p.display());
});
by_kind
.entry(kind.as_str().to_string())
.or_default()
.push(p.file_name().unwrap().to_string_lossy().into_owned());
}
by_kind
}
#[test]
fn every_scenario_kind_ships_a_runnable_example() {
let by_kind = bundled_examples();
let missing: Vec<&str> = kshana::api::list_scenario_kinds()
.iter()
.map(|m| m.name)
.filter(|name| !by_kind.contains_key(*name))
.collect();
assert!(
missing.is_empty(),
"these scenario kinds ship no file under scenarios/, so a reader cannot run \
them by example:\n {}\n\nAdd one file per kind. Every one of these takes no \
required fields, so a single `kind = \"...\"` line with a header explaining \
what the run shows is enough.",
missing.join("\n ")
);
}
#[test]
fn every_bundled_example_names_a_kind_the_engine_has() {
// The other direction: a file naming a kind the engine dropped would sit in the
// directory looking runnable and fail only when someone ran it. Since an unknown
// kind is now an error rather than a silent fallback to the clock pack,
// `bundled_examples` would already have panicked — this states the invariant so the
// reason is in the assertion rather than in a panic message.
let known: BTreeSet<&str> = kshana::api::list_scenario_kinds()
.iter()
.map(|m| m.name)
.collect();
for kind in bundled_examples().keys() {
assert!(
known.contains(kind.as_str()),
"a bundled scenario classifies as {kind:?}, which is not a built-in kind"
);
}
}