use std::path::Path;
fn fixtures_dir() -> &'static Path {
Path::new("tests/fixtures")
}
#[test]
fn test_verify_intact() {
let dir = fixtures_dir().join("intact");
let par2_path = dir.join("testdata.bin.par2");
let file_set = rust_par2::parse(&par2_path).expect("Failed to parse par2");
let result = rust_par2::verify(&file_set, &dir);
assert!(
result.all_correct(),
"Intact set should verify as all correct: {result}"
);
assert_eq!(result.intact.len(), 1);
assert!(result.damaged.is_empty());
assert!(result.missing.is_empty());
}
#[test]
fn test_verify_damaged() {
let dir = fixtures_dir().join("damaged");
let par2_path = dir.join("testdata.bin.par2");
let file_set = rust_par2::parse(&par2_path).expect("Failed to parse par2");
let result = rust_par2::verify(&file_set, &dir);
assert!(
!result.all_correct(),
"Damaged set should not verify as correct"
);
assert_eq!(result.damaged.len(), 1, "Should have 1 damaged file");
assert!(result.damaged[0].damaged_block_count > 0);
}
#[test]
fn test_verify_missing() {
let dir = fixtures_dir().join("missing");
let par2_path = dir.join("testdata.bin.par2");
let file_set = rust_par2::parse(&par2_path).expect("Failed to parse par2");
let result = rust_par2::verify(&file_set, &dir);
assert!(
!result.all_correct(),
"Missing set should not verify as correct"
);
assert_eq!(result.missing.len(), 1, "Should have 1 missing file");
}
#[test]
fn test_repair_damaged() {
let tmp = tempfile::tempdir().unwrap();
copy_dir(fixtures_dir().join("damaged"), tmp.path());
let par2_path = tmp.path().join("testdata.bin.par2");
let file_set = rust_par2::parse(&par2_path).expect("Failed to parse par2");
let pre = rust_par2::verify(&file_set, tmp.path());
assert!(!pre.all_correct(), "Should detect damage before repair");
assert!(
pre.repair_possible,
"Repair should be possible (enough recovery blocks)"
);
let result = rust_par2::repair(&file_set, tmp.path()).expect("Repair should succeed");
assert!(
result.success,
"Repair result should indicate success: {result}"
);
assert!(
result.blocks_repaired > 0,
"Should have repaired at least 1 block"
);
let post = rust_par2::verify(&file_set, tmp.path());
assert!(
post.all_correct(),
"All files should be correct after repair: {post}"
);
}
#[test]
fn test_repair_missing() {
let tmp = tempfile::tempdir().unwrap();
copy_dir(fixtures_dir().join("missing"), tmp.path());
let par2_path = tmp.path().join("testdata.bin.par2");
let file_set = rust_par2::parse(&par2_path).expect("Failed to parse par2");
let pre = rust_par2::verify(&file_set, tmp.path());
assert!(!pre.all_correct());
assert_eq!(pre.missing.len(), 1);
assert!(
pre.repair_possible,
"Should be repairable with 2 recovery blocks"
);
let result = rust_par2::repair(&file_set, tmp.path()).expect("Repair should succeed");
assert!(result.success, "Repair should succeed: {result}");
let post = rust_par2::verify(&file_set, tmp.path());
assert!(
post.all_correct(),
"All files should be correct after repair: {post}"
);
}
#[test]
fn test_repair_unrepairable() {
let tmp = tempfile::tempdir().unwrap();
copy_dir(fixtures_dir().join("unrepairable"), tmp.path());
let par2_path = tmp.path().join("testdata.bin.par2");
let file_set = rust_par2::parse(&par2_path).expect("Failed to parse par2");
let pre = rust_par2::verify(&file_set, tmp.path());
assert!(!pre.all_correct());
assert!(!pre.repair_possible, "Should not be repairable");
let result = rust_par2::repair(&file_set, tmp.path());
assert!(result.is_err(), "Repair should fail");
let err = result.unwrap_err();
assert!(
matches!(err, rust_par2::RepairError::InsufficientRecovery { .. }),
"Should be InsufficientRecovery error, got: {err}"
);
}
fn copy_dir(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
let src = src.as_ref();
let dst = dst.as_ref();
std::fs::create_dir_all(dst).unwrap();
for entry in std::fs::read_dir(src).unwrap() {
let entry = entry.unwrap();
if entry.file_type().unwrap().is_file() {
std::fs::copy(entry.path(), dst.join(entry.file_name())).unwrap();
}
}
}