use crate::utils::{archive, setup};
use clap::Parser;
use portable_network_archive::cli;
use std::{collections::HashSet, fs};
#[test]
fn delete_directory_entry() {
setup();
let base = "delete_directory_entry";
if std::path::Path::new(base).exists() {
fs::remove_dir_all(base).unwrap();
}
fs::create_dir_all(format!("{base}/in/subdir")).unwrap();
fs::write(format!("{base}/in/root.txt"), b"root content").unwrap();
fs::write(format!("{base}/in/subdir/nested.txt"), b"nested content").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"-f",
&format!("{base}/archive.pna"),
"--overwrite",
"--keep-dir",
&format!("{base}/in"),
])
.unwrap()
.execute()
.unwrap();
let mut before = HashSet::new();
archive::for_each_entry(format!("{base}/archive.pna"), |entry| {
before.insert((
entry.header().path().to_string(),
entry.header().data_kind(),
));
})
.unwrap();
assert!(
before.contains(&(format!("{base}/in"), pna::DataKind::DIRECTORY)),
"archive should contain directory entry before deletion"
);
assert!(
before.contains(&(format!("{base}/in/subdir"), pna::DataKind::DIRECTORY)),
"archive should contain subdir entry before deletion"
);
cli::Cli::try_parse_from([
"pna",
"--quiet",
"delete",
"-f",
&format!("{base}/archive.pna"),
&format!("{base}/in/subdir"),
])
.unwrap()
.execute()
.unwrap();
let mut seen = HashSet::new();
archive::for_each_entry(format!("{base}/archive.pna"), |entry| {
seen.insert(entry.header().path().to_string());
})
.unwrap();
assert!(
!seen.contains(&format!("{base}/in/subdir")),
"subdir directory entry should have been deleted"
);
for required in [
format!("{base}/in"),
format!("{base}/in/root.txt"),
format!("{base}/in/subdir/nested.txt"),
] {
assert!(
seen.take(&required).is_some(),
"required entry missing: {required}"
);
}
assert!(seen.is_empty(), "unexpected entries found: {seen:?}");
}
#[test]
fn delete_directory_and_contents() {
setup();
let base = "delete_directory_and_contents";
if std::path::Path::new(base).exists() {
fs::remove_dir_all(base).unwrap();
}
fs::create_dir_all(format!("{base}/in/keep")).unwrap();
fs::create_dir_all(format!("{base}/in/remove")).unwrap();
fs::write(format!("{base}/in/keep/keep.txt"), b"keep").unwrap();
fs::write(format!("{base}/in/remove/remove.txt"), b"remove").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"-f",
&format!("{base}/archive.pna"),
"--overwrite",
"--keep-dir",
&format!("{base}/in"),
])
.unwrap()
.execute()
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"delete",
"-f",
&format!("{base}/archive.pna"),
&format!("{base}/in/remove"),
&format!("{base}/in/remove/**"),
])
.unwrap()
.execute()
.unwrap();
let mut seen = HashSet::new();
archive::for_each_entry(format!("{base}/archive.pna"), |entry| {
seen.insert(entry.header().path().to_string());
})
.unwrap();
assert!(
!seen.contains(&format!("{base}/in/remove")),
"remove directory entry should have been deleted"
);
assert!(
!seen.contains(&format!("{base}/in/remove/remove.txt")),
"remove/remove.txt should have been deleted"
);
for required in [
format!("{base}/in"),
format!("{base}/in/keep"),
format!("{base}/in/keep/keep.txt"),
] {
assert!(
seen.take(&required).is_some(),
"required entry missing: {required}"
);
}
assert!(seen.is_empty(), "unexpected entries found: {seen:?}");
}