Skip to content

Commit ea65a34

Browse files
committed
refactor(test): add new testing APIs and simple showcases
1 parent 7ba0abf commit ea65a34

File tree

6 files changed

+100
-33
lines changed

6 files changed

+100
-33
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ otel = [
3737
]
3838

3939
# Exports code dependent on private interfaces for the integration test suite
40-
test = ["dep:walkdir"]
40+
test = ["dep:snapbox", "dep:walkdir"]
4141

4242
# Sorted by alphabetic order
4343
[dependencies]
@@ -77,6 +77,7 @@ semver = "1.0"
7777
serde = { version = "1.0", features = ["derive"] }
7878
sha2 = "0.10"
7979
sharded-slab = "0.1.1"
80+
snapbox = { version = "0.6.21", optional = true }
8081
strsim = "0.11"
8182
tar = "0.4.26"
8283
tempfile = "3.8"

src/test/clitools.rs

+65-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use std::{
1818
};
1919

2020
use enum_map::{Enum, EnumMap, enum_map};
21+
use snapbox::{IntoData, RedactedValue, Redactions, assert_data_eq};
2122
use tempfile::TempDir;
2223
use url::Url;
2324

@@ -61,6 +62,54 @@ pub struct Config {
6162
pub test_root_dir: PathBuf,
6263
}
6364

