@@ -170,3 +170,127 @@ impl Locator for Homebrew {
170170 } ) ;
171171 }
172172}
173+
174+ #[ cfg( all( test, unix) ) ]
175+ mod tests {
176+ use super :: * ;
177+ use std:: time:: { SystemTime , UNIX_EPOCH } ;
178+
179+ struct TestEnvironment {
180+ homebrew_prefix : Option < String > ,
181+ }
182+
183+ impl Environment for TestEnvironment {
184+ fn get_user_home ( & self ) -> Option < PathBuf > {
185+ None
186+ }
187+
188+ fn get_root ( & self ) -> Option < PathBuf > {
189+ None
190+ }
191+
192+ fn get_env_var ( & self , key : String ) -> Option < String > {
193+ if key == "HOMEBREW_PREFIX" {
194+ self . homebrew_prefix . clone ( )
195+ } else {
196+ None
197+ }
198+ }
199+
200+ fn get_know_global_search_locations ( & self ) -> Vec < PathBuf > {
201+ vec ! [ ]
202+ }
203+ }
204+
205+ fn create_test_dir ( name : & str ) -> PathBuf {
206+ let unique = SystemTime :: now ( )
207+ . duration_since ( UNIX_EPOCH )
208+ . unwrap ( )
209+ . as_nanos ( ) ;
210+ let directory = std:: env:: temp_dir ( ) . join ( format ! (
211+ "pet-homebrew-{name}-{}-{unique}" ,
212+ std:: process:: id( )
213+ ) ) ;
214+ fs:: create_dir_all ( & directory) . unwrap ( ) ;
215+ directory
216+ }
217+
218+ #[ test]
219+ fn homebrew_locator_reports_kind_and_supported_category ( ) {
220+ let locator = Homebrew :: from ( & TestEnvironment {
221+ homebrew_prefix : None ,
222+ } ) ;
223+
224+ assert_eq ! ( locator. get_kind( ) , LocatorKind :: Homebrew ) ;
225+ assert_eq ! (
226+ locator. supported_categories( ) ,
227+ vec![ PythonEnvironmentKind :: Homebrew ]
228+ ) ;
229+ }
230+
231+ #[ test]
232+ fn try_from_identifies_linuxbrew_python_executable ( ) {
233+ let locator = Homebrew :: from ( & TestEnvironment {
234+ homebrew_prefix : None ,
235+ } ) ;
236+ let env = PythonEnv :: new (
237+ PathBuf :: from ( "/home/linuxbrew/.linuxbrew/Cellar/python@3.12/3.12.4/bin/python3.12" ) ,
238+ None ,
239+ None ,
240+ ) ;
241+
242+ let homebrew_env = locator. try_from ( & env) . unwrap ( ) ;
243+
244+ assert_eq ! ( homebrew_env. kind, Some ( PythonEnvironmentKind :: Homebrew ) ) ;
245+ assert_eq ! (
246+ homebrew_env. executable,
247+ Some ( PathBuf :: from( "/home/linuxbrew/.linuxbrew/bin/python3.12" ) )
248+ ) ;
249+ assert_eq ! ( homebrew_env. version, Some ( "3.12.4" . to_string( ) ) ) ;
250+ assert_eq ! ( homebrew_env. prefix, None ) ;
251+ assert ! ( homebrew_env
252+ . symlinks
253+ . as_ref( )
254+ . unwrap( )
255+ . contains( & PathBuf :: from(
256+ "/home/linuxbrew/.linuxbrew/Cellar/python@3.12/3.12.4/bin/python3.12"
257+ ) ) ) ;
258+ }
259+
260+ #[ test]
261+ fn try_from_rejects_non_homebrew_python ( ) {
262+ let locator = Homebrew :: from ( & TestEnvironment {
263+ homebrew_prefix : None ,
264+ } ) ;
265+ let env = PythonEnv :: new ( PathBuf :: from ( "/usr/bin/python3.12" ) , None , None ) ;
266+
267+ assert ! ( locator. try_from( & env) . is_none( ) ) ;
268+ }
269+
270+ #[ test]
271+ fn try_from_rejects_virtualenv_and_conda_prefixes ( ) {
272+ let locator = Homebrew :: from ( & TestEnvironment {
273+ homebrew_prefix : None ,
274+ } ) ;
275+
276+ let venv_root = create_test_dir ( "venv-reject" ) ;
277+ let venv_bin = venv_root. join ( "bin" ) ;
278+ fs:: create_dir_all ( & venv_bin) . unwrap ( ) ;
279+ fs:: write ( venv_bin. join ( "activate" ) , b"" ) . unwrap ( ) ;
280+ let venv_executable = venv_bin. join ( "python3.12" ) ;
281+ fs:: write ( & venv_executable, b"" ) . unwrap ( ) ;
282+ let venv = PythonEnv :: new ( venv_executable, Some ( venv_root. clone ( ) ) , None ) ;
283+ assert ! ( locator. try_from( & venv) . is_none( ) ) ;
284+
285+ let conda_root = create_test_dir ( "conda-reject" ) ;
286+ fs:: create_dir_all ( conda_root. join ( "conda-meta" ) ) . unwrap ( ) ;
287+ let conda_executable = conda_root. join ( "bin" ) . join ( "python3.12" ) ;
288+ fs:: create_dir_all ( conda_executable. parent ( ) . unwrap ( ) ) . unwrap ( ) ;
289+ fs:: write ( & conda_executable, b"" ) . unwrap ( ) ;
290+ let conda = PythonEnv :: new ( conda_executable, Some ( conda_root. clone ( ) ) , None ) ;
291+ assert ! ( locator. try_from( & conda) . is_none( ) ) ;
292+
293+ fs:: remove_dir_all ( venv_root) . unwrap ( ) ;
294+ fs:: remove_dir_all ( conda_root) . unwrap ( ) ;
295+ }
296+ }
0 commit comments