History

Merge pull request #1560 from EliahKagan/run-ci/env-lifo

Let `gix_testtools::Env` undo multiple changes to the same var

Sebastian Thiel committed 2 years ago

Commit 2972ea82 parents 649f588 555164f4 files · +100 −3Browse files

Unified · Split

4 files
  1. Cargo.lock +1 −0
  2. tests/tools/Cargo.toml +3 −0
  3. tests/tools/src/lib.rs +3 −3
  4. tests/tools/tests/env.rs +93 −0
Cargo.lock+1−0
@@ -2579,6 +2579,7 @@ dependencies = [ · 2578 unmodified lines
2579 "is_ci",2579 "is_ci",
2580 "once_cell",2580 "once_cell",
2581 "parking_lot",2581 "parking_lot",
2582 "serial_test",
2582 "tar",2583 "tar",
2583 "tempfile",2584 "tempfile",
2584 "winnow",2585 "winnow",
tests/tools/Cargo.toml+3−0
@@ -49,6 +49,9 @@ xz2 = { version = "0.1.6", optional = true } · 48 unmodified lines
49 49
50document-features = { version = "0.2.1", optional = true }50document-features = { version = "0.2.1", optional = true }
51 51
52[dev-dependencies]
53serial_test = { version = "3.1.0", default-features = false }
54
52[package.metadata.docs.rs]55[package.metadata.docs.rs]
53all-features = true56all-features = true
54features = ["document-features"]57features = ["document-features"]
tests/tools/src/lib.rs+3−3
@@ -823,7 +823,7 @@ fn family_name() -> &'static str { · 822 unmodified lines
823 }823 }
824}824}
825 825
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.
827#[derive(Default)]827#[derive(Default)]
828pub struct Env<'a> {828pub struct Env<'a> {
829 altered_vars: Vec<(&'a str, Option<OsString>)>,829 altered_vars: Vec<(&'a str, Option<OsString>)>,
@@ -845,7 +845,7 @@ impl<'a> Env<'a> { · 15 unmodified lines
845 self845 self
846 }846 }
847 847
848 /// Set `var` to `value`.848 /// Unset `var`.
849 pub fn unset(mut self, var: &'a str) -> Self {849 pub fn unset(mut self, var: &'a str) -> Self {
850 let prev = std::env::var_os(var);850 let prev = std::env::var_os(var);
851 std::env::remove_var(var);851 std::env::remove_var(var);
@@ -856,7 +856,7 @@ impl<'a> Env<'a> { · 4 unmodified lines
856 856
857impl<'a> Drop for Env<'a> {857impl<'a> Drop for Env<'a> {
858 fn drop(&mut self) {858 fn drop(&mut self) {
859 for (var, prev_value) in &self.altered_vars {859 for (var, prev_value) in self.altered_vars.iter().rev() {
860 match prev_value {860 match prev_value {
861 Some(value) => std::env::set_var(var, value),861 Some(value) => std::env::set_var(var, value),
862 None => std::env::remove_var(var),862 None => std::env::remove_var(var),
tests/tools/tests/env.rs+93−0
@@ -0,0 +1,93 @@
1use std::env;
2
3use gix_testtools::Env;
4use serial_test::serial;
5
6// We rely on these not already existing, to test `Env` without using or rewriting it.
7static VAR1: &str = "VAR_03FC4045_6043_4A61_9D15_852236CB632B";
8static VAR2: &str = "VAR_8C135840_05DB_4F3A_BFDD_FC755EC35B89";
9static VAR3: &str = "VAR_9B23A2BE_E20B_4670_93E2_3A6A8D47F274";
10
11struct TestEnv;
12
13impl 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
22impl 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]
32fn 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]
49fn 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]
60fn 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]
72fn 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}