use std::ffi::OsString;
use tempfile::tempdir;
use super::*;
#[test]
fn offline_reads_huggingface_hub_s_true_values() {
for value in ["1", "on", "Yes", "TRUE"] {
assert!(offline(Some(value)), "{value}");
}
for value in [None, Some(""), Some("0"), Some("false"), Some("2")] {
assert!(!offline(value), "{value:?}");
}
}
fn root_with(vars: &[(&str, &str)]) -> PathBuf {
let var = |name: &str| {
let found = vars.iter().find(|(key, _)| *key == name);
found.map(|(_, value)| OsString::from(value))
};
root::resolve(var, Some(Path::new("/home/u")))
}
#[test]
fn the_root_takes_the_first_variable_in_huggingface_hub_s_order() {
let all = [
("HF_HUB_CACHE", "/hub"),
("HUGGINGFACE_HUB_CACHE", "/legacy/hub"),
("HF_HOME", "/hf"),
("XDG_CACHE_HOME", "/xdg"),
];
for (skip, expected) in [
(0, "/hub"),
(1, "/legacy/hub"),
(2, "/hf/hub"),
(3, "/xdg/huggingface/hub"),
(4, "/home/u/.cache/huggingface/hub"),
] {
assert_eq!(root_with(&all[skip..]), PathBuf::from(expected), "{skip}");
}
}
#[test]
fn a_tilde_becomes_the_home_directory_in_every_variable() {
for name in ["HF_HUB_CACHE", "HUGGINGFACE_HUB_CACHE"] {
assert_eq!(root_with(&[(name, "~/c")]), PathBuf::from("/home/u/c"));
assert_eq!(root_with(&[(name, "~")]), PathBuf::from("/home/u"));
}
assert_eq!(
root_with(&[("HF_HOME", "~/hfhome")]),
PathBuf::from("/home/u/hfhome/hub")
);
let xdg = root_with(&[("XDG_CACHE_HOME", "~/xdg")]);
assert_eq!(xdg, PathBuf::from("/home/u/xdg/huggingface/hub"));
assert_eq!(
root_with(&[("HF_HOME", "~user/h")]),
PathBuf::from("~user/h/hub")
);
assert_eq!(root_with(&[("HF_HOME", "a~/h")]), PathBuf::from("a~/h/hub"));
let at_root = |name: &str| (name == "HF_HUB_CACHE").then(|| OsString::from("~"));
assert_eq!(
root::resolve(at_root, Some(Path::new("/"))),
PathBuf::from("/")
);
}
#[test]
fn a_variable_in_a_value_is_expanded_and_an_unset_one_stays() {
let home = ("HOME", "/Users/u");
let expect = |value: &str, root: &str| {
let found = root_with(&[home, ("HF_HUB_CACHE", value), ("A_1", "/a")]);
assert_eq!(found, PathBuf::from(root), "{value}");
};
expect("$HOME/hubcache", "/Users/u/hubcache");
expect("${HOME}/hubcache", "/Users/u/hubcache");
expect("$A_1/x$A_1", "/a/x/a");
expect("$NOPE/x", "$NOPE/x");
expect("${NOPE}/x", "${NOPE}/x");
expect("$/x/${}/y/${HOME", "$/x/${}/y/${HOME");
expect("$HOMEdir", "$HOMEdir");
}
#[test]
fn the_default_path_is_expanded_twice_and_a_value_put_in_is_not_expanded_again() {
let vars = [("A", "$B"), ("B", "/b")];
let home = |value| root_with(&[vars[0], vars[1], ("HF_HOME", value)]);
assert_eq!(home("$A"), PathBuf::from("/b/hub"));
let legacy = root_with(&[vars[0], vars[1], ("HUGGINGFACE_HUB_CACHE", "$A")]);
assert_eq!(legacy, PathBuf::from("$B"));
}
#[test]
fn repo_dir_name_replaces_slash() {
assert_eq!(
repo_dir_name("BAAI/bge-small-en-v1.5"),
"models--BAAI--bge-small-en-v1.5"
);
}
fn fake_repo(cache: &Path, repo_id: &str, hash: &str) -> PathBuf {
let repo = cache.join(repo_dir_name(repo_id));
fs::create_dir_all(repo.join("refs")).unwrap();
fs::write(repo.join("refs").join("main"), format!("{hash}\n")).unwrap();
let snapshot = repo.join("snapshots").join(hash);
fs::create_dir_all(&snapshot).unwrap();
snapshot
}
#[test]
fn resolves_main_through_refs() {
let cache = tempdir().unwrap();
let snapshot = fake_repo(cache.path(), "org/model", "abc123");
assert_eq!(
snapshot_dir(cache.path(), "org/model", "main"),
Some(snapshot)
);
}
#[test]
fn a_bare_hash_resolves_with_no_ref_as_another_tool_leaves_it() {
let cache = tempdir().unwrap();
let repo = cache.path().join(repo_dir_name("org/model"));
let snapshot = repo.join("snapshots").join("abc123");
fs::create_dir_all(&snapshot).unwrap();
assert_eq!(
snapshot_dir(cache.path(), "org/model", "abc123"),
Some(snapshot)
);
}
#[test]
fn a_snapshot_marked_in_progress_does_not_resolve_by_commit_or_by_branch() {
let cache = tempdir().unwrap();
let snapshot = fake_repo(cache.path(), "org/model", "abc123");
let marker = in_progress_marker(cache.path(), "org/model", "abc123");
assert!(marker.starts_with(cache.path().join(".candding")));
fs::create_dir_all(marker.parent().unwrap()).unwrap();
fs::write(&marker, "").unwrap();
assert_eq!(snapshot_dir(cache.path(), "org/model", "abc123"), None);
assert_eq!(snapshot_dir(cache.path(), "org/model", "main"), None);
fs::remove_file(&marker).unwrap();
let found = snapshot_dir(cache.path(), "org/model", "abc123");
assert_eq!(found, Some(snapshot));
}
#[test]
fn missing_repo_is_none() {
let cache = tempdir().unwrap();
assert_eq!(snapshot_dir(cache.path(), "org/missing", "main"), None);
}