Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 4f923bf

Browse files
committed
run_make_support: move assertions and helpers into own module
1 parent e174399 commit 4f923bf

File tree

2 files changed

+150
-134
lines changed

2 files changed

+150
-134
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
//! Collection of assertions and assertion-related helpers.
2+
3+
use std::path::{Path, PathBuf};
4+
use std::panic;
5+
6+
use crate::fs_wrapper;
7+
use crate::path_helpers::cwd;
8+
9+
/// Browse the directory `path` non-recursively and return all files which respect the parameters
10+
/// outlined by `closure`.
11+
#[track_caller]
12+
pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
13+
path: P,
14+
filter: F,
15+
) -> Vec<PathBuf> {
16+
let mut matching_files = Vec::new();
17+
for entry in fs_wrapper::read_dir(path) {
18+
let entry = entry.expect("failed to read directory entry.");
19+
let path = entry.path();
20+
21+
if path.is_file() && filter(&path) {
22+
matching_files.push(path);
23+
}
24+
}
25+
matching_files
26+
}
27+
28+
/// Returns true if the filename at `path` starts with `prefix`.
29+
pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
30+
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
31+
}
32+
33+
/// Returns true if the filename at `path` has the extension `extension`.
34+
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
35+
path.as_ref().extension().is_some_and(|ext| ext == extension)
36+
}
37+
38+
/// Returns true if the filename at `path` does not contain `expected`.
39+
pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
40+
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
41+
}
42+
43+
/// Returns true if the filename at `path` is not in `expected`.
44+
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
45+
let expected = expected.as_ref();
46+
path.as_ref()
47+
.file_name()
48+
.is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
49+
}
50+
51+
/// Returns true if the filename at `path` ends with `suffix`.
52+
pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
53+
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
54+
}
55+
56+
/// Gathers all files in the current working directory that have the extension `ext`, and counts
57+
/// the number of lines within that contain a match with the regex pattern `re`.
58+
pub fn count_regex_matches_in_files_with_extension(re: &regex::Regex, ext: &str) -> usize {
59+
let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
60+
61+
let mut count = 0;
62+
for file in fetched_files {
63+
let content = fs_wrapper::read_to_string(file);
64+
count += content.lines().filter(|line| re.is_match(&line)).count();
65+
}
66+
67+
count
68+
}
69+
70+
/// Read the contents of a file that cannot simply be read by
71+
/// [`read_to_string`][crate::fs_wrapper::read_to_string], due to invalid UTF-8 data, then assert
72+
/// that it contains `expected`.
73+
#[track_caller]
74+
pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
75+
let buffer = fs_wrapper::read(path.as_ref());
76+
let expected = expected.as_ref();
77+
if !String::from_utf8_lossy(&buffer).contains(expected) {
78+
eprintln!("=== FILE CONTENTS (LOSSY) ===");
79+
eprintln!("{}", String::from_utf8_lossy(&buffer));
80+
eprintln!("=== SPECIFIED TEXT ===");
81+
eprintln!("{}", expected);
82+
panic!("specified text was not found in file");
83+
}
84+
}
85+
86+
/// Read the contents of a file that cannot simply be read by
87+
/// [`read_to_string`][crate::fs_wrapper::read_to_string], due to invalid UTF-8 data, then assert
88+
/// that it does not contain `expected`.
89+
#[track_caller]
90+
pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
91+
let buffer = fs_wrapper::read(path.as_ref());
92+
let expected = expected.as_ref();
93+
if String::from_utf8_lossy(&buffer).contains(expected) {
94+
eprintln!("=== FILE CONTENTS (LOSSY) ===");
95+
eprintln!("{}", String::from_utf8_lossy(&buffer));
96+
eprintln!("=== SPECIFIED TEXT ===");
97+
eprintln!("{}", expected);
98+
panic!("specified text was unexpectedly found in file");
99+
}
100+
}
101+
102+
/// Assert that `actual` is equal to `expected`.
103+
#[track_caller]
104+
pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) {
105+
let actual = actual.as_ref();
106+
let expected = expected.as_ref();
107+
if actual != expected {
108+
eprintln!("=== ACTUAL TEXT ===");
109+
eprintln!("{}", actual);
110+
eprintln!("=== EXPECTED ===");
111+
eprintln!("{}", expected);
112+
panic!("expected text was not found in actual text");
113+
}
114+
}
115+
116+
/// Assert that `haystack` contains `needle`.
117+
#[track_caller]
118+
pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
119+
let haystack = haystack.as_ref();
120+
let needle = needle.as_ref();
121+
if !haystack.contains(needle) {
122+
eprintln!("=== HAYSTACK ===");
123+
eprintln!("{}", haystack);
124+
eprintln!("=== NEEDLE ===");
125+
eprintln!("{}", needle);
126+
panic!("needle was not found in haystack");
127+
}
128+
}
129+
130+
/// Assert that `haystack` does not contain `needle`.
131+
#[track_caller]
132+
pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
133+
let haystack = haystack.as_ref();
134+
let needle = needle.as_ref();
135+
if haystack.contains(needle) {
136+
eprintln!("=== HAYSTACK ===");
137+
eprintln!("{}", haystack);
138+
eprintln!("=== NEEDLE ===");
139+
eprintln!("{}", needle);
140+
panic!("needle was unexpectedly found in haystack");
141+
}
142+
}

