#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use ssg::seo::validate_jsonld;
use std::{fs, path::Path};
fn collect_html(dir: &Path, out: &mut Vec<std::path::PathBuf>) {
let Ok(entries) = fs::read_dir(dir) else {
return;
};
for entry in entries.flatten() {
let p = entry.path();
if p.is_dir() {
collect_html(&p, out);
} else if p.extension().is_some_and(|e| e == "html") {
out.push(p);
}
}
}
#[test]
fn every_jsonld_block_in_built_examples_is_valid() {
let workspace = Path::new(env!("CARGO_MANIFEST_DIR"));
let examples = workspace.join("examples");
let mut html_files = Vec::new();
if examples.is_dir() {
for entry in fs::read_dir(&examples).unwrap().flatten() {
let public = entry.path().join("public");
if public.is_dir() {
collect_html(&public, &mut html_files);
}
}
}
if html_files.is_empty() {
eprintln!(
"[jsonld_validation] no built example output found under \
examples/*/public — run `cargo build --examples && \
cargo test --test example_outputs` first to populate. \
Skipping (this is not a failure)."
);
return;
}
let mut all_errors: Vec<(std::path::PathBuf, _)> = Vec::new();
for path in &html_files {
let html = fs::read_to_string(path).unwrap();
let errors = validate_jsonld(&html);
if !errors.is_empty() {
for err in errors {
all_errors.push((path.clone(), err));
}
}
}
if !all_errors.is_empty() {
let mut msg = format!(
"{} JSON-LD validation error(s) across {} file(s):\n",
all_errors.len(),
html_files.len()
);
for (path, err) in &all_errors {
msg.push_str(&format!(
" {}: {err}\n",
path.strip_prefix(workspace).unwrap_or(path).display()
));
}
panic!("{msg}");
}
eprintln!(
"[jsonld_validation] {} HTML file(s) scanned, all JSON-LD blocks \
pass schema.org required-field checks",
html_files.len()
);
}