Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 6 additions & 3 deletions ninja_env/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![forbid(unsafe_code)]

//! Shared environment constants used across netsuke crates (library, tests,
//! and helpers).
//! Shared environment constants used across netsuke crates (library, tests, and
//! helpers).

/// Environment variable override for the Ninja executable.
///
Expand All @@ -10,7 +10,10 @@
/// ```
/// use ninja_env::NINJA_ENV;
/// std::env::set_var(NINJA_ENV, "/usr/bin/ninja");
/// assert_eq!(std::env::var(NINJA_ENV).unwrap(), "/usr/bin/ninja");
/// assert_eq!(
/// std::env::var(NINJA_ENV).expect("NINJA_ENV should be set"),
/// "/usr/bin/ninja",
/// );
/// std::env::remove_var(NINJA_ENV);
/// ```
pub const NINJA_ENV: &str = "NETSUKE_NINJA";
32 changes: 18 additions & 14 deletions tests/ninja_env_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

use mockable::MockEnv;
use ninja_env::NINJA_ENV;
use rstest::rstest;
use rstest::{fixture, rstest};
use serial_test::serial;
use std::path::PathBuf;
use test_support::{env::override_ninja_env, env_lock::EnvLock};

#[fixture]
fn ninja_tmp() -> PathBuf {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Consider cleaning up the temp directory after tests.

Since 'ninja_tmp' may accumulate files or directories during tests, add cleanup logic to remove the temp directory after each test to maintain test isolation.

Suggested implementation:

use std::fs;
use std::ops::Deref;

/// Wrapper struct to clean up temp directory after test
pub struct NinjaTmp(PathBuf);

impl Deref for NinjaTmp {
    type Target = PathBuf;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Drop for NinjaTmp {
    fn drop(&mut self) {
        let _ = fs::remove_dir_all(&self.0);
    }
}

#[fixture]
fn ninja_tmp() -> NinjaTmp {
    let path = std::env::temp_dir().join("ninja");
    // Ensure the directory exists for the test
    let _ = fs::create_dir_all(&path);
    NinjaTmp(path)
}
fn override_ninja_env_sets_and_restores(ninja_tmp: NinjaTmp) {

If there are other tests in this file using the ninja_tmp fixture, update their signatures to accept NinjaTmp instead of PathBuf. Also, update any usage of ninja_tmp in the test bodies to use *ninja_tmp or ninja_tmp.deref() if a PathBuf is needed.

std::env::temp_dir().join("ninja")
}

#[rstest]
#[serial]
fn override_ninja_env_sets_and_restores() {
fn override_ninja_env_sets_and_restores(ninja_tmp: PathBuf) {
let before = std::env::var_os(NINJA_ENV);
let original = before
.as_ref()
Expand All @@ -18,22 +24,21 @@ fn override_ninja_env_sets_and_restores() {
.withf(|k| k == NINJA_ENV)
.returning(move |_| original.clone().ok_or(std::env::VarError::NotPresent));
{
let target = std::env::temp_dir().join("ninja");
let _guard = override_ninja_env(&env, target.as_path());
let after = std::env::var(NINJA_ENV).expect("NINJA_ENV should be set after override");
assert_eq!(after, target.to_string_lossy().as_ref());
let _guard = override_ninja_env(&env, ninja_tmp.as_path());
let after = std::env::var_os(NINJA_ENV).expect("NINJA_ENV should be set after override");
assert_eq!(after, ninja_tmp.as_os_str());
}
let restored = std::env::var_os(NINJA_ENV);
assert_eq!(restored, before);
}

#[rstest]
#[serial]
fn override_ninja_env_unset_removes_variable() {
fn override_ninja_env_unset_removes_variable(ninja_tmp: PathBuf) {
let before = std::env::var_os(NINJA_ENV);
{
let _lock = EnvLock::acquire();
// SAFETY: `EnvLock` serialises mutations during setup.
// EnvLock serialises mutations during setup.
unsafe { std::env::remove_var(NINJA_ENV) };
}

Expand All @@ -42,21 +47,20 @@ fn override_ninja_env_unset_removes_variable() {
.withf(|k| k == NINJA_ENV)
.returning(|_| Err(std::env::VarError::NotPresent));
{
let target = std::env::temp_dir().join("ninja");
let _guard = override_ninja_env(&env, target.as_path());
let after = std::env::var(NINJA_ENV).expect("NINJA_ENV should be set after override");
assert_eq!(after, target.to_string_lossy().as_ref());
let _guard = override_ninja_env(&env, ninja_tmp.as_path());
let after = std::env::var_os(NINJA_ENV).expect("NINJA_ENV should be set after override");
assert_eq!(after, ninja_tmp.as_os_str());
}
assert!(std::env::var_os(NINJA_ENV).is_none());

// Restore original global state for isolation
{
let _lock = EnvLock::acquire();
if let Some(val) = before {
// SAFETY: `EnvLock` serialises mutations while restoring.
// EnvLock serialises mutations while restoring.
unsafe { std::env::set_var(NINJA_ENV, val) };
} else {
// SAFETY: `EnvLock` serialises mutations while restoring.
// EnvLock serialises mutations while restoring.
unsafe { std::env::remove_var(NINJA_ENV) };
}
}
Expand Down