src/tools/run-make-support/src/lib.rs

Lines changed: 8 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod macros;
88

99
pub mod ar;
1010
pub mod artifact_names;
11+
pub mod assertion_helpers;
1112
pub mod diff;
1213
pub mod env_checked;
1314
pub mod external_deps;
@@ -18,7 +19,6 @@ pub mod run;
1819
pub mod scoped_run;
1920
pub mod targets;
2021

21-
use std::panic;
2222
use std::path::{Path, PathBuf};
2323

2424
// Re-exports of third-party library crates.
@@ -77,68 +77,14 @@ pub use fs_helpers::{copy_dir_all, create_symlink, read_dir};
7777
/// Helpers for scoped test execution where certain properties are attempted to be maintained.
7878
pub use scoped_run::{run_in_tmpdir, test_while_readonly};
7979

80-
use command::{Command, CompletedProcess};
81-
82-
/// Browse the directory `path` non-recursively and return all files which respect the parameters
83-
/// outlined by `closure`.
84-
#[track_caller]
85-
pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
86-
path: P,
87-
filter: F,
88-
) -> Vec<PathBuf> {
89-
let mut matching_files = Vec::new();
90-
for entry in fs_wrapper::read_dir(path) {
91-
let entry = entry.expect("failed to read directory entry.");
92-
let path = entry.path();
93-
94-
if path.is_file() && filter(&path) {
95-
matching_files.push(path);
96-
}
97-
}
98-
matching_files
99-
}
100-
101-
/// Returns true if the filename at `path` starts with `prefix`.
102-
pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
103-
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
104-
}
105-
106-
/// Returns true if the filename at `path` has the extension `extension`.
107-
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
108-
path.as_ref().extension().is_some_and(|ext| ext == extension)
109-
}
110-
111-
/// Returns true if the filename at `path` does not contain `expected`.
112-
pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
113-
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
114-
}
115-
116-
/// Returns true if the filename at `path` is not in `expected`.
117-
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
118-
let expected = expected.as_ref();
119-
path.as_ref()
120-
.file_name()
121-
.is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
122-
}
123-
124-
/// Returns true if the filename at `path` ends with `suffix`.
125-
pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
126-
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
127-
}
128-
129-
/// Gathers all files in the current working directory that have the extension `ext`, and counts
130-
/// the number of lines within that contain a match with the regex pattern `re`.
131-
pub fn count_regex_matches_in_files_with_extension(re: &regex::Regex, ext: &str) -> usize {
132-
let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
133-
134-
let mut count = 0;
135-
for file in fetched_files {
136-
let content = fs_wrapper::read_to_string(file);
137-
count += content.lines().filter(|line| re.is_match(&line)).count();
138-
}
80+
pub use assertion_helpers::{
81+
assert_contains, assert_equals, assert_not_contains,
82+
count_regex_matches_in_files_with_extension, filename_not_in_denylist, has_extension,
83+
has_prefix, has_suffix, invalid_utf8_contains, invalid_utf8_not_contains, not_contains,
84+
shallow_find_files,
85+
};
13986

140-
count
141-
}
87+
use command::{Command, CompletedProcess};
14288

