use super::*;
use std::fs;
use tempfile::tempdir;
fn enc(path: &str) -> String {
path.replace('/', "%2F")
}
#[test]
fn delivery_root_is_the_state_roots_bl_delivery_tree() {
assert_eq!(
delivery_root(Path::new("/s/balls/clones")),
Some(PathBuf::from("/s/balls/plugins/bl-delivery")),
);
assert_eq!(delivery_root(Path::new("/")), None);
}
#[test]
fn is_internal_matches_only_under_the_delivery_tree() {
let d = PathBuf::from("/s/balls/plugins/bl-delivery");
assert!(is_internal(
Path::new("/s/balls/plugins/bl-delivery/home/u/p/bl-1"),
Some(&d),
));
assert!(!is_internal(Path::new("/home/u/p"), Some(&d)));
assert!(!is_internal(Path::new("/anything"), None));
}
#[test]
fn missing_clones_dir_enumerates_empty() {
let dir = tempdir().unwrap();
assert!(enumerate(&dir.path().join("absent")).is_empty());
}
#[test]
fn enumerate_decodes_flags_internal_and_skips_non_dirs() {
let root = tempdir().unwrap();
let clones = root.path().join("balls").join("clones");
fs::create_dir_all(&clones).unwrap();
let delivery = root.path().join("balls/plugins/bl-delivery");
fs::create_dir(clones.join(enc("/home/u/proj"))).unwrap();
let internal_path = format!("{}/home/u/proj/bl-1", delivery.display());
fs::create_dir(clones.join(enc(&internal_path))).unwrap();
fs::write(clones.join("stray-file"), b"x").unwrap();
let projects = enumerate(&clones);
assert_eq!(projects.len(), 2, "non-dir entry skipped");
let normal = projects.iter().find(|p| !p.internal).unwrap();
assert_eq!(normal.path, PathBuf::from("/home/u/proj"));
let internal = projects.iter().find(|p| p.internal).unwrap();
assert_eq!(internal.path, PathBuf::from(internal_path));
let mut sorted = projects.clone();
sorted.sort_by(|a, b| a.path.cmp(&b.path));
assert_eq!(projects, sorted);
}
#[cfg(not(target_os = "macos"))]
#[test]
fn enumerate_skips_non_utf8_basenames() {
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
let clones = tempdir().unwrap();
fs::create_dir(clones.path().join(enc("/home/u/proj"))).unwrap();
fs::create_dir(clones.path().join(OsStr::from_bytes(&[0x66, 0x80]))).unwrap();
let projects = enumerate(clones.path());
assert_eq!(projects.len(), 1, "non-UTF-8 basename skipped");
assert_eq!(projects[0].path, PathBuf::from("/home/u/proj"));
}
#[test]
fn visible_filters_internal_unless_the_toggle_is_on() {
let projects = vec![
Project {
path: PathBuf::from("/a"),
internal: false,
},
Project {
path: PathBuf::from("/b"),
internal: true,
},
];
let shown: Vec<_> = visible(&projects, false).iter().map(|p| &p.path).collect();
assert_eq!(
shown,
vec![&PathBuf::from("/a")],
"internal hidden by default"
);
assert_eq!(visible(&projects, true).len(), 2, "toggle reveals internal");
}