Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions crates/pet-homebrew/src/environment_locations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,61 @@ pub fn get_homebrew_prefix_bin(env_vars: &EnvVariables) -> Vec<PathBuf> {

homebrew_prefixes
}

#[cfg(test)]
mod tests {
use super::*;
use std::{
fs,
time::{SystemTime, UNIX_EPOCH},
};

fn create_unique_prefix(name: &str) -> PathBuf {
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
std::env::temp_dir().join(format!(
"pet-homebrew-{name}-{}-{unique}",
std::process::id()
))
}

#[test]
fn homebrew_prefix_bin_uses_existing_homebrew_prefix_env_var() {
let homebrew_prefix = create_unique_prefix("prefix");
let homebrew_bin = homebrew_prefix.join("bin");
fs::create_dir_all(&homebrew_bin).unwrap();
let env_vars = EnvVariables {
home: None,
root: None,
path: None,
homebrew_prefix: Some(homebrew_prefix.to_string_lossy().to_string()),
known_global_search_locations: vec![],
};

let prefix_bins = get_homebrew_prefix_bin(&env_vars);

assert!(prefix_bins.contains(&homebrew_bin));

fs::remove_dir_all(homebrew_prefix).unwrap();
}

#[test]
fn homebrew_prefix_bin_ignores_missing_homebrew_prefix_env_var() {
let missing_homebrew_prefix = create_unique_prefix("missing-prefix");
Comment thread
karthiknadig marked this conversation as resolved.
Outdated
let env_vars = EnvVariables {
home: None,
root: None,
path: None,
homebrew_prefix: Some(missing_homebrew_prefix.to_string_lossy().to_string()),
known_global_search_locations: vec![],
};

let prefix_bins = get_homebrew_prefix_bin(&env_vars);

assert!(!prefix_bins
.iter()
.any(|path| path == &missing_homebrew_prefix.join("bin")));
}
}
124 changes: 124 additions & 0 deletions crates/pet-homebrew/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,127 @@ impl Locator for Homebrew {
});
}
}

#[cfg(all(test, unix))]
mod tests {
use super::*;
use std::time::{SystemTime, UNIX_EPOCH};

struct TestEnvironment {
homebrew_prefix: Option<String>,
}

impl Environment for TestEnvironment {
fn get_user_home(&self) -> Option<PathBuf> {
None
}

fn get_root(&self) -> Option<PathBuf> {
None
}

fn get_env_var(&self, key: String) -> Option<String> {
if key == "HOMEBREW_PREFIX" {
self.homebrew_prefix.clone()
} else {
None
}
}

fn get_know_global_search_locations(&self) -> Vec<PathBuf> {
vec![]
}
}

fn create_test_dir(name: &str) -> PathBuf {
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let directory = std::env::temp_dir().join(format!(
"pet-homebrew-{name}-{}-{unique}",
std::process::id()
));
fs::create_dir_all(&directory).unwrap();
directory
}

#[test]
fn homebrew_locator_reports_kind_and_supported_category() {
let locator = Homebrew::from(&TestEnvironment {
homebrew_prefix: None,
});

assert_eq!(locator.get_kind(), LocatorKind::Homebrew);
assert_eq!(
locator.supported_categories(),
vec![PythonEnvironmentKind::Homebrew]
);
}

#[test]
fn try_from_identifies_linuxbrew_python_executable() {
let locator = Homebrew::from(&TestEnvironment {
homebrew_prefix: None,
});
let env = PythonEnv::new(
PathBuf::from("/home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.12.4/bin/python3.12"),
None,
None,
);

let homebrew_env = locator.try_from(&env).unwrap();

assert_eq!(homebrew_env.kind, Some(PythonEnvironmentKind::Homebrew));
assert_eq!(
homebrew_env.executable,
Some(PathBuf::from("/home/linuxbrew/.linuxbrew/bin/python3.12"))
);
assert_eq!(homebrew_env.version, Some("3.12.4".to_string()));
assert_eq!(homebrew_env.prefix, None);
assert!(homebrew_env
.symlinks
.as_ref()
.unwrap()
.contains(&PathBuf::from(
"/home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.12.4/bin/python3.12"
)));
}

#[test]
fn try_from_rejects_non_homebrew_python() {
let locator = Homebrew::from(&TestEnvironment {
homebrew_prefix: None,
});
let env = PythonEnv::new(PathBuf::from("/usr/bin/python3.12"), None, None);

assert!(locator.try_from(&env).is_none());
}

#[test]
fn try_from_rejects_virtualenv_and_conda_prefixes() {
let locator = Homebrew::from(&TestEnvironment {
homebrew_prefix: None,
});

let venv_root = create_test_dir("venv-reject");
let venv_bin = venv_root.join("bin");
fs::create_dir_all(&venv_bin).unwrap();
fs::write(venv_bin.join("activate"), b"").unwrap();
let venv_executable = venv_bin.join("python3.12");
fs::write(&venv_executable, b"").unwrap();
let venv = PythonEnv::new(venv_executable, Some(venv_root.clone()), None);
assert!(locator.try_from(&venv).is_none());

let conda_root = create_test_dir("conda-reject");
fs::create_dir_all(conda_root.join("conda-meta")).unwrap();
let conda_executable = conda_root.join("bin").join("python3.12");
fs::create_dir_all(conda_executable.parent().unwrap()).unwrap();
fs::write(&conda_executable, b"").unwrap();
let conda = PythonEnv::new(conda_executable, Some(conda_root.clone()), None);
assert!(locator.try_from(&conda).is_none());

fs::remove_dir_all(venv_root).unwrap();
fs::remove_dir_all(conda_root).unwrap();
Comment thread
karthiknadig marked this conversation as resolved.
Outdated
}
}
36 changes: 36 additions & 0 deletions crates/pet-homebrew/src/sym_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,39 @@ pub fn get_known_symlinks_impl(
vec![]
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn homebrew_python_paths_are_recognized_across_supported_prefixes() {
assert!(is_homebrew_python(Path::new(
"/opt/homebrew/Cellar/[email protected]/3.12.4/bin/python3.12"
)));
assert!(is_homebrew_python(Path::new(
"/usr/local/Cellar/[email protected]/3.11.9/bin/python3.11"
)));
assert!(is_homebrew_python(Path::new(
"/home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.12.4/bin/python3.12"
)));
assert!(!is_homebrew_python(Path::new("/usr/bin/python3.12")));
}

#[test]
fn known_symlink_templates_include_expected_paths_for_linuxbrew() {
let resolved_exe =
PathBuf::from("/home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.12.4/bin/python3.12");
let symlinks = get_known_symlinks_impl(&resolved_exe, &"3.12.4".to_string());

assert!(symlinks.contains(&resolved_exe));
}
Comment thread
karthiknadig marked this conversation as resolved.
Outdated

#[test]
fn known_symlink_templates_return_empty_for_unrecognized_paths() {
assert!(
get_known_symlinks_impl(Path::new("/usr/bin/python3.12"), &"3.12.4".to_string())
.is_empty()
);
}
}
Loading