Skip to content

Commit 2972ea8

Browse files
authored
Merge pull request #1560 from EliahKagan/run-ci/env-lifo
Let `gix_testtools::Env` undo multiple changes to the same var
2 parents 649f588 + 555164f commit 2972ea8

File tree

4 files changed

+100
-3
lines changed

4 files changed

+100
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/tools/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ xz2 = { version = "0.1.6", optional = true }
4949

5050
document-features = { version = "0.2.1", optional = true }
5151

52+
[dev-dependencies]
53+
serial_test = { version = "3.1.0", default-features = false }
54+
5255
[package.metadata.docs.rs]
5356
all-features = true
5457
features = ["document-features"]

tests/tools/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ fn family_name() -> &'static str {
823823
}
824824
}
825825

826-
/// A utility to set environment variables, while unsetting them (or resetting them to their previous value) on drop.
826+
/// A utility to set and unset environment variables, while restoring or removing them on drop.
827827
#[derive(Default)]
828828
pub struct Env<'a> {
829829
altered_vars: Vec<(&'a str, Option<OsString>)>,
@@ -845,7 +845,7 @@ impl<'a> Env<'a> {
845845
self
846846
}
847847

848-
/// Set `var` to `value`.
848+
/// Unset `var`.
849849
pub fn unset(mut self, var: &'a str) -> Self {
850850
let prev = std::env::var_os(var);
851851
std::env::remove_var(var);
@@ -856,7 +856,7 @@ impl<'a> Env<'a> {
856856

857857
impl<'a> Drop for Env<'a> {
858858
fn drop(&mut self) {
859-
for (var, prev_value) in &self.altered_vars {
859+
for (var, prev_value) in self.altered_vars.iter().rev() {
860860
match prev_value {
861861
Some(value) => std::env::set_var(var, value),
862862
None => std::env::remove_var(var),

tests/tools/tests/env.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use std::env;
2+
3+
use gix_testtools::Env;
4+
use serial_test::serial;
5+
6+
// We rely on these not already existing, to test `Env` without using or rewriting it.
7+
static VAR1: &str = "VAR_03FC4045_6043_4A61_9D15_852236CB632B";
8+
static VAR2: &str = "VAR_8C135840_05DB_4F3A_BFDD_FC755EC35B89";
9+
static VAR3: &str = "VAR_9B23A2BE_E20B_4670_93E2_3A6A8D47F274";
10+
11+
struct TestEnv;
12+
13+
impl TestEnv {
14+
fn new() -> Self {
15+
assert_eq!(env::var_os(VAR1), None);
16+
assert_eq!(env::var_os(VAR2), None);
17+
assert_eq!(env::var_os(VAR3), None);
18+
Self
19+
}
20+
}
21+
22+
impl Drop for TestEnv {
23+
fn drop(&mut self) {
24+
env::remove_var(VAR1);
25+
env::remove_var(VAR2);
26+
env::remove_var(VAR3);
27+
}
28+
}
29+
30+
#[test]
31+
#[serial]
32+
fn nonoverlapping() {
33+
let _meta = TestEnv::new();
34+
env::set_var(VAR1, "old1");
35+
env::set_var(VAR2, "old2");
36+
{
37+
let _env = Env::new().set(VAR1, "new1").unset(VAR2).set(VAR3, "new3");
38+
assert_eq!(env::var_os(VAR1), Some("new1".into()));
39+
assert_eq!(env::var_os(VAR2), None);
40+
assert_eq!(env::var_os(VAR3), Some("new3".into()));
41+
}
42+
assert_eq!(env::var_os(VAR1), Some("old1".into()));
43+
assert_eq!(env::var_os(VAR2), Some("old2".into()));
44+
assert_eq!(env::var_os(VAR3), None);
45+
}
46+
47+
#[test]
48+
#[serial]
49+
fn overlapping_reset() {
50+
let _meta = TestEnv::new();
51+
{
52+
let _env = Env::new().set(VAR1, "new1A").set(VAR1, "new1B");
53+
assert_eq!(env::var_os(VAR1), Some("new1B".into()));
54+
}
55+
assert_eq!(env::var_os(VAR1), None);
56+
}
57+
58+
#[test]
59+
#[serial]
60+
fn overlapping_unset() {
61+
let _meta = TestEnv::new();
62+
env::set_var(VAR1, "old1");
63+
{
64+
let _env = Env::new().unset(VAR1).unset(VAR1);
65+
assert_eq!(env::var_os(VAR1), None);
66+
}
67+
assert_eq!(env::var_os(VAR1), Some("old1".into()));
68+
}
69+
70+
#[test]
71+
#[serial]
72+
fn overlapping_combo() {
73+
let _meta = TestEnv::new();
74+
env::set_var(VAR1, "old1");
75+
env::set_var(VAR2, "old2");
76+
{
77+
let _env = Env::new()
78+
.set(VAR1, "new1A")
79+
.unset(VAR2)
80+
.set(VAR1, "new1B")
81+
.unset(VAR3)
82+
.set(VAR2, "new2")
83+
.set(VAR3, "new3")
84+
.unset(VAR1)
85+
.unset(VAR3);
86+
assert_eq!(env::var_os(VAR1), None);
87+
assert_eq!(env::var_os(VAR2), Some("new2".into()));
88+
assert_eq!(env::var_os(VAR3), None);
89+
}
90+
assert_eq!(env::var_os(VAR1), Some("old1".into()));
91+
assert_eq!(env::var_os(VAR2), Some("old2".into()));
92+
assert_eq!(env::var_os(VAR3), None);
93+
}

0 commit comments

Comments
 (0)