use std::path::PathBuf;
use automapper_validation::{IssueKind, ValidationLevel};
use edifact_mapper::{DataDir, Mapper};
#[test]
fn every_sample_answer_is_a_code_of_its_list() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..");
let mapper = match Mapper::from_data_dir(DataDir::path(root.join("dist"))) {
Ok(m) => m,
Err(e) => panic!("the data bundles are a build artefact — run `bundle-data` first: {e}"),
};
let mut checked = 0usize;
let mut out = Vec::new();
let mut fvs: Vec<_> = std::fs::read_dir(root.join("fixtures/generated"))
.expect("fixtures")
.flatten()
.filter(|d| d.path().is_dir())
.collect();
fvs.sort_by_key(|d| d.file_name());
for fv_dir in fvs {
let fv = fv_dir.file_name().to_string_lossy().to_uppercase();
let mut msgs: Vec<_> = std::fs::read_dir(fv_dir.path())
.expect("fv dir")
.flatten()
.filter(|d| d.path().is_dir())
.collect();
msgs.sort_by_key(|d| d.file_name());
for msg_dir in msgs {
let msg = msg_dir.file_name().to_string_lossy().to_uppercase();
let mut files: Vec<_> = std::fs::read_dir(msg_dir.path())
.expect("msg dir")
.flatten()
.map(|f| f.path())
.filter(|p| p.extension().and_then(|e| e.to_str()) == Some("edi"))
.collect();
files.sort();
for p in files {
let stem = p
.file_stem()
.unwrap_or_default()
.to_string_lossy()
.into_owned();
let pid = mig_types::paths::sample_pid(&stem)
.unwrap_or(&stem)
.to_string();
let Ok(edi) = std::fs::read_to_string(&p) else {
continue;
};
let variants: Vec<String> = if msg == "UTILMD" {
vec![format!("{msg}_Strom"), format!("{msg}_Gas")]
} else {
vec![msg.clone()]
};
let Some(report) = variants.iter().find_map(|v| {
mapper
.validate_edifact_for_pid(&edi, &fv, v, &pid, ValidationLevel::Full)
.ok()
}) else {
continue;
};
checked += 1;
for issue in &report.issues {
if let IssueKind::AnswerNotInList { answer, list, .. } = &issue.kind {
out.push(format!(
"{fv} {msg} {stem}: {answer} not in {list} ({})",
issue.field_path.as_deref().unwrap_or("-")
));
}
}
}
}
}
assert!(checked > 1500, "only {checked} samples validated");
assert!(
out.is_empty(),
"{} answer(s) outside the list they name:\n{}",
out.len(),
out.join("\n")
);
}