From 004dcc5d5ca96e0ce1d5274d1dc47ee486125ffe Mon Sep 17 00:00:00 2001 From: Aaron Allen Date: Sun, 24 Aug 2025 16:01:20 -0500 Subject: [PATCH] Add `temp-env` as a dev dependency and refactor tests (#4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Introduce `temp-env` crate (v0.3) to simplify environment variable handling in tests. - Replace custom `env::set_var`/`env::remove_var` calls with `temp_env` utility methods. - Eliminate unsafe code in test cases by leveraging `temp_env`'s scoped modification functions. - Update `Cargo.toml` and `Cargo.lock` to reflect the new development dependency. ## Type of Change - [ ] ๐Ÿ› Bug fix (non-breaking change that fixes an issue) - [ ] โœจ New feature (non-breaking change that adds functionality) - [ ] ๐Ÿ’ฅ Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] ๐Ÿ“š Documentation update - [x] ๐Ÿงน Code cleanup or refactoring - [x] ๐Ÿ”ง Build system or dependency changes - [x] ๐Ÿงช Test improvements ## What Changed? This refactors tests to use temp-env instead of using unsafe code ## How Has This Been Tested? - [x] Existing tests pass (`mise test`) - [x] New tests added for new functionality - [x] Manual testing performed - [x] Code follows style guidelines (`mise lint`) --- Cargo.lock | 154 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 + src/lib.rs | 227 ++++++++++++++++++++++------------------------------- 3 files changed, 253 insertions(+), 131 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c33b73..8db928a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,160 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "2.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + [[package]] name = "dir_spec" version = "0.2.0" +dependencies = [ + "temp-env", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "temp-env" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96374855068f47402c3121c6eed88d29cb1de8f3ab27090e273e420bdabcf050" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 40ff127..359eb58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,9 @@ readme = "README.md" keywords = ["xdg", "directories", "cross-platform", "filesystem", "config"] categories = ["filesystem", "os", "config"] +[dev-dependencies] +temp-env = "0.3" + [lints.clippy] complexity = { level = "warn", priority = -1 } correctness = { level = "warn", priority = -1 } diff --git a/src/lib.rs b/src/lib.rs index 38bd43d..93ca316 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -425,44 +425,30 @@ impl Dir { #[cfg(test)] mod tests { - use std::env; - use super::*; #[test] - #[allow(unsafe_code)] fn test_resolve_xdg_path_absolute() { - unsafe { - env::set_var("TEST_XDG_VAR", "/absolute/path"); - } - let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); - assert_eq!(result, Some(PathBuf::from("/absolute/path"))); - unsafe { - env::remove_var("TEST_XDG_VAR"); - } + temp_env::with_var("TEST_XDG_VAR", Some("/absolute/path"), || { + let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); + assert_eq!(result, Some(PathBuf::from("/absolute/path"))); + }); } #[test] - #[allow(unsafe_code)] fn test_resolve_xdg_path_relative_ignored() { - unsafe { - env::set_var("TEST_XDG_VAR", "relative/path"); - } - let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); - assert_eq!(result, None); - unsafe { - env::remove_var("TEST_XDG_VAR"); - } + temp_env::with_var("TEST_XDG_VAR", Some("relative/path"), || { + let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); + assert_eq!(result, None); + }); } #[test] - #[allow(unsafe_code)] fn test_resolve_xdg_path_unset() { - unsafe { - env::remove_var("TEST_XDG_VAR"); - } - let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); - assert_eq!(result, None); + temp_env::with_var_unset("TEST_XDG_VAR", || { + let result = Dir::resolve_xdg_path("TEST_XDG_VAR"); + assert_eq!(result, None); + }); } #[test] @@ -474,158 +460,137 @@ mod tests { } #[test] - #[allow(unsafe_code)] fn test_config_home_default() { - unsafe { - env::remove_var("XDG_CONFIG_HOME"); - } - let config = Dir::config_home(); - if let Some(config_path) = config { - assert!(config_path.is_absolute()); + temp_env::with_var_unset("XDG_CONFIG_HOME", || { + let config = Dir::config_home(); + if let Some(config_path) = config { + assert!(config_path.is_absolute()); - #[cfg(target_os = "linux")] - assert!(config_path.to_string_lossy().ends_with(".config")); + #[cfg(target_os = "linux")] + assert!(config_path.to_string_lossy().ends_with(".config")); - #[cfg(target_os = "macos")] - assert!(config_path.to_string_lossy().contains("Library/Application Support")); - } + #[cfg(target_os = "macos")] + assert!(config_path.to_string_lossy().contains("Library/Application Support")); + } + }); } #[test] - #[allow(unsafe_code)] fn test_config_home_xdg_override() { let test_path = if cfg!(windows) { "C:\\test\\config" } else { "/test/config" }; - unsafe { - env::set_var("XDG_CONFIG_HOME", test_path); - } - let config = Dir::config_home(); - assert_eq!(config, Some(PathBuf::from(test_path))); - unsafe { - env::remove_var("XDG_CONFIG_HOME"); - } + temp_env::with_var("XDG_CONFIG_HOME", Some(test_path), || { + let config = Dir::config_home(); + assert_eq!(config, Some(PathBuf::from(test_path))); + }); } #[test] - #[allow(unsafe_code)] fn test_cache_home_default() { - unsafe { - env::remove_var("XDG_CACHE_HOME"); - } - let cache = Dir::cache_home(); - if let Some(cache_path) = cache { - assert!(cache_path.is_absolute()); + temp_env::with_var_unset("XDG_CACHE_HOME", || { + let cache = Dir::cache_home(); + if let Some(cache_path) = cache { + assert!(cache_path.is_absolute()); - #[cfg(target_os = "linux")] - assert!(cache_path.to_string_lossy().ends_with(".cache")); + #[cfg(target_os = "linux")] + assert!(cache_path.to_string_lossy().ends_with(".cache")); - #[cfg(target_os = "macos")] - assert!(cache_path.to_string_lossy().contains("Library/Caches")); - } + #[cfg(target_os = "macos")] + assert!(cache_path.to_string_lossy().contains("Library/Caches")); + } + }); } #[test] - #[allow(unsafe_code)] fn test_data_home_default() { - unsafe { - env::remove_var("XDG_DATA_HOME"); - } - let data = Dir::data_home(); - if let Some(data_path) = data { - assert!(data_path.is_absolute()); + temp_env::with_var_unset("XDG_DATA_HOME", || { + let data = Dir::data_home(); + if let Some(data_path) = data { + assert!(data_path.is_absolute()); - #[cfg(target_os = "linux")] - assert!(data_path.to_string_lossy().ends_with(".local/share")); + #[cfg(target_os = "linux")] + assert!(data_path.to_string_lossy().ends_with(".local/share")); - #[cfg(target_os = "macos")] - assert!(data_path.to_string_lossy().contains("Library/Application Support")); - } + #[cfg(target_os = "macos")] + assert!(data_path.to_string_lossy().contains("Library/Application Support")); + } + }); } #[test] - #[allow(unsafe_code)] fn test_bin_home_default() { - unsafe { - env::remove_var("XDG_BIN_HOME"); - } - let bin = Dir::bin_home(); - if let Some(bin_path) = bin { - assert!(bin_path.is_absolute()); + temp_env::with_var_unset("XDG_BIN_HOME", || { + let bin = Dir::bin_home(); + if let Some(bin_path) = bin { + assert!(bin_path.is_absolute()); - #[cfg(any(target_os = "linux", target_os = "macos"))] - assert!(bin_path.to_string_lossy().ends_with(".local/bin")); + #[cfg(any(target_os = "linux", target_os = "macos"))] + assert!(bin_path.to_string_lossy().ends_with(".local/bin")); - #[cfg(target_os = "windows")] - assert!(bin_path.to_string_lossy().contains("Programs")); - } + #[cfg(target_os = "windows")] + assert!(bin_path.to_string_lossy().contains("Programs")); + } + }); } #[test] - #[allow(unsafe_code)] fn test_runtime_default() { - unsafe { - env::remove_var("XDG_RUNTIME_DIR"); - } - let runtime = Dir::runtime(); - if let Some(runtime_path) = runtime { - assert!(runtime_path.is_absolute()); - - #[cfg(any(target_os = "linux", target_os = "macos"))] - { - let path_str = runtime_path.to_string_lossy(); - assert!(path_str.contains("tmp") || path_str.starts_with("/var/folders")); + temp_env::with_var_unset("XDG_RUNTIME_DIR", || { + let runtime = Dir::runtime(); + if let Some(runtime_path) = runtime { + assert!(runtime_path.is_absolute()); + + #[cfg(any(target_os = "linux", target_os = "macos"))] + { + let path_str = runtime_path.to_string_lossy(); + assert!(path_str.contains("tmp") || path_str.starts_with("/var/folders")); + } } - } + }); } #[test] - #[allow(unsafe_code)] fn test_desktop_default() { - unsafe { - env::remove_var("XDG_DESKTOP_DIR"); - } - let desktop = Dir::desktop(); - if let Some(desktop_path) = desktop { - assert!(desktop_path.is_absolute()); - assert!(desktop_path.to_string_lossy().ends_with("Desktop")); - } + temp_env::with_var_unset("XDG_DESKTOP_DIR", || { + let desktop = Dir::desktop(); + if let Some(desktop_path) = desktop { + assert!(desktop_path.is_absolute()); + assert!(desktop_path.to_string_lossy().ends_with("Desktop")); + } + }); } #[test] - #[allow(unsafe_code)] fn test_videos_platform_differences() { - unsafe { - env::remove_var("XDG_VIDEOS_DIR"); - } - let videos = Dir::videos(); - if let Some(videos_path) = videos { - assert!(videos_path.is_absolute()); + temp_env::with_var_unset("XDG_VIDEOS_DIR", || { + let videos = Dir::videos(); + if let Some(videos_path) = videos { + assert!(videos_path.is_absolute()); - #[cfg(target_os = "linux")] - assert!(videos_path.to_string_lossy().ends_with("Videos")); + #[cfg(target_os = "linux")] + assert!(videos_path.to_string_lossy().ends_with("Videos")); - #[cfg(target_os = "macos")] - assert!(videos_path.to_string_lossy().ends_with("Movies")); + #[cfg(target_os = "macos")] + assert!(videos_path.to_string_lossy().ends_with("Movies")); - #[cfg(target_os = "windows")] - assert!(videos_path.to_string_lossy().ends_with("Videos")); - } + #[cfg(target_os = "windows")] + assert!(videos_path.to_string_lossy().ends_with("Videos")); + } + }); } #[test] - #[allow(unsafe_code)] fn test_publicshare_windows_absolute() { - unsafe { - env::remove_var("XDG_PUBLICSHARE_DIR"); - } - let public = Dir::publicshare(); - if let Some(public_path) = public { - assert!(public_path.is_absolute()); + temp_env::with_var_unset("XDG_PUBLICSHARE_DIR", || { + let public = Dir::publicshare(); + if let Some(public_path) = public { + assert!(public_path.is_absolute()); - #[cfg(target_os = "windows")] - assert_eq!(public_path, PathBuf::from("C:\\Users\\Public")); + #[cfg(target_os = "windows")] + assert_eq!(public_path, PathBuf::from("C:\\Users\\Public")); - #[cfg(any(target_os = "linux", target_os = "macos"))] - assert!(public_path.to_string_lossy().ends_with("Public")); - } + #[cfg(any(target_os = "linux", target_os = "macos"))] + assert!(public_path.to_string_lossy().ends_with("Public")); + } + }); } } -- 2.51.2