Skip to content

docs: mention the Assert APIs, add misc fixes #4374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 7, 2025
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
35 changes: 18 additions & 17 deletions doc/dev-guide/src/coding-standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,29 @@ Usually, a `process: &Process` variable will be available to you in the current
For example, it could be in the form of a parameter of the current function,
or a field of a `Cfg` instance, etc.

## Clippy lints
## Writing tests

Rustup provides a number of test helpers in the `rustup::test` module
which is conditionally enabled with the `test` feature.

We do not enforce lint status in the checks done by GitHub Actions, because
clippy is a moving target that can make it hard to merge for little benefit.
The existing tests under `tests/suite` provide good examples of how to use these
helpers, but you might also find it useful to look at the documentation for
particular APIs in the `rustup::test` module.

We do ask that contributors keep the clippy status clean themselves.
For example, for more information regarding end-to-end tests with the `.expect()`
APIs, you can refer to the documentation of the [`Assert`] type.

Minimally, run `cargo clippy --all --all-targets --features test -- -D warnings` before
submitting code.
[`Assert`]: https://github.com/search?q=repo%3Arust-lang%2Frustup+symbol%3A%2F%28%3F-i%29Assert%2F&type=code

If possible, adding `--all-features` to the command is useful, but will require
additional dependencies like `libcurl-dev`.
## Clippy lints

Regular contributors or contributors to particularly OS-specific code should
also make sure that their clippy checking is done on at least Linux and Windows,
as OS-conditional code is a common source of unused imports and other small
lints, which can build up over time.
At the time of writing, rustup's CI pipeline runs clippy on both Windows and
Linux, but contributors to particularly OS-specific code should also make
sure that their clippy checking is done on that particular platform, as
OS-conditional code is a common source of unused imports and other small lints,
which can build up over time.

## Writing platform-specific code

For developers using BSD/Linux/Mac OS, there are Windows VM's suitable for such
development tasks for use with virtualbox and other hypervisors are downloadable
Expand All @@ -59,8 +65,3 @@ from
Similarly, there are many Linux and Unix operating systems images available for
developers whose usual operating system is Windows. Currently Rustup has no Mac
OS specific code, so there should be no need to worry about Mac VM images.

Clippy is also run in GitHub Actions, in the `General Checks / Checks` build
task, but not currently run per-platform, which means there is no way to find
out the status of clippy per platform without running it on that platform as a
developer.
2 changes: 1 addition & 1 deletion doc/user-guide/src/installation/already-installed-rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ eval $(/opt/homebrew/bin/brew shellenv)
. $HOME/.cargo/env
```

In this example, both of these lines all _prepend_ to `$PATH`, so the last one
In this example, both of these lines _prepend_ to `$PATH`, so the last one
takes over, letting the rustup proxies shadow the homebrew-installed `rust`.
On the other hand, putting these lines the other way around will cause the
aforementioned error.
Expand Down
49 changes: 48 additions & 1 deletion src/test/clitools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,61 @@ pub struct Config {
pub test_root_dir: PathBuf,
}

/// Helper type to simplify assertions of a command's output.
///
/// Typically, an [`Assert`] instance is created by calling the
/// [`Config::expect()`] method (or its variations) which will run the given
/// command in the test environment and wrap its output in the instance.
/// Then, that output can be compared against the expected one.
///
/// # Snapshot-Based Testing
///
/// Currently, rustup utilizes [`snapbox`] (a snapshot-based testing library)
/// for most comparisons, where the corresponding [`Assert`] method would
/// accept an `expected` argument conforming [`IntoData`], which is also
/// called a "snapshot".
///
/// Most of our tests use [inline][`snapbox::data::Inline`] snapshots created
/// with [`snapbox::str`], but it is also possible to use snapshots from
/// another file with [`snapbox::file`].
///
/// # Creating or Updating a Snapshot
///
/// There is no need to write out a snapshot by hand. Instead, create an empty
/// snapshot (e.g. `snapbox::str![[""]]`), and run the test in question with the
/// environment variable `SNAPSHOTS=overwrite` set. Normally, the snapshot will
/// then be populated automatically with the right value (modulo redaction,
/// which will be discussed in a later section).
///
/// The same environment variable is also used to update a snapshot with no extra
/// steps required.
///
/// # Redacting Snapshots
///
/// To defend against leaking of environment-specific information that might
/// break the tests on a different machine, a set of redaction rules (also known
/// as "filters") is used to sanitize the output before sending to comparison.
///
/// Rustup extends the list of `snapbox`'s default filters (see
/// [`assert_data_eq`]'s documentation for more info) with a list of
/// rustup-specific values, including:
/// - `[CURRENT_VERSION]`: The current rustup version.
/// - `[HOST_TRIPLE]`: The return value of [`this_host_triple()`].
/// - `[CROSS_ARCH_I]`: The value of [`CROSS_ARCH1`].
/// - `[CROSS_ARCH_II]`: The value of [`CROSS_ARCH2`].
/// - `[MULTI_ARCH_I]`: The value of [`MULTI_ARCH1`].
///
/// When updating snapshots, the filters are automatically applied.
/// To redact some remaining part of the snapshot, you can use the
/// [`Assert::extend_redactions`] method to introduce new filters.
#[derive(Clone)]
pub struct Assert {
output: SanitizedOutput,
redactions: Redactions,
}

impl Assert {
/// Creates a new [`Assert`] object with the given command [`SanitizedOutput`].
/// Creates a new [`Assert`] object with the given [`SanitizedOutput`].
pub fn new(output: SanitizedOutput) -> Self {
let mut redactions = Redactions::new();
redactions
Expand Down