use std::io::Cursor;
use zipatch_rs::test_utils::{MAGIC, make_chunk};
use zipatch_rs::{ApplyConfig, ApplyError, ParseError, ZiPatchReader};
#[test]
fn apply_to_applies_adir_chunk_to_filesystem() {
let mut adir_body = Vec::new();
adir_body.extend_from_slice(&7u32.to_be_bytes());
adir_body.extend_from_slice(b"created");
let mut patch = Vec::new();
patch.extend_from_slice(&MAGIC);
patch.extend_from_slice(&make_chunk(b"ADIR", &adir_body));
patch.extend_from_slice(&make_chunk(b"EOF_", &[]));
let tmp = tempfile::tempdir().unwrap();
let ctx = ApplyConfig::new(tmp.path());
let reader = ZiPatchReader::new(Cursor::new(patch)).unwrap();
ctx.apply_patch(reader).unwrap();
assert!(
tmp.path().join("created").is_dir(),
"ADIR must have created the directory"
);
}
#[test]
fn apply_to_empty_patch_succeeds_without_side_effects() {
let mut patch = Vec::new();
patch.extend_from_slice(&MAGIC);
patch.extend_from_slice(&make_chunk(b"EOF_", &[]));
let tmp = tempfile::tempdir().unwrap();
let ctx = ApplyConfig::new(tmp.path());
let reader = ZiPatchReader::new(Cursor::new(patch)).unwrap();
ctx.apply_patch(reader).unwrap();
let entries: Vec<_> = std::fs::read_dir(tmp.path()).unwrap().collect();
assert!(
entries.is_empty(),
"empty patch must not create any files/dirs"
);
}
#[test]
fn apply_to_propagates_parse_error_as_unknown_chunk_tag() {
let mut patch = Vec::new();
patch.extend_from_slice(&MAGIC);
patch.extend_from_slice(&make_chunk(b"ZZZZ", &[]));
let tmp = tempfile::tempdir().unwrap();
let ctx = ApplyConfig::new(tmp.path());
let reader = ZiPatchReader::new(Cursor::new(patch)).unwrap();
let err = ctx.apply_patch(reader).unwrap_err();
assert!(
matches!(err, ApplyError::Parse(ParseError::UnknownChunkTag(_))),
"expected UnknownChunkTag, got {err:?}"
);
}
#[test]
fn apply_to_propagates_apply_error_from_delete_directory() {
let mut deld_body = Vec::new();
deld_body.extend_from_slice(&14u32.to_be_bytes());
deld_body.extend_from_slice(b"does_not_exist");
let mut patch = Vec::new();
patch.extend_from_slice(&MAGIC);
patch.extend_from_slice(&make_chunk(b"DELD", &deld_body));
patch.extend_from_slice(&make_chunk(b"EOF_", &[]));
let tmp = tempfile::tempdir().unwrap();
let ctx = ApplyConfig::new(tmp.path());
let reader = ZiPatchReader::new(Cursor::new(patch)).unwrap();
let err = ctx.apply_patch(reader).unwrap_err();
assert!(
matches!(err, ApplyError::Io { .. }),
"expected ApplyError::Io for missing dir without ignore_missing, got {err:?}"
);
}
#[test]
fn default_no_observer_apply_succeeds_as_before() {
let mut adir_body = Vec::new();
adir_body.extend_from_slice(&7u32.to_be_bytes());
adir_body.extend_from_slice(b"created");
let mut patch = Vec::new();
patch.extend_from_slice(&MAGIC);
patch.extend_from_slice(&make_chunk(b"ADIR", &adir_body));
patch.extend_from_slice(&make_chunk(b"EOF_", &[]));
let tmp = tempfile::tempdir().unwrap();
let ctx = ApplyConfig::new(tmp.path()); let reader = ZiPatchReader::new(Cursor::new(patch)).unwrap();
ctx.apply_patch(reader).unwrap();
assert!(
tmp.path().join("created").is_dir(),
"ADIR must be applied when no observer is set"
);
}