use std::collections::BTreeSet;
use serde_json::Value;
const SPEC: &str = include_str!("../openapi.json");
const BRIDGE: &str = include_str!("../src/bridge.rs");
fn declared_v1_paths() -> BTreeSet<String> {
let mut set = BTreeSet::new();
let mut in_v1 = false;
for line in BRIDGE.lines() {
let trimmed = line.trim();
if trimmed.starts_with("let v1_routes") {
in_v1 = true;
continue;
}
if in_v1 && trimmed.starts_with("let app") {
break;
}
if !in_v1 {
continue;
}
if let Some(rest) = trimmed.split(".route(\"").nth(1) {
if let Some(path) = rest.split('"').next() {
set.insert(format!("/v1{path}"));
}
}
}
set
}
fn spec_paths() -> BTreeSet<String> {
let doc: Value = serde_json::from_str(SPEC).expect("openapi.json parses");
assert!(
doc["openapi"]
.as_str()
.unwrap_or_default()
.starts_with("3."),
"openapi.json should declare a 3.x document, found {:?}",
doc["openapi"]
);
doc["paths"]
.as_object()
.expect("openapi.json has a paths object")
.keys()
.cloned()
.collect()
}
#[test]
fn every_documented_path_is_a_real_route() {
let declared = declared_v1_paths();
assert!(
!declared.is_empty(),
"route extraction found nothing; the anchor in bridge.rs moved"
);
let documented = spec_paths();
let mut missing = Vec::new();
for path in &documented {
if path == "/openapi.json" {
assert!(
BRIDGE.contains(".route(\"/openapi.json\""),
"the spec serves {path} but bridge.rs does not mount it"
);
continue;
}
if !declared.contains(path) {
missing.push(path.clone());
}
}
assert!(
missing.is_empty(),
"openapi.json documents routes the bridge does not mount: {missing:?}"
);
}
#[test]
fn every_v1_route_is_documented() {
let declared = declared_v1_paths();
let documented = spec_paths();
let mut undocumented: Vec<_> = declared.difference(&documented).cloned().collect();
undocumented.sort();
assert!(
undocumented.is_empty(),
"the bridge mounts routes that openapi.json does not document: \
{undocumented:?}"
);
}