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
25792579 "is_ci",
25802580 "once_cell",
25812581 "parking_lot",
2582+ "serial_test",
25822583 "tar",
25832584 "tempfile",
25842585 "winnow",
tests/tools/Cargo.toml+3−0
@@ -49,6 +49,9 @@ xz2 = { version = "0.1.6", optional = true } · 48 unmodified lines
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+3−3
@@ -823,7 +823,7 @@ fn family_name() -> &'static str { · 822 unmodified lines
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> { · 15 unmodified lines
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> { · 4 unmodified lines
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+93−0
@@ -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+}