test(examples): guard docs against low-level plumbing

Extend the canonical example contract to scan Markdown docs so they keep teaching generated ergonomic APIs instead of raw handles, registry/form types, or legacy HTML helpers.

req: dx/002

req: dx/003

req: examples/003
This commit is contained in:
slhx agent
2026-06-02 00:26:40 +02:00
parent df4b4cc649
commit a462e7f097
+36 -1
View File
@@ -99,6 +99,41 @@ fn canonical_examples_do_not_author_low_level_resource_plumbing() {
assert!(failures.is_empty(), "{}", failures.join("\n"));
}
#[test]
fn canonical_example_docs_do_not_teach_low_level_plumbing() {
// req: dx/002 req: dx/003 req: examples/003
let root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap();
let examples = root.join("examples");
let forbidden = [
"generated handle ids",
"numeric handle ids",
"manual registry",
"HandlerRegistry",
"InteractionForm",
"register_handle(",
"lower_html(",
"render_html(",
"SafeHtml::trusted",
];
let mut failures = Vec::new();
scan_examples(&examples, &mut |path, text| {
if path.extension().and_then(|ext| ext.to_str()) != Some("md") {
return;
}
for (line_no, line) in text.lines().enumerate() {
if let Some(token) = forbidden.iter().find(|token| line.contains(*token)) {
failures.push(format!(
"{}:{}: example docs must teach generated ergonomic APIs, not `{token}`",
path.display(),
line_no + 1
));
}
}
});
assert!(failures.is_empty(), "{}", failures.join("\n"));
}
#[test]
fn browser_e2e_does_not_shortcut_product_interactions() {
// req: examples/005
@@ -135,7 +170,7 @@ fn scan_examples(dir: &Path, visit: &mut impl FnMut(&Path, &str)) {
fn is_example_source(path: &PathBuf) -> bool {
matches!(
path.extension().and_then(|ext| ext.to_str()),
Some("rs" | "heml" | "html")
Some("rs" | "heml" | "html" | "md")
)
}