use super::common::values_structurally_equal;
use oatf::normalize::normalize;
use oatf::parse::parse;
use std::path::PathBuf;
fn conformance_dir() -> PathBuf {
std::env::var("OATF_CONFORMANCE_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("spec/conformance"))
}
#[derive(Debug, serde::Deserialize)]
struct TestCase {
name: String,
id: String,
input: String,
expected: String,
}
#[test]
fn normalize_conformance_suite() {
let suite_path = conformance_dir().join("normalize/suite.yaml");
assert!(
suite_path.exists(),
"Conformance fixture not found: {:?}. Is the spec submodule initialized?",
suite_path
);
let content = std::fs::read_to_string(&suite_path).unwrap();
let cases: Vec<TestCase> = serde_saphyr::from_str(&content).unwrap();
let mut passed = 0;
let mut failed = 0;
for case in &cases {
let doc = match parse(&case.input) {
Ok(d) => d,
Err(e) => {
eprintln!(" FAIL [{}] {}: parse error: {}", case.id, case.name, e);
failed += 1;
continue;
}
};
let normalized = normalize(doc);
let expected_value: serde_json::Value = serde_saphyr::from_str(&case.expected).unwrap();
let actual_value = serde_json::to_value(&normalized).unwrap();
if values_structurally_equal(&actual_value, &expected_value) {
passed += 1;
} else {
eprintln!(" FAIL [{}] {}", case.id, case.name);
eprintln!(
" Expected: {}",
serde_json::to_string_pretty(&expected_value).unwrap()
);
eprintln!(
" Actual: {}",
serde_json::to_string_pretty(&actual_value).unwrap()
);
failed += 1;
}
}
eprintln!(
"\nNormalize conformance: {} passed, {} failed out of {} total",
passed,
failed,
cases.len()
);
assert_eq!(failed, 0, "{} normalize conformance tests failed", failed);
}