Skip to content

Commit f66d3d3

Browse files
committed
run_make_support: move assertions and helpers into own module
1 parent 66cef19 commit f66d3d3

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,41 +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-
}
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+
};
11086

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-
}
87+
use command::{Command, CompletedProcess};
11588

11689
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
11790
#[track_caller]
@@ -133,33 +106,6 @@ pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
133106
path(lib_path)
134107
}
135108

136-
/// Returns true if the filename at `path` is not in `expected`.
137-
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
138-
let expected = expected.as_ref();
139-
path.as_ref()
140-
.file_name()
141-
.is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
142-
}
143-
144-
/// Returns true if the filename at `path` ends with `suffix`.
145-
pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
146-
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
147-
}
148-
149-
/// Gathers all files in the current working directory that have the extension `ext`, and counts
150-
/// the number of lines within that contain a match with the regex pattern `re`.
151-
pub fn count_regex_matches_in_files_with_extension(re: &regex::Regex, ext: &str) -> usize {
152-
let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
153-
154-
let mut count = 0;
155-
for file in fetched_files {
156-
let content = fs_wrapper::read_to_string(file);
157-
count += content.lines().filter(|line| re.is_match(&line)).count();
158-
}
159-
160-
count
161-
}
162-
163109
pub(crate) fn handle_failed_output(
164110
cmd: &Command,
165111
output: CompletedProcess,
@@ -191,36 +137,6 @@ pub fn set_host_rpath(cmd: &mut Command) {
191137
});
192138
}
193139

194-
/// Read the contents of a file that cannot simply be read by
195-
/// read_to_string, due to invalid utf8 data, then assert that it contains `expected`.
196-
#[track_caller]
197-
pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
198-
let buffer = fs_wrapper::read(path.as_ref());
199-
let expected = expected.as_ref();
200-
if !String::from_utf8_lossy(&buffer).contains(expected) {
201-
eprintln!("=== FILE CONTENTS (LOSSY) ===");
202-
eprintln!("{}", String::from_utf8_lossy(&buffer));
203-
eprintln!("=== SPECIFIED TEXT ===");
204-
eprintln!("{}", expected);
205-
panic!("specified text was not found in file");
206-
}
207-
}
208-
209-
/// Read the contents of a file that cannot simply be read by
210-
/// read_to_string, due to invalid utf8 data, then assert that it does not contain `expected`.
211-
#[track_caller]
212-
pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
213-
let buffer = fs_wrapper::read(path.as_ref());
214-
let expected = expected.as_ref();
215-
if String::from_utf8_lossy(&buffer).contains(expected) {
216-
eprintln!("=== FILE CONTENTS (LOSSY) ===");
217-
eprintln!("{}", String::from_utf8_lossy(&buffer));
218-
eprintln!("=== SPECIFIED TEXT ===");
219-
eprintln!("{}", expected);
220-
panic!("specified text was unexpectedly found in file");
221-
}
222-
}
223-
224140
/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
225141
pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
226142
let dir2 = dir2.as_ref();
@@ -245,45 +161,3 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
245161
}
246162
});
247163
}
248-
249-
/// Check that `actual` is equal to `expected`. Panic otherwise.
250-
#[track_caller]
251-
pub fn assert_equals<S1: AsRef<str>, S2: AsRef<str>>(actual: S1, expected: S2) {
252-
let actual = actual.as_ref();
253-
let expected = expected.as_ref();
254-
if actual != expected {
255-
eprintln!("=== ACTUAL TEXT ===");
256-
eprintln!("{}", actual);
257-
eprintln!("=== EXPECTED ===");
258-
eprintln!("{}", expected);
259-
panic!("expected text was not found in actual text");
260-
}
261-
}
262-
263-
/// Check that `haystack` contains `needle`. Panic otherwise.
264-
#[track_caller]
265-
pub fn assert_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
266-
let haystack = haystack.as_ref();
267-
let needle = needle.as_ref();
268-
if !haystack.contains(needle) {
269-
eprintln!("=== HAYSTACK ===");
270-
eprintln!("{}", haystack);
271-
eprintln!("=== NEEDLE ===");
272-
eprintln!("{}", needle);
273-
panic!("needle was not found in haystack");
274-
}
275-
}
276-
277-
/// Check that `haystack` does not contain `needle`. Panic otherwise.
278-
#[track_caller]
279-
pub fn assert_not_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
280-
let haystack = haystack.as_ref();
281-
let needle = needle.as_ref();
282-
if haystack.contains(needle) {
283-
eprintln!("=== HAYSTACK ===");
284-
eprintln!("{}", haystack);
285-
eprintln!("=== NEEDLE ===");
286-
eprintln!("{}", needle);
287-
panic!("needle was unexpectedly found in haystack");
288-
}
289-
}

0 commit comments

Comments
 (0)