use super::*;
use crate::command_test_support::{fixture, remove};
#[test]
fn a_copy_holds_every_nested_file_and_shares_nothing() {
let directory = fixture("cases-copy");
let source = directory.join("source");
std::fs::create_dir_all(source.join("inner/deeper")).expect("source directories");
std::fs::write(source.join("top.txt"), b"top").expect("top file");
std::fs::write(source.join("inner/deeper/leaf.txt"), b"leaf").expect("leaf file");
let copy = directory.join("copy");
copy_tree(source.as_path(), copy.as_path());
assert_eq!(std::fs::read(copy.join("top.txt")).expect("copied top"), b"top");
assert_eq!(std::fs::read(copy.join("inner/deeper/leaf.txt")).expect("copied leaf"), b"leaf");
std::fs::write(copy.join("top.txt"), b"changed").expect("change the copy");
assert_eq!(std::fs::read(source.join("top.txt")).expect("source top"), b"top");
remove(directory.as_path());
}
#[cfg(unix)]
#[test]
fn a_link_in_the_source_is_refused() {
let directory = fixture("cases-link");
let source = directory.join("source");
std::fs::create_dir_all(&source).expect("source directory");
std::os::unix::fs::symlink("elsewhere", source.join("link")).expect("link");
let outcome = std::panic::catch_unwind(|| copy_tree(source.as_path(), directory.join("copy").as_path()));
assert!(outcome.is_err());
remove(directory.as_path());
}
#[test]
fn every_item_is_handled_exactly_once() {
for count in [0, 1, WORKER_CAP, WORKER_CAP * 3 + 1] {
let items: Vec<usize> = (0..count).collect();
let results: Vec<Vec<usize>> = across_workers(
&items,
|_| return Vec::new(),
|item, seen| {
seen.push(*item);
},
);
let mut handled: Vec<usize> = results.into_iter().flatten().collect();
handled.sort_unstable();
assert_eq!(handled, items, "{count} items");
}
}
#[test]
fn each_worker_gets_its_own_result() {
let items: Vec<usize> = (0..WORKER_CAP * 2).collect();
let results: Vec<usize> = across_workers(&items, |number| { return number; }, |_, _| {});
let mut numbers: Vec<usize> = results.clone();
numbers.sort_unstable();
numbers.dedup();
assert_eq!(numbers.len(), results.len());
}
#[test]
fn a_panic_in_a_worker_reaches_the_caller() {
let items: Vec<usize> = vec![1];
let outcome = std::panic::catch_unwind(|| {
return across_workers(&items, |_| (), |_, _| panic!("the case failed"));
});
let payload = outcome.expect_err("the panic resumes on the caller");
assert_eq!(payload.downcast_ref::<&str>().copied(), Some("the case failed"));
}