Skip to content

Commit 96a6037

Browse files
committed
run-make-support: adjust assertion printing, add some basic sanity checks
1 parent bf6f8a4 commit 96a6037

File tree

3 files changed

+261
-107
lines changed

3 files changed

+261
-107
lines changed

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

-107
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
//! Collection of assertions and assertion-related helpers.
2+
3+
#[cfg(test)]
4+
mod tests;
5+
6+
use std::panic;
7+
use std::path::Path;
8+
9+
use crate::{fs, regex};
10+
11+
/// Assert that `actual` is equal to `expected`.
12+
#[track_caller]
13+
pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) {
14+
let actual = actual.as_ref();
15+
let expected = expected.as_ref();
16+
17+
if actual != expected {
18+
eprintln!("=== ACTUAL TEXT ===");
19+
eprintln!("{}", actual);
20+
eprintln!("=== EXPECTED ===");
21+
eprintln!("{}", expected);
22+
panic!("expected text does not match actual text");
23+
}
24+
}
25+
26+
struct SearchDetails<'assertion_name, 'haystack, 'query> {
27+
assertion_name: &'assertion_name str,
28+
haystack: &'haystack str,
29+
query_kind: &'static str,
30+
query: &'query str,
31+
}
32+
33+
impl<'assertion_name, 'haystack, 'query> SearchDetails<'assertion_name, 'haystack, 'query> {
34+
fn dump(&self) {
35+
eprintln!("{}:", self.assertion_name);
36+
eprintln!("=== HAYSTACK ===");
37+
eprintln!("{}", self.haystack);
38+
eprintln!("=== {} ===", self.query_kind);
39+
eprintln!("{}", self.query);
40+
}
41+
}
42+
43+
/// Assert that `haystack` contains `needle`.
44+
#[track_caller]
45+
pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
46+
let haystack = haystack.as_ref();
47+
let needle = needle.as_ref();
48+
if !haystack.contains(needle) {
49+
SearchDetails {
50+
assertion_name: "assert_contains",
51+
haystack,
52+
query_kind: "NEEDLE",
53+
query: needle,
54+
}
55+
.dump();
56+
panic!("needle was not found in haystack");
57+
}
58+
}
59+
60+
/// Assert that `haystack` does not contain `needle`.
61+
#[track_caller]
62+
pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
63+
let haystack = haystack.as_ref();
64+
let needle = needle.as_ref();
65+
if haystack.contains(needle) {
66+
SearchDetails {
67+
assertion_name: "assert_not_contains",
68+
haystack,
69+
query_kind: "NEEDLE",
70+
query: needle,
71+
}
72+
.dump();
73+
panic!("needle was unexpectedly found in haystack");
74+
}
75+
}
76+
77+
/// Assert that `haystack` contains the regex `pattern`.
78+
#[track_caller]
79+
pub fn assert_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, pattern: N) {
80+
let haystack = haystack.as_ref();
81+
let pattern = pattern.as_ref();
82+
let re = regex::Regex::new(pattern).unwrap();
83+
if !re.is_match(haystack) {
84+
SearchDetails {
85+
assertion_name: "assert_contains_regex",
86+
haystack,
87+
query_kind: "REGEX",
88+
query: pattern,
89+
}
90+
.dump();
91+
panic!("regex was not found in haystack");
92+
}
93+
}
94+
95+
/// Assert that `haystack` does not contain the regex `pattern`.
96+
#[track_caller]
97+
pub fn assert_not_contains_regex<H: AsRef<str>, N: AsRef<str>>(haystack: H, pattern: N) {
98+
let haystack = haystack.as_ref();
99+
let pattern = pattern.as_ref();
100+
let re = regex::Regex::new(pattern).unwrap();
101+
if re.is_match(haystack) {
102+
SearchDetails {
103+
assertion_name: "assert_not_contains_regex",
104+
haystack,
105+
query_kind: "REGEX",
106+
query: pattern,
107+
}
108+
.dump();
109+
panic!("regex was unexpectedly found in haystack");
110+
}
111+
}
112+
113+
/// Assert that `haystack` contains regex `pattern` an `expected_count` number of times.
114+
#[track_caller]
115+
pub fn assert_count_is<H: AsRef<str>, N: AsRef<str>>(
116+
expected_count: usize,
117+
haystack: H,
118+
pattern: N,
119+
) {
120+
let haystack = haystack.as_ref();
121+
let pattern = pattern.as_ref();
122+
123+
let actual_count = haystack.matches(pattern).count();
124+
if expected_count != actual_count {
125+
let count_fmt = format!(
126+
"assert_count_is (expected_count = {expected_count}, actual_count = {actual_count})"
127+
);
128+
SearchDetails { assertion_name: &count_fmt, haystack, query_kind: "REGEX", query: pattern }
129+
.dump();
130+
panic!(
131+
"regex did not appear {expected_count} times in haystack (expected_count = \
132+
{expected_count}, actual_count = {actual_count})"
133+
);
134+
}
135+
}
136+
137+
/// Assert that all files in `dir1` exist and have the same content in `dir2`
138+
pub fn assert_dirs_are_equal(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
139+
let dir2 = dir2.as_ref();
140+
fs::read_dir_entries(dir1, |entry_path| {
141+
let entry_name = entry_path.file_name().unwrap();
142+
if entry_path.is_dir() {
143+
assert_dirs_are_equal(&entry_path, &dir2.join(entry_name));
144+
} else {
145+
let path2 = dir2.join(entry_name);
146+
let file1 = fs::read(&entry_path);
147+
let file2 = fs::read(&path2);
148+
149+
// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
150+
// Why not using String? Because there might be minified files or even potentially
151+
// binary ones, so that would display useless output.
152+
assert!(
153+
file1 == file2,
154+
"`{}` and `{}` have different content",
155+
entry_path.display(),
156+
path2.display(),
157+
);
158+
}
159+
});
160+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//! Basic sanity checks for assertion helpers.
2+
3+
use super::*;
4+
5+
mod test_assert_equals {
6+
use super::*;
7+
8+
#[test]
9+
fn assert_equals_same() {
10+
assert_equals("foo", "foo");
11+
assert_equals("", "");
12+
}
13+
14+
#[test]
15+
#[should_panic]
16+
fn assert_equals_different() {
17+
assert_equals("foo", "bar");
18+
}
19+
}
20+
21+
mod test_assert_contains {
22+
use super::*;
23+
24+
#[test]
25+
fn assert_contains_yes() {
26+
assert_contains("", "");
27+
assert_contains(" ", "");
28+
assert_contains("a", "a");
29+
assert_contains("ab", "a");
30+
}
31+
32+
#[test]
33+
#[should_panic]
34+
fn assert_contains_no() {
35+
assert_contains("a", "b");
36+
}
37+
}
38+
39+
mod test_assert_not_contains {
40+
use super::*;
41+
42+
#[test]
43+
fn assert_not_contains_yes() {
44+
assert_not_contains("a", "b");
45+
}
46+
47+
#[test]
48+
#[should_panic]
49+
fn assert_not_contains_no() {
50+
assert_not_contains(" ", "");
51+
}
52+
}
53+
54+
mod assert_contains_regex {
55+
use super::*;
56+
57+
#[test]
58+
fn assert_contains_regex_yes() {
59+
assert_contains_regex("", "");
60+
assert_contains_regex("", ".*");
61+
assert_contains_regex("abcde", ".*");
62+
assert_contains_regex("abcde", ".+");
63+
}
64+
65+
#[test]
66+
#[should_panic]
67+
fn assert_contains_regex_no() {
68+
assert_contains_regex("", ".+");
69+
}
70+
}
71+
72+
mod assert_not_contains_regex_regex {
73+
use super::*;
74+
75+
#[test]
76+
fn assert_not_contains_regex_yes() {
77+
assert_not_contains_regex("abc", "d");
78+
}
79+
80+
#[test]
81+
#[should_panic]
82+
fn assert_not_contains_regex_no() {
83+
assert_not_contains_regex("abc", ".*");
84+
}
85+
}
86+
87+
mod test_assert_count_is {
88+
use super::*;
89+
90+
#[test]
91+
fn assert_count_is_yes() {
92+
assert_count_is(0, "", "b");
93+
assert_count_is(3, "abcbdb", "b");
94+
}
95+
96+
#[test]
97+
#[should_panic]
98+
fn assert_count_is_no() {
99+
assert_count_is(2, "abcbdb", "b");
100+
}
101+
}

0 commit comments

Comments
 (0)