use super::find_orphaned_generated_files;
use std::collections::HashSet;
use std::path::{Path, PathBuf};
fn join_components(root: &Path, relative: &str) -> PathBuf {
relative
.split('/')
.fold(root.to_path_buf(), |path, part| path.join(part))
}
fn marked_java_content() -> String {
let header = crate::core::hash::header(crate::core::hash::CommentStyle::DoubleSlash);
crate::core::hash::inject_hash_line(&header, &"0".repeat(64))
}
#[test]
fn reports_a_marked_file_the_current_run_no_longer_produces() {
let dir = tempfile::tempdir().expect("tempdir");
let package_dir = join_components(dir.path(), "packages/java/dev/demo");
std::fs::create_dir_all(&package_dir).expect("package dir");
let dropped = package_dir.join("VisitorBridge.java");
std::fs::write(&dropped, marked_java_content()).expect("write dropped file");
let managed_paths: HashSet<PathBuf> = HashSet::new();
let orphans = find_orphaned_generated_files(dir.path(), &managed_paths);
assert_eq!(
orphans,
vec![dropped.display().to_string()],
"a marked file absent from the managed-path set must be reported as an orphan"
);
}
#[test]
fn does_not_report_a_marked_file_still_in_the_managed_path_set() {
let dir = tempfile::tempdir().expect("tempdir");
let package_dir = join_components(dir.path(), "packages/java/dev/demo");
std::fs::create_dir_all(&package_dir).expect("package dir");
let current = package_dir.join("Bridge.java");
std::fs::write(¤t, marked_java_content()).expect("write current file");
let managed_paths: HashSet<PathBuf> = HashSet::from([current.clone()]);
let orphans = find_orphaned_generated_files(dir.path(), &managed_paths);
assert!(
orphans.is_empty(),
"a file still in this run's managed-path set must never be reported: {orphans:?}"
);
}
#[test]
fn does_not_report_an_unmarked_user_owned_file_in_a_generated_directory() {
let dir = tempfile::tempdir().expect("tempdir");
let package_dir = join_components(dir.path(), "packages/java/dev/demo");
std::fs::create_dir_all(&package_dir).expect("package dir");
let current = package_dir.join("Bridge.java");
std::fs::write(¤t, marked_java_content()).expect("write current file");
let hand_written = package_dir.join("UserExtensions.java");
std::fs::write(&hand_written, "package dev.demo;\npublic class UserExtensions {}\n").expect("write hand file");
let managed_paths: HashSet<PathBuf> = HashSet::from([current]);
let orphans = find_orphaned_generated_files(dir.path(), &managed_paths);
assert!(
orphans.is_empty(),
"an unmarked hand-written file must never be reported as an orphan, even sitting in a \
generated directory: {orphans:?}"
);
}
#[test]
fn does_not_report_the_rust_toolchain_create_once_seed() {
let dir = tempfile::tempdir().expect("tempdir");
let header = crate::core::hash::header(crate::core::hash::CommentStyle::Hash);
let hashed = crate::core::hash::inject_hash_line(&header, &"0".repeat(64));
let seed = dir.path().join("rust-toolchain.toml");
std::fs::write(&seed, hashed).expect("write seed");
let managed_paths: HashSet<PathBuf> = HashSet::new();
let orphans = find_orphaned_generated_files(dir.path(), &managed_paths);
assert!(
orphans.is_empty(),
"rust-toolchain.toml is a documented create-once seed and must never be reported: {orphans:?}"
);
}
#[test]
fn does_not_report_a_file_owned_by_a_different_crate_once_paths_are_unioned() {
let dir = tempfile::tempdir().expect("tempdir");
let package_dir = join_components(dir.path(), "packages/java/dev/demo");
std::fs::create_dir_all(&package_dir).expect("package dir");
let owned_by_crate_b = package_dir.join("CrateBOnly.java");
std::fs::write(&owned_by_crate_b, marked_java_content()).expect("write file");
let crate_a_managed: HashSet<PathBuf> = HashSet::new();
let crate_b_managed: HashSet<PathBuf> = HashSet::from([owned_by_crate_b.clone()]);
let unioned: HashSet<PathBuf> = crate_a_managed.union(&crate_b_managed).cloned().collect();
let orphans = find_orphaned_generated_files(dir.path(), &unioned);
assert!(
orphans.is_empty(),
"a file owned by another crate in the union must not be reported: {orphans:?}"
);
}