use std::fs;
use std::path::Path;
use edifact_parser::{detect_format_version, DetectError};
const SUPPORTED_FVS: &[&str] = &["FV2504", "FV2510", "FV2604", "FV2610"];
#[test]
fn version_table_covers_mig_xml() {
let xml_root = Path::new("../../xml-migs-and-ahbs");
if !xml_root.exists() {
eprintln!("SKIP: xml-migs-and-ahbs submodule not present");
return;
}
let mut missing = Vec::new();
for fv in SUPPORTED_FVS {
let fv_dir = xml_root.join(fv);
if !fv_dir.exists() {
continue;
}
for entry in fs::read_dir(&fv_dir).unwrap() {
let entry = entry.unwrap();
let name = entry.file_name().to_string_lossy().to_string();
if !name.ends_with(".xml") || !name.contains("MIG") {
continue;
}
let Some(msg_type) = name.split('_').next() else {
continue;
};
let xml = fs::read_to_string(entry.path()).unwrap();
let Some(version) = extract_versionsnummer(&xml) else {
missing.push(format!("{fv}/{name}: no Versionsnummer attribute"));
continue;
};
let synthetic = format!(
"UNB+UNOC:3+s+r+250505:0826+R'\
UNH+R+{msg_type}:D:XXA:UN:{version}'\
UNT+1+R'UNZ+1+R'"
);
match detect_format_version(&synthetic) {
Ok(result) => {
let covered = result.format_version == *fv
|| result.note.as_deref().is_some_and(|n| n.contains(fv));
if !covered {
missing.push(format!("{fv}/{msg_type}/{version}"));
}
}
Err(DetectError::UnknownVersion { .. }) => {
missing.push(format!("{fv}/{msg_type}/{version}"));
}
Err(DetectError::UnsupportedMessageType { .. }) => {}
Err(other) => panic!("unexpected error for {msg_type} {version}: {other}"),
}
}
}
assert!(
missing.is_empty(),
"VERSION_TABLE missing entries (add to format_detection.rs):\n {}",
missing.join("\n ")
);
}
fn extract_versionsnummer(xml: &str) -> Option<String> {
let needle = "Versionsnummer=\"";
let start = xml.find(needle)? + needle.len();
let rest = &xml[start..];
let end = rest.find('"')?;
Some(rest[..end].to_string())
}