use std::path::{Path, PathBuf};
use standard_plugin_cli::check::check;
use standard_plugin_manifest::CATALOGUE;
fn sdk() -> Option<PathBuf> {
let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../standard-plugin-sdk");
root.join("docs").is_dir().then_some(root)
}
fn json_blocks(text: &str) -> Vec<String> {
let mut blocks = Vec::new();
let mut current: Option<String> = None;
for line in text.lines() {
let line = line
.strip_prefix("//!")
.map_or(line, |rest| rest.strip_prefix(' ').unwrap_or(rest));
match (&mut current, line.trim_start()) {
(None, "```json") => current = Some(String::new()),
(Some(block), "```") => {
blocks.push(std::mem::take(block));
current = None;
}
(Some(block), _) => {
block.push_str(line);
block.push('\n');
}
_ => {}
}
}
blocks
}
#[test]
fn documented_manifests_pass_check() {
let Some(root) = sdk() else {
eprintln!("skipped: the SDK crate is not beside this one");
return;
};
let mut files: Vec<PathBuf> = Vec::new();
for dir in ["docs", "examples"] {
for entry in std::fs::read_dir(root.join(dir)).unwrap() {
files.push(entry.unwrap().path());
}
}
let mut checked = 0;
for file in files {
let text = std::fs::read_to_string(&file).unwrap();
for block in json_blocks(&text) {
if !block.contains("\"apiVersion\"") {
continue;
}
let report = check(block.as_bytes(), None);
assert!(report.is_ok(), "{}:\n{block}\n{report}", file.display());
checked += 1;
}
}
assert!(checked >= 5, "found only {checked} manifests");
}
#[test]
fn the_grants_page_lists_the_whole_catalogue() {
let Some(root) = sdk() else {
return;
};
let page = std::fs::read_to_string(root.join("docs/grants.md")).unwrap();
for spec in CATALOGUE {
assert!(
page.contains(&format!("| `{}", spec.kind)),
"docs/grants.md does not list `{}`",
spec.kind
);
}
}
#[test]
fn every_guide_file_is_one_the_sdk_lists() {
let Some(root) = sdk() else {
return;
};
let mut files: Vec<String> = std::fs::read_dir(root.join("docs"))
.unwrap()
.map(|entry| entry.unwrap().path())
.filter(|path| path.extension().is_some_and(|extension| extension == "md"))
.map(|path| path.file_stem().unwrap().to_string_lossy().into_owned())
.collect();
files.sort();
let mut listed: Vec<String> = standard_plugin::sources::GUIDES
.iter()
.map(|guide| guide.name.to_string())
.collect();
listed.sort();
assert_eq!(
files, listed,
"docs/ and standard_plugin::sources::GUIDES differ"
);
}