1b3ba51a1Sopenharmony_ciextern crate which; 2b3ba51a1Sopenharmony_ci 3b3ba51a1Sopenharmony_ci#[cfg(all(unix, feature = "regex"))] 4b3ba51a1Sopenharmony_ciuse regex::Regex; 5b3ba51a1Sopenharmony_ciuse std::ffi::{OsStr, OsString}; 6b3ba51a1Sopenharmony_ciuse std::fs; 7b3ba51a1Sopenharmony_ciuse std::io; 8b3ba51a1Sopenharmony_ciuse std::path::{Path, PathBuf}; 9b3ba51a1Sopenharmony_ciuse std::{env, vec}; 10b3ba51a1Sopenharmony_ciuse tempfile::TempDir; 11b3ba51a1Sopenharmony_ci 12b3ba51a1Sopenharmony_cistruct TestFixture { 13b3ba51a1Sopenharmony_ci /// Temp directory. 14b3ba51a1Sopenharmony_ci pub tempdir: TempDir, 15b3ba51a1Sopenharmony_ci /// $PATH 16b3ba51a1Sopenharmony_ci pub paths: OsString, 17b3ba51a1Sopenharmony_ci /// Binaries created in $PATH 18b3ba51a1Sopenharmony_ci pub bins: Vec<PathBuf>, 19b3ba51a1Sopenharmony_ci} 20b3ba51a1Sopenharmony_ci 21b3ba51a1Sopenharmony_ciconst SUBDIRS: &[&str] = &["a", "b", "c"]; 22b3ba51a1Sopenharmony_ciconst BIN_NAME: &str = "bin"; 23b3ba51a1Sopenharmony_ci 24b3ba51a1Sopenharmony_ci#[cfg(unix)] 25b3ba51a1Sopenharmony_cifn mk_bin(dir: &Path, path: &str, extension: &str) -> io::Result<PathBuf> { 26b3ba51a1Sopenharmony_ci use std::os::unix::fs::OpenOptionsExt; 27b3ba51a1Sopenharmony_ci let bin = dir.join(path).with_extension(extension); 28b3ba51a1Sopenharmony_ci fs::OpenOptions::new() 29b3ba51a1Sopenharmony_ci .write(true) 30b3ba51a1Sopenharmony_ci .create(true) 31b3ba51a1Sopenharmony_ci .mode(0o666 | (libc::S_IXUSR as u32)) 32b3ba51a1Sopenharmony_ci .open(&bin) 33b3ba51a1Sopenharmony_ci .and_then(|_f| bin.canonicalize()) 34b3ba51a1Sopenharmony_ci} 35b3ba51a1Sopenharmony_ci 36b3ba51a1Sopenharmony_cifn touch(dir: &Path, path: &str, extension: &str) -> io::Result<PathBuf> { 37b3ba51a1Sopenharmony_ci let b = dir.join(path).with_extension(extension); 38b3ba51a1Sopenharmony_ci fs::File::create(&b).and_then(|_f| b.canonicalize()) 39b3ba51a1Sopenharmony_ci} 40b3ba51a1Sopenharmony_ci 41b3ba51a1Sopenharmony_ci#[cfg(windows)] 42b3ba51a1Sopenharmony_cifn mk_bin(dir: &Path, path: &str, extension: &str) -> io::Result<PathBuf> { 43b3ba51a1Sopenharmony_ci touch(dir, path, extension) 44b3ba51a1Sopenharmony_ci} 45b3ba51a1Sopenharmony_ci 46b3ba51a1Sopenharmony_ciimpl TestFixture { 47b3ba51a1Sopenharmony_ci // tmp/a/bin 48b3ba51a1Sopenharmony_ci // tmp/a/bin.exe 49b3ba51a1Sopenharmony_ci // tmp/a/bin.cmd 50b3ba51a1Sopenharmony_ci // tmp/b/bin 51b3ba51a1Sopenharmony_ci // tmp/b/bin.exe 52b3ba51a1Sopenharmony_ci // tmp/b/bin.cmd 53b3ba51a1Sopenharmony_ci // tmp/c/bin 54b3ba51a1Sopenharmony_ci // tmp/c/bin.exe 55b3ba51a1Sopenharmony_ci // tmp/c/bin.cmd 56b3ba51a1Sopenharmony_ci pub fn new() -> TestFixture { 57b3ba51a1Sopenharmony_ci let tempdir = tempfile::tempdir().unwrap(); 58b3ba51a1Sopenharmony_ci let mut builder = fs::DirBuilder::new(); 59b3ba51a1Sopenharmony_ci builder.recursive(true); 60b3ba51a1Sopenharmony_ci let mut paths = vec![]; 61b3ba51a1Sopenharmony_ci let mut bins = vec![]; 62b3ba51a1Sopenharmony_ci for d in SUBDIRS.iter() { 63b3ba51a1Sopenharmony_ci let p = tempdir.path().join(d); 64b3ba51a1Sopenharmony_ci builder.create(&p).unwrap(); 65b3ba51a1Sopenharmony_ci bins.push(mk_bin(&p, BIN_NAME, "").unwrap()); 66b3ba51a1Sopenharmony_ci bins.push(mk_bin(&p, BIN_NAME, "exe").unwrap()); 67b3ba51a1Sopenharmony_ci bins.push(mk_bin(&p, BIN_NAME, "cmd").unwrap()); 68b3ba51a1Sopenharmony_ci paths.push(p); 69b3ba51a1Sopenharmony_ci } 70b3ba51a1Sopenharmony_ci let p = tempdir.path().join("win-bin"); 71b3ba51a1Sopenharmony_ci builder.create(&p).unwrap(); 72b3ba51a1Sopenharmony_ci bins.push(mk_bin(&p, "win-bin", "exe").unwrap()); 73b3ba51a1Sopenharmony_ci paths.push(p); 74b3ba51a1Sopenharmony_ci TestFixture { 75b3ba51a1Sopenharmony_ci tempdir, 76b3ba51a1Sopenharmony_ci paths: env::join_paths(paths).unwrap(), 77b3ba51a1Sopenharmony_ci bins, 78b3ba51a1Sopenharmony_ci } 79b3ba51a1Sopenharmony_ci } 80b3ba51a1Sopenharmony_ci 81b3ba51a1Sopenharmony_ci #[allow(dead_code)] 82b3ba51a1Sopenharmony_ci pub fn touch(&self, path: &str, extension: &str) -> io::Result<PathBuf> { 83b3ba51a1Sopenharmony_ci touch(self.tempdir.path(), path, extension) 84b3ba51a1Sopenharmony_ci } 85b3ba51a1Sopenharmony_ci 86b3ba51a1Sopenharmony_ci pub fn mk_bin(&self, path: &str, extension: &str) -> io::Result<PathBuf> { 87b3ba51a1Sopenharmony_ci mk_bin(self.tempdir.path(), path, extension) 88b3ba51a1Sopenharmony_ci } 89b3ba51a1Sopenharmony_ci} 90b3ba51a1Sopenharmony_ci 91b3ba51a1Sopenharmony_cifn _which<T: AsRef<OsStr>>(f: &TestFixture, path: T) -> which::Result<which::CanonicalPath> { 92b3ba51a1Sopenharmony_ci which::CanonicalPath::new_in(path, Some(f.paths.clone()), f.tempdir.path()) 93b3ba51a1Sopenharmony_ci} 94b3ba51a1Sopenharmony_ci 95b3ba51a1Sopenharmony_cifn _which_all<'a, T: AsRef<OsStr> + 'a>( 96b3ba51a1Sopenharmony_ci f: &'a TestFixture, 97b3ba51a1Sopenharmony_ci path: T, 98b3ba51a1Sopenharmony_ci) -> which::Result<impl Iterator<Item = which::Result<which::CanonicalPath>> + '_> { 99b3ba51a1Sopenharmony_ci which::CanonicalPath::all_in(path, Some(f.paths.clone()), f.tempdir.path()) 100b3ba51a1Sopenharmony_ci} 101b3ba51a1Sopenharmony_ci 102b3ba51a1Sopenharmony_ci#[test] 103b3ba51a1Sopenharmony_ci#[cfg(unix)] 104b3ba51a1Sopenharmony_cifn it_works() { 105b3ba51a1Sopenharmony_ci use std::process::Command; 106b3ba51a1Sopenharmony_ci let result = which::Path::new("rustc"); 107b3ba51a1Sopenharmony_ci assert!(result.is_ok()); 108b3ba51a1Sopenharmony_ci 109b3ba51a1Sopenharmony_ci let which_result = Command::new("which").arg("rustc").output(); 110b3ba51a1Sopenharmony_ci 111b3ba51a1Sopenharmony_ci assert_eq!( 112b3ba51a1Sopenharmony_ci String::from(result.unwrap().to_str().unwrap()), 113b3ba51a1Sopenharmony_ci String::from_utf8(which_result.unwrap().stdout) 114b3ba51a1Sopenharmony_ci .unwrap() 115b3ba51a1Sopenharmony_ci .trim() 116b3ba51a1Sopenharmony_ci ); 117b3ba51a1Sopenharmony_ci} 118b3ba51a1Sopenharmony_ci 119b3ba51a1Sopenharmony_ci#[test] 120b3ba51a1Sopenharmony_ci#[cfg(unix)] 121b3ba51a1Sopenharmony_cifn test_which() { 122b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 123b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &BIN_NAME).unwrap(), f.bins[0]) 124b3ba51a1Sopenharmony_ci} 125b3ba51a1Sopenharmony_ci 126b3ba51a1Sopenharmony_ci#[test] 127b3ba51a1Sopenharmony_ci#[cfg(windows)] 128b3ba51a1Sopenharmony_cifn test_which() { 129b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 130b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &BIN_NAME).unwrap(), f.bins[1]) 131b3ba51a1Sopenharmony_ci} 132b3ba51a1Sopenharmony_ci 133b3ba51a1Sopenharmony_ci#[test] 134b3ba51a1Sopenharmony_ci#[cfg(all(unix, feature = "regex"))] 135b3ba51a1Sopenharmony_cifn test_which_re_in_with_matches() { 136b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 137b3ba51a1Sopenharmony_ci f.mk_bin("a/bin_0", "").unwrap(); 138b3ba51a1Sopenharmony_ci f.mk_bin("b/bin_1", "").unwrap(); 139b3ba51a1Sopenharmony_ci let re = Regex::new(r"bin_\d").unwrap(); 140b3ba51a1Sopenharmony_ci 141b3ba51a1Sopenharmony_ci let result: Vec<PathBuf> = which::which_re_in(re, Some(f.paths)) 142b3ba51a1Sopenharmony_ci .unwrap() 143b3ba51a1Sopenharmony_ci .into_iter() 144b3ba51a1Sopenharmony_ci .collect(); 145b3ba51a1Sopenharmony_ci 146b3ba51a1Sopenharmony_ci let temp = f.tempdir; 147b3ba51a1Sopenharmony_ci 148b3ba51a1Sopenharmony_ci assert_eq!( 149b3ba51a1Sopenharmony_ci result, 150b3ba51a1Sopenharmony_ci vec![temp.path().join("a/bin_0"), temp.path().join("b/bin_1")] 151b3ba51a1Sopenharmony_ci ) 152b3ba51a1Sopenharmony_ci} 153b3ba51a1Sopenharmony_ci 154b3ba51a1Sopenharmony_ci#[test] 155b3ba51a1Sopenharmony_ci#[cfg(all(unix, feature = "regex"))] 156b3ba51a1Sopenharmony_cifn test_which_re_in_without_matches() { 157b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 158b3ba51a1Sopenharmony_ci let re = Regex::new(r"bi[^n]").unwrap(); 159b3ba51a1Sopenharmony_ci 160b3ba51a1Sopenharmony_ci let result: Vec<PathBuf> = which::which_re_in(re, Some(f.paths)) 161b3ba51a1Sopenharmony_ci .unwrap() 162b3ba51a1Sopenharmony_ci .into_iter() 163b3ba51a1Sopenharmony_ci .collect(); 164b3ba51a1Sopenharmony_ci 165b3ba51a1Sopenharmony_ci assert_eq!(result, Vec::<PathBuf>::new()) 166b3ba51a1Sopenharmony_ci} 167b3ba51a1Sopenharmony_ci 168b3ba51a1Sopenharmony_ci#[test] 169b3ba51a1Sopenharmony_ci#[cfg(all(unix, feature = "regex"))] 170b3ba51a1Sopenharmony_cifn test_which_re_accepts_owned_and_borrow() { 171b3ba51a1Sopenharmony_ci which::which_re(Regex::new(r".").unwrap()) 172b3ba51a1Sopenharmony_ci .unwrap() 173b3ba51a1Sopenharmony_ci .for_each(drop); 174b3ba51a1Sopenharmony_ci which::which_re(&Regex::new(r".").unwrap()) 175b3ba51a1Sopenharmony_ci .unwrap() 176b3ba51a1Sopenharmony_ci .for_each(drop); 177b3ba51a1Sopenharmony_ci which::which_re_in(Regex::new(r".").unwrap(), Some("pth")) 178b3ba51a1Sopenharmony_ci .unwrap() 179b3ba51a1Sopenharmony_ci .for_each(drop); 180b3ba51a1Sopenharmony_ci which::which_re_in(&Regex::new(r".").unwrap(), Some("pth")) 181b3ba51a1Sopenharmony_ci .unwrap() 182b3ba51a1Sopenharmony_ci .for_each(drop); 183b3ba51a1Sopenharmony_ci} 184b3ba51a1Sopenharmony_ci 185b3ba51a1Sopenharmony_ci#[test] 186b3ba51a1Sopenharmony_ci#[cfg(unix)] 187b3ba51a1Sopenharmony_cifn test_which_extension() { 188b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 189b3ba51a1Sopenharmony_ci let b = Path::new(&BIN_NAME).with_extension(""); 190b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &b).unwrap(), f.bins[0]) 191b3ba51a1Sopenharmony_ci} 192b3ba51a1Sopenharmony_ci 193b3ba51a1Sopenharmony_ci#[test] 194b3ba51a1Sopenharmony_ci#[cfg(windows)] 195b3ba51a1Sopenharmony_cifn test_which_extension() { 196b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 197b3ba51a1Sopenharmony_ci let b = Path::new(&BIN_NAME).with_extension("cmd"); 198b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &b).unwrap(), f.bins[2]) 199b3ba51a1Sopenharmony_ci} 200b3ba51a1Sopenharmony_ci 201b3ba51a1Sopenharmony_ci#[test] 202b3ba51a1Sopenharmony_ci#[cfg(windows)] 203b3ba51a1Sopenharmony_cifn test_which_no_extension() { 204b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 205b3ba51a1Sopenharmony_ci let b = Path::new("win-bin"); 206b3ba51a1Sopenharmony_ci let which_result = which::which_in(&b, Some(&f.paths), ".").unwrap(); 207b3ba51a1Sopenharmony_ci // Make sure the extension is the correct case. 208b3ba51a1Sopenharmony_ci assert_eq!(which_result.extension(), f.bins[9].extension()); 209b3ba51a1Sopenharmony_ci assert_eq!(fs::canonicalize(&which_result).unwrap(), f.bins[9]) 210b3ba51a1Sopenharmony_ci} 211b3ba51a1Sopenharmony_ci 212b3ba51a1Sopenharmony_ci#[test] 213b3ba51a1Sopenharmony_cifn test_which_not_found() { 214b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 215b3ba51a1Sopenharmony_ci assert!(_which(&f, "a").is_err()); 216b3ba51a1Sopenharmony_ci} 217b3ba51a1Sopenharmony_ci 218b3ba51a1Sopenharmony_ci#[test] 219b3ba51a1Sopenharmony_cifn test_which_second() { 220b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 221b3ba51a1Sopenharmony_ci let b = f.mk_bin("b/another", env::consts::EXE_EXTENSION).unwrap(); 222b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, "another").unwrap(), b); 223b3ba51a1Sopenharmony_ci} 224b3ba51a1Sopenharmony_ci 225b3ba51a1Sopenharmony_ci#[test] 226b3ba51a1Sopenharmony_cifn test_which_all() { 227b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 228b3ba51a1Sopenharmony_ci let actual = _which_all(&f, BIN_NAME) 229b3ba51a1Sopenharmony_ci .unwrap() 230b3ba51a1Sopenharmony_ci .map(|c| c.unwrap()) 231b3ba51a1Sopenharmony_ci .collect::<Vec<_>>(); 232b3ba51a1Sopenharmony_ci let mut expected = f 233b3ba51a1Sopenharmony_ci .bins 234b3ba51a1Sopenharmony_ci .iter() 235b3ba51a1Sopenharmony_ci .map(|p| p.canonicalize().unwrap()) 236b3ba51a1Sopenharmony_ci .collect::<Vec<_>>(); 237b3ba51a1Sopenharmony_ci #[cfg(windows)] 238b3ba51a1Sopenharmony_ci { 239b3ba51a1Sopenharmony_ci expected.retain(|p| p.file_stem().unwrap() == BIN_NAME); 240b3ba51a1Sopenharmony_ci expected.retain(|p| p.extension().map(|ext| ext == "exe" || ext == "cmd") == Some(true)); 241b3ba51a1Sopenharmony_ci } 242b3ba51a1Sopenharmony_ci #[cfg(not(windows))] 243b3ba51a1Sopenharmony_ci { 244b3ba51a1Sopenharmony_ci expected.retain(|p| p.file_name().unwrap() == BIN_NAME); 245b3ba51a1Sopenharmony_ci } 246b3ba51a1Sopenharmony_ci assert_eq!(actual, expected); 247b3ba51a1Sopenharmony_ci} 248b3ba51a1Sopenharmony_ci 249b3ba51a1Sopenharmony_ci#[test] 250b3ba51a1Sopenharmony_ci#[cfg(unix)] 251b3ba51a1Sopenharmony_cifn test_which_absolute() { 252b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 253b3ba51a1Sopenharmony_ci assert_eq!( 254b3ba51a1Sopenharmony_ci _which(&f, &f.bins[3]).unwrap(), 255b3ba51a1Sopenharmony_ci f.bins[3].canonicalize().unwrap() 256b3ba51a1Sopenharmony_ci ); 257b3ba51a1Sopenharmony_ci} 258b3ba51a1Sopenharmony_ci 259b3ba51a1Sopenharmony_ci#[test] 260b3ba51a1Sopenharmony_ci#[cfg(windows)] 261b3ba51a1Sopenharmony_cifn test_which_absolute() { 262b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 263b3ba51a1Sopenharmony_ci assert_eq!( 264b3ba51a1Sopenharmony_ci _which(&f, &f.bins[4]).unwrap(), 265b3ba51a1Sopenharmony_ci f.bins[4].canonicalize().unwrap() 266b3ba51a1Sopenharmony_ci ); 267b3ba51a1Sopenharmony_ci} 268b3ba51a1Sopenharmony_ci 269b3ba51a1Sopenharmony_ci#[test] 270b3ba51a1Sopenharmony_ci#[cfg(windows)] 271b3ba51a1Sopenharmony_cifn test_which_absolute_path_case() { 272b3ba51a1Sopenharmony_ci // Test that an absolute path with an uppercase extension 273b3ba51a1Sopenharmony_ci // is accepted. 274b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 275b3ba51a1Sopenharmony_ci let p = &f.bins[4]; 276b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &p).unwrap(), f.bins[4].canonicalize().unwrap()); 277b3ba51a1Sopenharmony_ci} 278b3ba51a1Sopenharmony_ci 279b3ba51a1Sopenharmony_ci#[test] 280b3ba51a1Sopenharmony_ci#[cfg(unix)] 281b3ba51a1Sopenharmony_cifn test_which_absolute_extension() { 282b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 283b3ba51a1Sopenharmony_ci // Don't append EXE_EXTENSION here. 284b3ba51a1Sopenharmony_ci let b = f.bins[3].parent().unwrap().join(&BIN_NAME); 285b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &b).unwrap(), f.bins[3].canonicalize().unwrap()); 286b3ba51a1Sopenharmony_ci} 287b3ba51a1Sopenharmony_ci 288b3ba51a1Sopenharmony_ci#[test] 289b3ba51a1Sopenharmony_ci#[cfg(windows)] 290b3ba51a1Sopenharmony_cifn test_which_absolute_extension() { 291b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 292b3ba51a1Sopenharmony_ci // Don't append EXE_EXTENSION here. 293b3ba51a1Sopenharmony_ci let b = f.bins[4].parent().unwrap().join(&BIN_NAME); 294b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &b).unwrap(), f.bins[4].canonicalize().unwrap()); 295b3ba51a1Sopenharmony_ci} 296b3ba51a1Sopenharmony_ci 297b3ba51a1Sopenharmony_ci#[test] 298b3ba51a1Sopenharmony_ci#[cfg(unix)] 299b3ba51a1Sopenharmony_cifn test_which_relative() { 300b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 301b3ba51a1Sopenharmony_ci assert_eq!( 302b3ba51a1Sopenharmony_ci _which(&f, "b/bin").unwrap(), 303b3ba51a1Sopenharmony_ci f.bins[3].canonicalize().unwrap() 304b3ba51a1Sopenharmony_ci ); 305b3ba51a1Sopenharmony_ci} 306b3ba51a1Sopenharmony_ci 307b3ba51a1Sopenharmony_ci#[test] 308b3ba51a1Sopenharmony_ci#[cfg(windows)] 309b3ba51a1Sopenharmony_cifn test_which_relative() { 310b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 311b3ba51a1Sopenharmony_ci assert_eq!( 312b3ba51a1Sopenharmony_ci _which(&f, "b/bin").unwrap(), 313b3ba51a1Sopenharmony_ci f.bins[4].canonicalize().unwrap() 314b3ba51a1Sopenharmony_ci ); 315b3ba51a1Sopenharmony_ci} 316b3ba51a1Sopenharmony_ci 317b3ba51a1Sopenharmony_ci#[test] 318b3ba51a1Sopenharmony_ci#[cfg(unix)] 319b3ba51a1Sopenharmony_cifn test_which_relative_extension() { 320b3ba51a1Sopenharmony_ci // test_which_relative tests a relative path without an extension, 321b3ba51a1Sopenharmony_ci // so test a relative path with an extension here. 322b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 323b3ba51a1Sopenharmony_ci let b = Path::new("b/bin").with_extension(env::consts::EXE_EXTENSION); 324b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &b).unwrap(), f.bins[3].canonicalize().unwrap()); 325b3ba51a1Sopenharmony_ci} 326b3ba51a1Sopenharmony_ci 327b3ba51a1Sopenharmony_ci#[test] 328b3ba51a1Sopenharmony_ci#[cfg(windows)] 329b3ba51a1Sopenharmony_cifn test_which_relative_extension() { 330b3ba51a1Sopenharmony_ci // test_which_relative tests a relative path without an extension, 331b3ba51a1Sopenharmony_ci // so test a relative path with an extension here. 332b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 333b3ba51a1Sopenharmony_ci let b = Path::new("b/bin").with_extension("cmd"); 334b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &b).unwrap(), f.bins[5].canonicalize().unwrap()); 335b3ba51a1Sopenharmony_ci} 336b3ba51a1Sopenharmony_ci 337b3ba51a1Sopenharmony_ci#[test] 338b3ba51a1Sopenharmony_ci#[cfg(windows)] 339b3ba51a1Sopenharmony_cifn test_which_relative_extension_case() { 340b3ba51a1Sopenharmony_ci // Test that a relative path with an uppercase extension 341b3ba51a1Sopenharmony_ci // is accepted. 342b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 343b3ba51a1Sopenharmony_ci let b = Path::new("b/bin").with_extension("EXE"); 344b3ba51a1Sopenharmony_ci assert_eq!(_which(&f, &b).unwrap(), f.bins[4].canonicalize().unwrap()); 345b3ba51a1Sopenharmony_ci} 346b3ba51a1Sopenharmony_ci 347b3ba51a1Sopenharmony_ci#[test] 348b3ba51a1Sopenharmony_ci#[cfg(unix)] 349b3ba51a1Sopenharmony_cifn test_which_relative_leading_dot() { 350b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 351b3ba51a1Sopenharmony_ci assert_eq!( 352b3ba51a1Sopenharmony_ci _which(&f, "./b/bin").unwrap(), 353b3ba51a1Sopenharmony_ci f.bins[3].canonicalize().unwrap() 354b3ba51a1Sopenharmony_ci ); 355b3ba51a1Sopenharmony_ci} 356b3ba51a1Sopenharmony_ci 357b3ba51a1Sopenharmony_ci#[test] 358b3ba51a1Sopenharmony_ci#[cfg(windows)] 359b3ba51a1Sopenharmony_cifn test_which_relative_leading_dot() { 360b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 361b3ba51a1Sopenharmony_ci assert_eq!( 362b3ba51a1Sopenharmony_ci _which(&f, "./b/bin").unwrap(), 363b3ba51a1Sopenharmony_ci f.bins[4].canonicalize().unwrap() 364b3ba51a1Sopenharmony_ci ); 365b3ba51a1Sopenharmony_ci} 366b3ba51a1Sopenharmony_ci 367b3ba51a1Sopenharmony_ci#[test] 368b3ba51a1Sopenharmony_ci#[cfg(unix)] 369b3ba51a1Sopenharmony_cifn test_which_non_executable() { 370b3ba51a1Sopenharmony_ci // Shouldn't return non-executable files. 371b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 372b3ba51a1Sopenharmony_ci f.touch("b/another", "").unwrap(); 373b3ba51a1Sopenharmony_ci assert!(_which(&f, "another").is_err()); 374b3ba51a1Sopenharmony_ci} 375b3ba51a1Sopenharmony_ci 376b3ba51a1Sopenharmony_ci#[test] 377b3ba51a1Sopenharmony_ci#[cfg(unix)] 378b3ba51a1Sopenharmony_cifn test_which_absolute_non_executable() { 379b3ba51a1Sopenharmony_ci // Shouldn't return non-executable files, even if given an absolute path. 380b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 381b3ba51a1Sopenharmony_ci let b = f.touch("b/another", "").unwrap(); 382b3ba51a1Sopenharmony_ci assert!(_which(&f, &b).is_err()); 383b3ba51a1Sopenharmony_ci} 384b3ba51a1Sopenharmony_ci 385b3ba51a1Sopenharmony_ci#[test] 386b3ba51a1Sopenharmony_ci#[cfg(unix)] 387b3ba51a1Sopenharmony_cifn test_which_relative_non_executable() { 388b3ba51a1Sopenharmony_ci // Shouldn't return non-executable files. 389b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 390b3ba51a1Sopenharmony_ci f.touch("b/another", "").unwrap(); 391b3ba51a1Sopenharmony_ci assert!(_which(&f, "b/another").is_err()); 392b3ba51a1Sopenharmony_ci} 393b3ba51a1Sopenharmony_ci 394b3ba51a1Sopenharmony_ci#[test] 395b3ba51a1Sopenharmony_cifn test_failure() { 396b3ba51a1Sopenharmony_ci let f = TestFixture::new(); 397b3ba51a1Sopenharmony_ci 398b3ba51a1Sopenharmony_ci let run = || -> which::Result<PathBuf> { 399b3ba51a1Sopenharmony_ci let p = _which(&f, "./b/bin")?; 400b3ba51a1Sopenharmony_ci Ok(p.into_path_buf()) 401b3ba51a1Sopenharmony_ci }; 402b3ba51a1Sopenharmony_ci 403b3ba51a1Sopenharmony_ci let _ = run(); 404b3ba51a1Sopenharmony_ci} 405