Skip to content
Open
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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ cargo-credential-macos-keychain = { version = "0.4.18", path = "credential/cargo
cargo-credential-wincred = { version = "0.4.18", path = "credential/cargo-credential-wincred" }
cargo-platform = { path = "crates/cargo-platform", version = "0.3.0" }
cargo-test-macro = { version = "0.4.7", path = "crates/cargo-test-macro" }
cargo-test-support = { version = "0.8.2", path = "crates/cargo-test-support" }
cargo-test-support = { version = "0.9.0", path = "crates/cargo-test-support" }
cargo-util = { version = "0.2.25", path = "crates/cargo-util" }
cargo-util-schemas = { version = "0.10.1", path = "crates/cargo-util-schemas" }
cargo_metadata = "0.21.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-test-support/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargo-test-support"
version = "0.8.2"
version = "0.9.0"
edition.workspace = true
rust-version = "1.90" # MSRV:1
license.workspace = true
Expand Down
6 changes: 6 additions & 0 deletions crates/cargo-test-support/src/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ fn add_regex_redactions(subs: &mut snapbox::Redactions) {
.unwrap();
subs.insert("[HASH]", regex!(r"/[a-z0-9\-_]+-(?<redacted>[0-9a-f]{16})"))
.unwrap();
// Match multi-part hashes like `06/b451d0d6f88b1d` used in directory paths
subs.insert("[HASH]", regex!(r"/(?<redacted>[a-f0-9]{2}\/[0-9a-f]{14})"))
.unwrap();
// Match file name hashes like `foo-06b451d0d6f88b1d`
subs.insert("[HASH]", regex!(r"[a-z0-9]+-(?<redacted>[a-f0-9]{16})"))
.unwrap();
subs.insert(
"[AVG_ELAPSED]",
regex!(r"(?<redacted>[0-9]+(\.[0-9]+)?) ns/iter"),
Expand Down
73 changes: 73 additions & 0 deletions crates/cargo-test-support/src/paths.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Access common paths and manipulate the filesystem

use filetime::FileTime;
use itertools::Itertools;
use walkdir::WalkDir;

use std::cell::RefCell;
use std::env;
Expand All @@ -12,6 +14,9 @@ use std::sync::Mutex;
use std::sync::OnceLock;
use std::sync::atomic::{AtomicUsize, Ordering};

use crate::compare::assert_e2e;
use crate::compare::match_contains;

static CARGO_INTEGRATION_TEST_DIR: &str = "cit";

static GLOBAL_ROOT: OnceLock<Mutex<Option<PathBuf>>> = OnceLock::new();
Expand Down Expand Up @@ -152,6 +157,14 @@ pub trait CargoPathExt {
fn move_in_time<F>(&self, travel_amount: F)
where
F: Fn(i64, u32) -> (i64, u32);

fn assert_file_layout(&self, expected: impl snapbox::IntoData);

fn assert_file_layout_with_ignored_paths(
&self,
expected: impl snapbox::IntoData,
ignored: &[PathBuf],
);
}

impl CargoPathExt for Path {
Expand Down Expand Up @@ -236,6 +249,37 @@ impl CargoPathExt for Path {
});
}
}

#[track_caller]
fn assert_file_layout(&self, expected: impl snapbox::IntoData) {
self.assert_file_layout_with_ignored_paths(expected, &default_ignored_paths());
}

#[track_caller]
fn assert_file_layout_with_ignored_paths(
&self,
expected: impl snapbox::IntoData,
ignored_paths: &[PathBuf],
) {
let assert = assert_e2e();
let actual = WalkDir::new(self)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
.map(|e| e.path().to_string_lossy().into_owned())
.filter(|file| {
for ignored in ignored_paths {
let ignored = ignored.to_str().unwrap();
if match_contains(&ignored, file, &assert.redactions()).is_ok() {
return false;
}
}
return true;
})
.join("\n");

assert.eq(format!("{actual}\n"), expected.unordered());
}
}

impl CargoPathExt for PathBuf {
Expand All @@ -260,6 +304,21 @@ impl CargoPathExt for PathBuf {
{
self.as_path().move_in_time(travel_amount)
}

#[track_caller]
fn assert_file_layout(&self, expected: impl snapbox::IntoData) {
self.as_path().assert_file_layout(expected);
}

#[track_caller]
fn assert_file_layout_with_ignored_paths(
&self,
expected: impl snapbox::IntoData,
ignored_paths: &[PathBuf],
) {
self.as_path()
.assert_file_layout_with_ignored_paths(expected, ignored_paths);
}
}

fn do_op<F>(path: &Path, desc: &str, mut f: F)
Expand Down Expand Up @@ -290,6 +349,20 @@ where
}
}

/// The default paths to ignore when [`CargoPathExt::assert_file_layout`] is called
fn default_ignored_paths() -> Vec<PathBuf> {
vec![
// Ignore MacOS debug symbols as there are many files/directories that would clutter up
// tests few not a lot of benefit.
"[..].dSYM/[..]",
// Ignore Windows debub symbols files (.pdb)
"[..].pdb",
]
.into_iter()
.map(|s| PathBuf::from(s))
.collect()
}

/// Get the filename for a library.
///
/// `kind` should be one of:
Expand Down
10 changes: 10 additions & 0 deletions src/doc/contrib/src/tests/writing.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ test.
- See [`support::compare`] for an explanation of the string pattern matching.
Patterns are used to make it easier to match against the expected output.

#### Filesystem layout testing

Tests often to need to verify Cargo created/removed files.
The `CargoPathExt` trait (implemented by `Path` and `PathBuf`) provides a `assert_file_layout()` to verify the files in a directory (including nested directories).
This takes a snapshot of (unordered) file paths for the given directory and asserts that all files are present and no new files have been created.

Files vary across operating systems, for example `.pdb` files on Windows.
Some of these platform specific files are ignored from snapshotting by default.
You can use `assert_file_layout_with_ignored_paths()` to change the file patterns that are ignored.

#### Testing Nightly Features

If you are testing a Cargo feature that only works on "nightly" Cargo, then
Expand Down
Loading
Loading