run_make_support: move assertions and helpers into own module
This commit is contained in:
parent
66cef19d11
commit
f66d3d33e4
142
src/tools/run-make-support/src/assertion_helpers.rs
Normal file
142
src/tools/run-make-support/src/assertion_helpers.rs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
//! Collection of assertions and assertion-related helpers.
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::panic;
|
||||||
|
|
||||||
|
use crate::fs_wrapper;
|
||||||
|
use crate::path_helpers::cwd;
|
||||||
|
|
||||||
|
/// Browse the directory `path` non-recursively and return all files which respect the parameters
|
||||||
|
/// outlined by `closure`.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
|
||||||
|
path: P,
|
||||||
|
filter: F,
|
||||||
|
) -> Vec<PathBuf> {
|
||||||
|
let mut matching_files = Vec::new();
|
||||||
|
for entry in fs_wrapper::read_dir(path) {
|
||||||
|
let entry = entry.expect("failed to read directory entry.");
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
|
if path.is_file() && filter(&path) {
|
||||||
|
matching_files.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matching_files
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` starts with `prefix`.
|
||||||
|
pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
|
||||||
|
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` has the extension `extension`.
|
||||||
|
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
|
||||||
|
path.as_ref().extension().is_some_and(|ext| ext == extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` does not contain `expected`.
|
||||||
|
pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
|
||||||
|
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` is not in `expected`.
|
||||||
|
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
|
||||||
|
let expected = expected.as_ref();
|
||||||
|
path.as_ref()
|
||||||
|
.file_name()
|
||||||
|
.is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the filename at `path` ends with `suffix`.
|
||||||
|
pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
|
||||||
|
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gathers all files in the current working directory that have the extension `ext`, and counts
|
||||||
|
/// the number of lines within that contain a match with the regex pattern `re`.
|
||||||
|
pub fn count_regex_matches_in_files_with_extension(re: ®ex::Regex, ext: &str) -> usize {
|
||||||
|
let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
for file in fetched_files {
|
||||||
|
let content = fs_wrapper::read_to_string(file);
|
||||||
|
count += content.lines().filter(|line| re.is_match(&line)).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the contents of a file that cannot simply be read by
|
||||||
|
/// [`read_to_string`][crate::fs_wrapper::read_to_string], due to invalid UTF-8 data, then assert
|
||||||
|
/// that it contains `expected`.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
||||||
|
let buffer = fs_wrapper::read(path.as_ref());
|
||||||
|
let expected = expected.as_ref();
|
||||||
|
if !String::from_utf8_lossy(&buffer).contains(expected) {
|
||||||
|
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||||
|
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
||||||
|
eprintln!("=== SPECIFIED TEXT ===");
|
||||||
|
eprintln!("{}", expected);
|
||||||
|
panic!("specified text was not found in file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the contents of a file that cannot simply be read by
|
||||||
|
/// [`read_to_string`][crate::fs_wrapper::read_to_string], due to invalid UTF-8 data, then assert
|
||||||
|
/// that it does not contain `expected`.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
||||||
|
let buffer = fs_wrapper::read(path.as_ref());
|
||||||
|
let expected = expected.as_ref();
|
||||||
|
if String::from_utf8_lossy(&buffer).contains(expected) {
|
||||||
|
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||||
|
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
||||||
|
eprintln!("=== SPECIFIED TEXT ===");
|
||||||
|
eprintln!("{}", expected);
|
||||||
|
panic!("specified text was unexpectedly found in file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assert that `actual` is equal to `expected`.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) {
|
||||||
|
let actual = actual.as_ref();
|
||||||
|
let expected = expected.as_ref();
|
||||||
|
if actual != expected {
|
||||||
|
eprintln!("=== ACTUAL TEXT ===");
|
||||||
|
eprintln!("{}", actual);
|
||||||
|
eprintln!("=== EXPECTED ===");
|
||||||
|
eprintln!("{}", expected);
|
||||||
|
panic!("expected text was not found in actual text");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assert that `haystack` contains `needle`.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
|
||||||
|
let haystack = haystack.as_ref();
|
||||||
|
let needle = needle.as_ref();
|
||||||
|
if !haystack.contains(needle) {
|
||||||
|
eprintln!("=== HAYSTACK ===");
|
||||||
|
eprintln!("{}", haystack);
|
||||||
|
eprintln!("=== NEEDLE ===");
|
||||||
|
eprintln!("{}", needle);
|
||||||
|
panic!("needle was not found in haystack");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assert that `haystack` does not contain `needle`.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
|
||||||
|
let haystack = haystack.as_ref();
|
||||||
|
let needle = needle.as_ref();
|
||||||
|
if haystack.contains(needle) {
|
||||||
|
eprintln!("=== HAYSTACK ===");
|
||||||
|
eprintln!("{}", haystack);
|
||||||
|
eprintln!("=== NEEDLE ===");
|
||||||
|
eprintln!("{}", needle);
|
||||||
|
panic!("needle was unexpectedly found in haystack");
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
pub mod ar;
|
pub mod ar;
|
||||||
pub mod artifact_names;
|
pub mod artifact_names;
|
||||||
|
pub mod assertion_helpers;
|
||||||
pub mod diff;
|
pub mod diff;
|
||||||
pub mod env_checked;
|
pub mod env_checked;
|
||||||
pub mod external_deps;
|
pub mod external_deps;
|
||||||
@ -18,7 +19,6 @@
|
|||||||
pub mod scoped_run;
|
pub mod scoped_run;
|
||||||
pub mod targets;
|
pub mod targets;
|
||||||
|
|
||||||
use std::panic;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
// Re-exports of third-party library crates.
|
// Re-exports of third-party library crates.
|
||||||
@ -77,42 +77,15 @@
|
|||||||
/// Helpers for scoped test execution where certain properties are attempted to be maintained.
|
/// Helpers for scoped test execution where certain properties are attempted to be maintained.
|
||||||
pub use scoped_run::{run_in_tmpdir, test_while_readonly};
|
pub use scoped_run::{run_in_tmpdir, test_while_readonly};
|
||||||
|
|
||||||
|
pub use assertion_helpers::{
|
||||||
|
assert_contains, assert_equals, assert_not_contains,
|
||||||
|
count_regex_matches_in_files_with_extension, filename_not_in_denylist, has_extension,
|
||||||
|
has_prefix, has_suffix, invalid_utf8_contains, invalid_utf8_not_contains, not_contains,
|
||||||
|
shallow_find_files,
|
||||||
|
};
|
||||||
|
|
||||||
use command::{Command, CompletedProcess};
|
use command::{Command, CompletedProcess};
|
||||||
|
|
||||||
/// Browse the directory `path` non-recursively and return all files which respect the parameters
|
|
||||||
/// outlined by `closure`.
|
|
||||||
#[track_caller]
|
|
||||||
pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
|
|
||||||
path: P,
|
|
||||||
filter: F,
|
|
||||||
) -> Vec<PathBuf> {
|
|
||||||
let mut matching_files = Vec::new();
|
|
||||||
for entry in fs_wrapper::read_dir(path) {
|
|
||||||
let entry = entry.expect("failed to read directory entry.");
|
|
||||||
let path = entry.path();
|
|
||||||
|
|
||||||
if path.is_file() && filter(&path) {
|
|
||||||
matching_files.push(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matching_files
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the filename at `path` starts with `prefix`.
|
|
||||||
pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
|
|
||||||
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the filename at `path` has the extension `extension`.
|
|
||||||
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
|
|
||||||
path.as_ref().extension().is_some_and(|ext| ext == extension)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the filename at `path` does not contain `expected`.
|
|
||||||
pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
|
|
||||||
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
|
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
|
||||||
@ -133,33 +106,6 @@ pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
|
|||||||
path(lib_path)
|
path(lib_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the filename at `path` is not in `expected`.
|
|
||||||
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
|
|
||||||
let expected = expected.as_ref();
|
|
||||||
path.as_ref()
|
|
||||||
.file_name()
|
|
||||||
.is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the filename at `path` ends with `suffix`.
|
|
||||||
pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
|
|
||||||
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gathers all files in the current working directory that have the extension `ext`, and counts
|
|
||||||
/// the number of lines within that contain a match with the regex pattern `re`.
|
|
||||||
pub fn count_regex_matches_in_files_with_extension(re: ®ex::Regex, ext: &str) -> usize {
|
|
||||||
let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
|
|
||||||
|
|
||||||
let mut count = 0;
|
|
||||||
for file in fetched_files {
|
|
||||||
let content = fs_wrapper::read_to_string(file);
|
|
||||||
count += content.lines().filter(|line| re.is_match(&line)).count();
|
|
||||||
}
|
|
||||||
|
|
||||||
count
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn handle_failed_output(
|
pub(crate) fn handle_failed_output(
|
||||||
cmd: &Command,
|
cmd: &Command,
|
||||||
output: CompletedProcess,
|
output: CompletedProcess,
|
||||||
@ -191,36 +137,6 @@ pub fn set_host_rpath(cmd: &mut Command) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the contents of a file that cannot simply be read by
|
|
||||||
/// read_to_string, due to invalid utf8 data, then assert that it contains `expected`.
|
|
||||||
#[track_caller]
|
|
||||||
pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
|
||||||
let buffer = fs_wrapper::read(path.as_ref());
|
|
||||||
let expected = expected.as_ref();
|
|
||||||
if !String::from_utf8_lossy(&buffer).contains(expected) {
|
|
||||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
|
||||||
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
|
||||||
eprintln!("=== SPECIFIED TEXT ===");
|
|
||||||
eprintln!("{}", expected);
|
|
||||||
panic!("specified text was not found in file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read the contents of a file that cannot simply be read by
|
|
||||||
/// read_to_string, due to invalid utf8 data, then assert that it does not contain `expected`.
|
|
||||||
#[track_caller]
|
|
||||||
pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
|
||||||
let buffer = fs_wrapper::read(path.as_ref());
|
|
||||||
let expected = expected.as_ref();
|
|
||||||
if String::from_utf8_lossy(&buffer).contains(expected) {
|
|
||||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
|
||||||
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
|
||||||
eprintln!("=== SPECIFIED TEXT ===");
|
|
||||||
eprintln!("{}", expected);
|
|
||||||
panic!("specified text was unexpectedly found in file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
|
/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
|
||||||
pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
|
pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
|
||||||
let dir2 = dir2.as_ref();
|
let dir2 = dir2.as_ref();
|
||||||
@ -245,45 +161,3 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that `actual` is equal to `expected`. Panic otherwise.
|
|
||||||
#[track_caller]
|
|
||||||
pub fn assert_equals<S1: AsRef<str>, S2: AsRef<str>>(actual: S1, expected: S2) {
|
|
||||||
let actual = actual.as_ref();
|
|
||||||
let expected = expected.as_ref();
|
|
||||||
if actual != expected {
|
|
||||||
eprintln!("=== ACTUAL TEXT ===");
|
|
||||||
eprintln!("{}", actual);
|
|
||||||
eprintln!("=== EXPECTED ===");
|
|
||||||
eprintln!("{}", expected);
|
|
||||||
panic!("expected text was not found in actual text");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that `haystack` contains `needle`. Panic otherwise.
|
|
||||||
#[track_caller]
|
|
||||||
pub fn assert_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
|
|
||||||
let haystack = haystack.as_ref();
|
|
||||||
let needle = needle.as_ref();
|
|
||||||
if !haystack.contains(needle) {
|
|
||||||
eprintln!("=== HAYSTACK ===");
|
|
||||||
eprintln!("{}", haystack);
|
|
||||||
eprintln!("=== NEEDLE ===");
|
|
||||||
eprintln!("{}", needle);
|
|
||||||
panic!("needle was not found in haystack");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that `haystack` does not contain `needle`. Panic otherwise.
|
|
||||||
#[track_caller]
|
|
||||||
pub fn assert_not_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
|
|
||||||
let haystack = haystack.as_ref();
|
|
||||||
let needle = needle.as_ref();
|
|
||||||
if haystack.contains(needle) {
|
|
||||||
eprintln!("=== HAYSTACK ===");
|
|
||||||
eprintln!("{}", haystack);
|
|
||||||
eprintln!("=== NEEDLE ===");
|
|
||||||
eprintln!("{}", needle);
|
|
||||||
panic!("needle was unexpectedly found in haystack");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user