65+
#[derive(Clone)]
66+
pub struct Assert {
67+
output: SanitizedOutput,
68+
redactions: Redactions,
69+
}
70+
71+
impl Assert {
72+
pub fn new(output: SanitizedOutput) -> Self {
73+
let mut redactions = Redactions::new();
74+
redactions
75+
.extend([("[HOST_TRIPLE]", this_host_triple())])
76+
.expect("invalid redactions detected");
77+
Self { output, redactions }
78+
}
79+
80+
pub fn extend_redactions(
81+
&mut self,
82+
vars: impl IntoIterator<Item = (&'static str, impl Into<RedactedValue>)>,
83+
) -> &mut Self {
84+
self.redactions
85+
.extend(vars)
86+
.expect("invalid redactions detected");
87+
self
88+
}
89+
90+
pub fn is_ok(&self) -> &Self {
91+
assert!(self.output.ok);
92+
self
93+
}
94+
95+
pub fn is_err(&self) -> &Self {
96+
assert!(!self.output.ok);
97+
self
98+
}
99+
100+
pub fn with_stdout(&self, expected: impl IntoData) -> &Self {
101+
let stdout = self.redactions.redact(&self.output.stdout);
102+
assert_data_eq!(&stdout, expected);
103+
self
104+
}
105+
106+
pub fn with_stderr(&self, expected: impl IntoData) -> &Self {
107+
let stderr = self.redactions.redact(&self.output.stderr);
108+
assert_data_eq!(&stderr, expected);
109+
self
110+
}
111+
}
112+
64113
impl Config {
65114
pub fn current_dir(&self) -> PathBuf {
66115
self.workdir.borrow().clone()
@@ -136,6 +185,21 @@ impl Config {
136185
}
137186
}
138187

188+
#[must_use]
189+
pub async fn expect_with_env(
190+
&self,
191+
args: impl AsRef<[&str]>,
192+
env: impl AsRef<[(&str, &str)]>,
193+
) -> Assert {
194+
let args = args.as_ref();
195+
let output = self.run(args[0], &args[1..], env.as_ref()).await;
196+
Assert::new(output)
197+
}
198+
199+
pub async fn expect(&self, args: impl AsRef<[&str]>) -> Assert {
200+
self.expect_with_env(args, &[]).await
201+
}
202+
139203
/// Expect an ok status
140204
pub async fn expect_ok(&mut self, args: &[&str]) {
141205
self.expect_ok_env(args, &[]).await
@@ -1035,7 +1099,7 @@ pub struct Output {
10351099
pub stderr: Vec<u8>,
10361100
}
10371101

1038-
#[derive(Debug)]
1102+
#[derive(Debug, Clone)]
10391103
pub struct SanitizedOutput {
10401104
pub ok: bool,
10411105
pub stdout: String,

tests/suite/cli_exact.rs

+14-17
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustup::test::{
66
CROSS_ARCH1, CROSS_ARCH2, CliTestContext, MULTI_ARCH1, Scenario, this_host_triple,
77
};
88
use rustup::utils::raw;
9+
use snapbox::str;
910

1011
#[tokio::test]
1112
async fn update_once() {
@@ -308,23 +309,19 @@ info: default toolchain set to 'nightly-{0}'
308309

309310
#[tokio::test]
310311
async fn override_again() {
311-
let mut cx = CliTestContext::new(Scenario::SimpleV2).await;
312-
let cwd = cx.config.current_dir();
313-
cx.config
314-
.expect_ok(&["rustup", "override", "add", "nightly"])
315-
.await;
316-
cx.config
317-
.expect_ok_ex(
318-
&["rustup", "override", "add", "nightly"],
319-
"",
320-
&format!(
321-
r"info: override toolchain for '{}' set to 'nightly-{1}'
322-
",
323-
cwd.display(),
324-
&this_host_triple()
325-
),
326-
)
327-
.await;
312+
let cfg = &CliTestContext::new(Scenario::SimpleV2).await.config;
313+
cfg.expect(["rustup", "override", "add", "nightly"])
314+
.await
315+
.is_ok();
316+
cfg.expect(["rustup", "override", "add", "nightly"])
317+
.await
318+
.extend_redactions([("[CWD]", cfg.current_dir().display().to_string())])
319+
.is_ok()
320+
.with_stdout("")
321+
.with_stderr(str![[r#"
322+
info: override toolchain for '[CWD]' set to 'nightly-[HOST_TRIPLE]'
323+
324+
"#]]);
328325
}
329326

330327
#[tokio::test]

tests/suite/cli_misc.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustup::test::{
1111
};
1212
use rustup::utils;
1313
use rustup::utils::raw::symlink_dir;
14+
use snapbox::str;
1415

1516
#[tokio::test]
1617
async fn smoke_test() {
@@ -113,16 +114,15 @@ async fn custom_invalid_names_with_archive_dates() {
113114
async fn update_all_no_update_whitespace() {
114115
let cx = CliTestContext::new(Scenario::SimpleV2).await;
115116
cx.config
116-
.expect_stdout_ok(
117-
&["rustup", "update", "nightly"],
118-
for_host!(
119-
r"
120-
nightly-{} installed - 1.3.0 (hash-nightly-2)
117+
.expect(["rustup", "update", "nightly"])
118+
.await
119+
.is_ok()
120+
.with_stdout(str![[r#"
121121
122-
"
123-
),
124-
)
125-
.await;
122+
nightly-[HOST_TRIPLE] installed - 1.3.0 (hash-nightly-2)
123+
124+
125+
"#]]);
126126
}
127127

128128
// Issue #145

tests/suite/cli_v1.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@ use std::fs;
55

66
use rustup::for_host;
77
use rustup::test::{CliTestContext, Scenario};
8+
use snapbox::str;
89

910
#[tokio::test]
1011
async fn rustc_no_default_toolchain() {
1112
let cx = CliTestContext::new(Scenario::SimpleV1).await;
1213
cx.config
13-
.expect_err(
14-
&["rustc"],
15-
"rustup could not choose a version of rustc to run",
16-
)
17-
.await;
14+
.expect(["rustc"])
15+
.await
16+
.is_err()
17+
.with_stderr(str![[r#"
18+
error: rustup could not choose a version of rustc to run, because one wasn't specified explicitly, and no default is configured.
19+
help: run 'rustup default stable' to download the latest stable release of Rust and set it as your default toolchain.
20+
21+
"#]]);
1822
}
1923

2024
#[tokio::test]

0 commit comments

Comments
 (0)