#![cfg(feature = "serde")]
use std::fs;
use std::path::Path;
const KNOWN_VARIANTS: &[&str] = &[
"Integer",
"Float",
"Rational",
"Complex",
"Quaternion",
"Variable",
"Constant",
"Binary",
"Unary",
"Function",
"Derivative",
"PartialDerivative",
"Integral",
"MultipleIntegral",
"ClosedIntegral",
"Limit",
"Sum",
"Product",
"Vector",
"Matrix",
"Equation",
"Inequality",
"ForAll",
"Exists",
"Logical",
"MarkedVector",
"DotProduct",
"CrossProduct",
"OuterProduct",
"Gradient",
"Divergence",
"Curl",
"Laplacian",
"Nabla",
"Determinant",
"Trace",
"Rank",
"ConjugateTranspose",
"MatrixInverse",
"NumberSetExpr",
"SetOperation",
"SetRelationExpr",
"SetBuilder",
"EmptySet",
"PowerSet",
"Tensor",
"KroneckerDelta",
"LeviCivita",
"FunctionSignature",
"Composition",
"Differential",
"WedgeProduct",
"Relation",
];
#[test]
fn manifest_file_lists_all_known_variants() {
let manifest_path =
Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/serde/variant_manifest.txt");
if std::env::var("MATHLEX_UPDATE_GOLDEN").is_ok() {
fs::create_dir_all(manifest_path.parent().unwrap()).unwrap();
let content = KNOWN_VARIANTS.join("\n") + "\n";
fs::write(&manifest_path, content).unwrap();
return;
}
let manifest = fs::read_to_string(&manifest_path).unwrap_or_else(|_| {
panic!(
"Missing variant manifest: {}\nRun with MATHLEX_UPDATE_GOLDEN=1 to generate",
manifest_path.display()
)
});
let manifest_variants: Vec<&str> = manifest.lines().filter(|l| !l.is_empty()).collect();
for variant in manifest_variants.iter() {
assert!(
KNOWN_VARIANTS.contains(variant),
"Variant '{}' from manifest is no longer in KNOWN_VARIANTS — \
this is a breaking wire-format change. Update KNOWN_VARIANTS \
and bump the major version.",
variant
);
}
}
#[test]
fn all_known_variants_have_golden_fixture() {
let fixture_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/serde");
if std::env::var("MATHLEX_UPDATE_GOLDEN").is_ok() {
return;
}
fn to_snake_case(s: &str) -> String {
let mut out = String::new();
for (i, ch) in s.chars().enumerate() {
if ch.is_uppercase() && i > 0 {
out.push('_');
}
out.extend(ch.to_lowercase());
}
out
}
for variant in KNOWN_VARIANTS {
let snake = to_snake_case(variant);
let found = fixture_dir
.read_dir()
.map(|rd| {
rd.filter_map(|e| e.ok())
.filter_map(|e| {
e.path()
.file_stem()
.and_then(|s| s.to_str().map(|s| s.to_owned()))
})
.any(|stem| stem == snake || stem.starts_with(&format!("{}_", snake)))
})
.unwrap_or(false);
assert!(
found,
"No golden fixture found for variant '{}' (expected file starting with \
'tests/fixtures/serde/{}.json'). \
Run with MATHLEX_UPDATE_GOLDEN=1 after adding a test in golden_fixtures.rs.",
variant, snake
);
}
}