DazedTL/util/wolfdawn-master/crates/wolf-formats/tests/ver5_archive.rs
2026-07-03 13:54:07 -05:00

73 lines
2.8 KiB
Rust

//! Verify the DXArchive VER5 decoder against the real Wolf 2.01 sample-game Data.wolf:
//! extracted inner files must parse + round-trip byte-exact through wolf-formats.
//! cargo test -p wolf-formats --test ver5_archive -- --nocapture
use std::path::{Path, PathBuf};
use wolf_formats::common_event::CommonEventsFile;
use wolf_formats::map::Map;
fn find_wolf(dir: &Path) -> Option<PathBuf> {
let mut stack = vec![dir.to_path_buf()];
while let Some(d) = stack.pop() {
let Ok(rd) = std::fs::read_dir(&d) else {
continue;
};
for e in rd.flatten() {
let p = e.path();
if p.is_dir() {
stack.push(p);
} else if p.extension().and_then(|s| s.to_str()) == Some("wolf") {
return Some(p);
}
}
}
None
}
#[test]
fn ver5_ver6_archives_parse() {
// VER5 = Wolf 2.01, VER6 = Wolf 2.20.
for editor in ["WolfRPGEditor_201", "WolfRPGEditor_220"] {
let base = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..")
.join("..")
.join("ALLWOLFVERSIONS")
.join(editor);
let Some(arc) = find_wolf(&base) else {
eprintln!("{editor}: no Data.wolf, skipping");
continue;
};
let data = std::fs::read(&arc).expect("read Data.wolf");
let files = wolf_archive::extract_archive(&data, wolf_archive::DEFAULT_WOLF_PRO_KEY)
.unwrap_or_else(|e| panic!("{editor}: archive decode failed: {e}"));
eprintln!("{editor}: extracted {} files", files.len());
assert!(files.len() > 100, "{editor}: expected a populated archive");
// CommonEvent.dat was LZ-compressed: parse + round-trip proves keycode-LZSS + key decode.
let ce = files
.iter()
.find(|(p, _)| p.replace('\\', "/").ends_with("BasicData/CommonEvent.dat"))
.unwrap_or_else(|| panic!("{editor}: CommonEvent.dat not in archive"));
let parsed = CommonEventsFile::read(&ce.1)
.unwrap_or_else(|e| panic!("{editor}: parse CommonEvent: {e}"));
assert_eq!(parsed.write(), ce.1, "{editor}: CommonEvent.dat round-trip");
eprintln!(
" CommonEvent.dat: {} events, {} bytes, round-trip OK",
parsed.events.len(),
ce.1.len()
);
let mut maps = 0;
for (p, b) in &files {
if !p.to_ascii_lowercase().ends_with(".mps") {
continue;
}
let m = Map::read(b).unwrap_or_else(|e| panic!("{editor}: parse {p}: {e}"));
assert_eq!(&m.write(), b, "{editor}: map {p} round-trip");
maps += 1;
}
eprintln!(" maps round-tripped byte-exact: {maps}");
assert!(maps > 0, "{editor}: expected maps");
}
}