use std::collections::BTreeMap;
use std::path::Path;
use openusd::sdf;
use openusd::usda::TextReader;
const ASSETS: &str = "vendor/core-spec-supplemental-release_dec2025/file_formats/tests/assets/text";
fn assert_text_format(name: &str) {
let assets = Path::new(ASSETS);
let usda = assets.join("usda").join(format!("{name}.usda"));
let baseline = assets.join("baseline").join(format!("{name}.json"));
let reader = TextReader::read(&usda).unwrap_or_else(|e| panic!("failed to parse {}: {e:#}", usda.display()));
let mut actual: BTreeMap<String, BTreeMap<&str, &sdf::Value>> = BTreeMap::new();
for (path, spec) in reader.iter() {
let fields: BTreeMap<&str, &sdf::Value> = spec.fields.iter().map(|(k, v)| (k.as_str(), v)).collect();
actual.insert(path.to_string(), fields);
}
let mut actual_json = serde_json::to_value(&actual).expect("failed to serialize actual data");
let mut expected_json: serde_json::Value =
serde_json::from_str(&std::fs::read_to_string(&baseline).expect("failed to read baseline"))
.expect("failed to parse baseline JSON");
normalize_json(&mut actual_json);
normalize_json(&mut expected_json);
let diffs = diff_json::compare_values(&actual_json, &expected_json);
assert!(
diffs.is_empty(),
"mismatch for {name}:\n{}",
diff_json::DiffFormatter::new().format(&diffs)
);
}
fn normalize_json(v: &mut serde_json::Value) {
match v {
serde_json::Value::Number(n) if n.is_f64() => {
let f = n.as_f64().unwrap();
if f.fract() == 0.0 && f.is_finite() && f.abs() < i64::MAX as f64 {
*v = serde_json::Value::from(f as i64);
} else {
let short = format!("{}", f as f32);
let long = format!("{f}");
if short.len() < long.len() {
if let Ok(clean) = short.parse::<f64>() {
*v = serde_json::json!(clean);
}
}
}
}
serde_json::Value::Array(a) => a.iter_mut().for_each(normalize_json),
serde_json::Value::Object(m) => {
if m.contains_key("layerOffset") || m.contains_key("asset") {
m.remove("customData");
}
m.values_mut().for_each(normalize_json);
}
_ => {}
}
}
mod text_parser {
use super::*;
#[test]
fn test_empty() {
assert_text_format("empty");
}
#[test]
fn test_simple() {
assert_text_format("simple");
}
#[test]
fn test_attributes() {
assert_text_format("attributes");
}
#[test]
fn test_relations() {
assert_text_format("relations");
}
#[test]
fn test_primmetadata() {
assert_text_format("primmetadata");
}
#[test]
fn test_layermetadata() {
assert_text_format("layermetadata");
}
#[test]
fn test_dictionaries() {
assert_text_format("dictionaries");
}
#[test]
fn test_splines() {
assert_text_format("splines");
}
#[test]
fn test_variants() {
assert_text_format("variants");
}
#[test]
fn test_geometryattributes() {
assert_text_format("geometryattributes");
}
}