Skip to main content

max / makenotwork

2.1 KB · 65 lines History Blame Raw
1 //! CI guard for business assumptions.
2 //!
3 //! Catches at PR time what would otherwise only fail at prod boot:
4 //! - `docs/internal/business/assumptions.toml` parses
5 //! - All consistency rules pass (sums, bounds, founding ≤ standard)
6 //! - Every `{{ ... }}` marker in the live site-docs corpus resolves
7 //!
8 //! Run with: cargo test --test assumptions
9
10 use docengine::Assumptions;
11
12 // Canonical assumptions.toml moved to _private/ on 2026-05-20. Test runs from
13 // the server crate's cwd (MNW/server/); one level up gets to MNW/, two gets
14 // to ~/Code/. Production uses ASSUMPTIONS_PATH env override (see main.rs).
15 const ASSUMPTIONS_PATH: &str =
16 "../../_private/docs/mnw/server-internal/business/assumptions.toml";
17 const SITE_DOCS_PATH: &str = "site-docs/public";
18
19 #[test]
20 fn real_assumptions_file_parses_and_validates() {
21 let a = Assumptions::load(ASSUMPTIONS_PATH)
22 .unwrap_or_else(|e| panic!("failed to load {ASSUMPTIONS_PATH}: {e}"));
23 a.validate()
24 .unwrap_or_else(|e| panic!("assumptions failed validation:\n{e}"));
25 }
26
27 #[test]
28 fn every_marker_in_site_docs_resolves() {
29 let a = Assumptions::load(ASSUMPTIONS_PATH).expect("load");
30
31 let mut failures = Vec::new();
32 visit_markdown(std::path::Path::new(SITE_DOCS_PATH), &mut |path, body| {
33 if !body.contains("{{") {
34 return;
35 }
36 if let Err(e) = a.substitute(body) {
37 failures.push(format!(" {}: {e}", path.display()));
38 }
39 });
40
41 if !failures.is_empty() {
42 panic!(
43 "{} doc(s) contain unresolved {{{{ … }}}} markers:\n{}",
44 failures.len(),
45 failures.join("\n")
46 );
47 }
48 }
49
50 fn visit_markdown(dir: &std::path::Path, f: &mut impl FnMut(&std::path::Path, &str)) {
51 let Ok(entries) = std::fs::read_dir(dir) else {
52 return;
53 };
54 for entry in entries.flatten() {
55 let path = entry.path();
56 if path.is_dir() {
57 visit_markdown(&path, f);
58 } else if path.extension().and_then(|s| s.to_str()) == Some("md") {
59 if let Ok(body) = std::fs::read_to_string(&path) {
60 f(&path, &body);
61 }
62 }
63 }
64 }
65