use std::fs;
use std::path::Path;
use mlt_core::Parser;
use mlt_core::dump::{DumpTree, annotate_tile};
use test_each_file::test_each_path;
test_each_path! { for ["mlt"] in "../test/synthetic/0x01" as dump_0x01 => check }
test_each_path! { for ["mlt"] in "../test/synthetic/0x01-rust" as dump_0x01_rust => check }
test_each_path! { for ["mlt"] in "../test/synthetic/0x02" as dump_0x02 => check }
test_each_path! { for ["mlt"] in "../test/synthetic/0x02-java" as dump_0x02_java => check }
fn check([path]: [&Path; 1]) {
let buffer = fs::read(path).unwrap();
let parse_ok = Parser::default().parse_layers(&buffer).is_ok();
let tree = annotate_tile(&buffer);
match (parse_ok, tree) {
(true, Ok(tree)) => assert_full_coverage(&tree, buffer.len(), path),
(true, Err(e)) => {
panic!(
"{}: parser succeeded but annotate_tile failed: {e}",
path.display()
)
}
(false, Err(_)) => {}
(false, Ok(_)) => {
panic!(
"{}: parser failed but annotate_tile succeeded",
path.display()
)
}
}
}
fn assert_full_coverage(tree: &DumpTree, buf_len: usize, path: &Path) {
let mut leaves: Vec<(usize, usize)> = tree
.regions
.iter()
.filter(|r| !r.container)
.map(|r| (r.offset, r.len))
.collect();
leaves.sort_unstable();
assert_eq!(
tree.buf_len,
buf_len,
"{}: buf_len mismatch",
path.display()
);
assert!(!leaves.is_empty(), "{}: no leaf regions", path.display());
assert_eq!(
leaves[0].0,
0,
"{}: first leaf not at offset 0",
path.display()
);
let mut cursor = 0usize;
for (offset, len) in &leaves {
assert_eq!(
*offset,
cursor,
"{}: gap/overlap at offset {offset} (expected {cursor})",
path.display()
);
cursor += len;
}
assert_eq!(
cursor,
buf_len,
"{}: leaves end at {cursor}, expected {buf_len}",
path.display()
);
}