14389
pub(crate) fn handle_failed_output(
14490
cmd: &Command,
@@ -171,36 +117,6 @@ pub fn set_host_rpath(cmd: &mut Command) {
171117
});
172118
}
173119

174-
/// Read the contents of a file that cannot simply be read by
175-
/// read_to_string, due to invalid utf8 data, then assert that it contains `expected`.
176-
#[track_caller]
177-
pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
178-
let buffer = fs_wrapper::read(path.as_ref());
179-
let expected = expected.as_ref();
180-
if !String::from_utf8_lossy(&buffer).contains(expected) {
181-
eprintln!("=== FILE CONTENTS (LOSSY) ===");
182-
eprintln!("{}", String::from_utf8_lossy(&buffer));
183-
eprintln!("=== SPECIFIED TEXT ===");
184-
eprintln!("{}", expected);
185-
panic!("specified text was not found in file");
186-
}
187-
}
188-
189-
/// Read the contents of a file that cannot simply be read by
190-
/// read_to_string, due to invalid utf8 data, then assert that it does not contain `expected`.
191-
#[track_caller]
192-
pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
193-
let buffer = fs_wrapper::read(path.as_ref());
194-
let expected = expected.as_ref();
195-
if String::from_utf8_lossy(&buffer).contains(expected) {
196-
eprintln!("=== FILE CONTENTS (LOSSY) ===");
197-
eprintln!("{}", String::from_utf8_lossy(&buffer));
198-
eprintln!("=== SPECIFIED TEXT ===");
199-
eprintln!("{}", expected);
200-
panic!("specified text was unexpectedly found in file");
201-
}
202-
}
203-
204120
/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
205121
pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
206122
let dir2 = dir2.as_ref();
@@ -225,45 +141,3 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
225141
}
226142
});
227143
}
228-
229-
/// Check that `actual` is equal to `expected`. Panic otherwise.
230-
#[track_caller]
231-
pub fn assert_equals<S1: AsRef<str>, S2: AsRef<str>>(actual: S1, expected: S2) {
232-
let actual = actual.as_ref();
233-
let expected = expected.as_ref();
234-
if actual != expected {
235-
eprintln!("=== ACTUAL TEXT ===");
236-
eprintln!("{}", actual);
237-
eprintln!("=== EXPECTED ===");
238-
eprintln!("{}", expected);
239-
panic!("expected text was not found in actual text");
240-
}
241-
}
242-
243-
/// Check that `haystack` contains `needle`. Panic otherwise.
244-
#[track_caller]
245-
pub fn assert_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
246-
let haystack = haystack.as_ref();
247-
let needle = needle.as_ref();
248-
if !haystack.contains(needle) {
249-
eprintln!("=== HAYSTACK ===");
250-
eprintln!("{}", haystack);
251-
eprintln!("=== NEEDLE ===");
252-
eprintln!("{}", needle);
253-
panic!("needle was not found in haystack");
254-
}
255-
}
256-
257-
/// Check that `haystack` does not contain `needle`. Panic otherwise.
258-
#[track_caller]
259-
pub fn assert_not_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
260-
let haystack = haystack.as_ref();
261-
let needle = needle.as_ref();
262-
if haystack.contains(needle) {
263-
eprintln!("=== HAYSTACK ===");
264-
eprintln!("{}", haystack);
265-
eprintln!("=== NEEDLE ===");
266-
eprintln!("{}", needle);
267-
panic!("needle was unexpectedly found in haystack");
268-
}
269-
}

0 commit comments

Comments
 (0)