mirror of
https://github.com/uutils/coreutils
synced 2024-07-21 18:04:45 +00:00
Merge pull request #2011 from Gilnaa/master
Add some test utils needed for major test refactoring
This commit is contained in:
commit
c224b955da
|
@ -1,40 +1,3 @@
|
|||
/// Assertion helper macro for [`CmdResult`] types
|
||||
///
|
||||
/// [`CmdResult`]: crate::tests::common::util::CmdResult
|
||||
#[macro_export]
|
||||
macro_rules! assert_empty_stderr(
|
||||
($cond:expr) => (
|
||||
if $cond.stderr.len() > 0 {
|
||||
panic!("stderr: {}", $cond.stderr_str())
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
/// Assertion helper macro for [`CmdResult`] types
|
||||
///
|
||||
/// [`CmdResult`]: crate::tests::common::util::CmdResult
|
||||
#[macro_export]
|
||||
macro_rules! assert_empty_stdout(
|
||||
($cond:expr) => (
|
||||
if $cond.stdout.len() > 0 {
|
||||
panic!("stdout: {}", $cond.stdout_str())
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
/// Assertion helper macro for [`CmdResult`] types
|
||||
///
|
||||
/// [`CmdResult`]: crate::tests::common::util::CmdResult
|
||||
#[macro_export]
|
||||
macro_rules! assert_no_error(
|
||||
($cond:expr) => (
|
||||
assert!($cond.success);
|
||||
if $cond.stderr.len() > 0 {
|
||||
panic!("stderr: {}", $cond.stderr_str())
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
/// Platform-independent helper for constructing a PathBuf from individual elements
|
||||
#[macro_export]
|
||||
macro_rules! path_concat {
|
||||
|
|
|
@ -64,7 +64,7 @@ fn read_scenario_fixture<S: AsRef<OsStr>>(tmpd: &Option<Rc<TempDir>>, file_rel_p
|
|||
|
||||
/// A command result is the outputs of a command (streams and status code)
|
||||
/// within a struct which has convenience assertion functions about those outputs
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CmdResult {
|
||||
//tmpd is used for convenience functions for asserts against fixtures
|
||||
tmpd: Option<Rc<TempDir>>,
|
||||
|
@ -130,6 +130,11 @@ impl CmdResult {
|
|||
self.code.expect("Program must be run first")
|
||||
}
|
||||
|
||||
pub fn code_is(&self, expected_code: i32) -> &CmdResult {
|
||||
assert_eq!(self.code(), expected_code);
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns the program's TempDir
|
||||
/// Panics if not present
|
||||
pub fn tmpd(&self) -> Rc<TempDir> {
|
||||
|
@ -146,13 +151,25 @@ impl CmdResult {
|
|||
|
||||
/// asserts that the command resulted in a success (zero) status code
|
||||
pub fn success(&self) -> &CmdResult {
|
||||
assert!(self.success);
|
||||
if !self.success {
|
||||
panic!(
|
||||
"Command was expected to succeed.\nstdout = {}\n stderr = {}",
|
||||
self.stdout_str(),
|
||||
self.stderr_str()
|
||||
);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// asserts that the command resulted in a failure (non-zero) status code
|
||||
pub fn failure(&self) -> &CmdResult {
|
||||
assert!(!self.success);
|
||||
if self.success {
|
||||
panic!(
|
||||
"Command was expected to fail.\nstdout = {}\n stderr = {}",
|
||||
self.stdout_str(),
|
||||
self.stderr_str()
|
||||
);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -168,7 +185,12 @@ impl CmdResult {
|
|||
/// 1. you can not know exactly what stdout will be or
|
||||
/// 2. you know that stdout will also be empty
|
||||
pub fn no_stderr(&self) -> &CmdResult {
|
||||
assert!(self.stderr.is_empty());
|
||||
if !self.stderr.is_empty() {
|
||||
panic!(
|
||||
"Expected stderr to be empty, but it's:\n{}",
|
||||
self.stderr_str()
|
||||
);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -179,7 +201,12 @@ impl CmdResult {
|
|||
/// 1. you can not know exactly what stderr will be or
|
||||
/// 2. you know that stderr will also be empty
|
||||
pub fn no_stdout(&self) -> &CmdResult {
|
||||
assert!(self.stdout.is_empty());
|
||||
if !self.stdout.is_empty() {
|
||||
panic!(
|
||||
"Expected stdout to be empty, but it's:\n{}",
|
||||
self.stderr_str()
|
||||
);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -277,10 +304,34 @@ impl CmdResult {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn stderr_contains<T: AsRef<str>>(&self, cmp: &T) -> &CmdResult {
|
||||
pub fn stderr_contains<T: AsRef<str>>(&self, cmp: T) -> &CmdResult {
|
||||
assert!(self.stderr_str().contains(cmp.as_ref()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn stdout_does_not_contain<T: AsRef<str>>(&self, cmp: T) -> &CmdResult {
|
||||
assert!(!self.stdout_str().contains(cmp.as_ref()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn stderr_does_not_contain<T: AsRef<str>>(&self, cmp: T) -> &CmdResult {
|
||||
assert!(!self.stderr_str().contains(cmp.as_ref()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn stdout_matches(&self, regex: ®ex::Regex) -> &CmdResult {
|
||||
if !regex.is_match(self.stdout_str()) {
|
||||
panic!("Stdout does not match regex:\n{}", self.stdout_str())
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn stdout_does_not_match(&self, regex: ®ex::Regex) -> &CmdResult {
|
||||
if regex.is_match(self.stdout_str()) {
|
||||
panic!("Stdout matches regex:\n{}", self.stdout_str())
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn log_info<T: AsRef<str>, U: AsRef<str>>(msg: T, par: U) {
|
||||
|
@ -819,3 +870,211 @@ pub fn vec_of_size(n: usize) -> Vec<u8> {
|
|||
assert_eq!(result.len(), n);
|
||||
result
|
||||
}
|
||||
|
||||
/// Sanity checks for test utils
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_code_is() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: Some(32),
|
||||
success: false,
|
||||
stdout: "".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
res.code_is(32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_code_is_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: Some(32),
|
||||
success: false,
|
||||
stdout: "".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
res.code_is(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_failure() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: false,
|
||||
stdout: "".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
res.failure();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_failure_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
res.failure();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_success() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
res.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_success_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: false,
|
||||
stdout: "".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
res.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_std_errout() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
res.no_stderr();
|
||||
res.no_stdout();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_no_stderr_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "".into(),
|
||||
stderr: "asdfsadfa".into(),
|
||||
};
|
||||
|
||||
res.no_stderr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_no_stdout_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "asdfsadfa".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
|
||||
res.no_stdout();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_std_does_not_contain() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "This is a likely error message\n".into(),
|
||||
stderr: "This is a likely error message\n".into(),
|
||||
};
|
||||
res.stdout_does_not_contain("unlikely");
|
||||
res.stderr_does_not_contain("unlikely");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_stdout_does_not_contain_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "This is a likely error message\n".into(),
|
||||
stderr: "".into(),
|
||||
};
|
||||
|
||||
res.stdout_does_not_contain("likely");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_stderr_does_not_contain_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "".into(),
|
||||
stderr: "This is a likely error message\n".into(),
|
||||
};
|
||||
|
||||
res.stderr_does_not_contain("likely");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdout_matches() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "This is a likely error message\n".into(),
|
||||
stderr: "This is a likely error message\n".into(),
|
||||
};
|
||||
let positive = regex::Regex::new(".*likely.*").unwrap();
|
||||
let negative = regex::Regex::new(".*unlikely.*").unwrap();
|
||||
res.stdout_matches(&positive);
|
||||
res.stdout_does_not_match(&negative);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_stdout_matches_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "This is a likely error message\n".into(),
|
||||
stderr: "This is a likely error message\n".into(),
|
||||
};
|
||||
let negative = regex::Regex::new(".*unlikely.*").unwrap();
|
||||
|
||||
res.stdout_matches(&negative);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_stdout_not_matches_fail() {
|
||||
let res = CmdResult {
|
||||
tmpd: None,
|
||||
code: None,
|
||||
success: true,
|
||||
stdout: "This is a likely error message\n".into(),
|
||||
stderr: "This is a likely error message\n".into(),
|
||||
};
|
||||
let positive = regex::Regex::new(".*likely.*").unwrap();
|
||||
|
||||
res.stdout_does_not_match(&positive);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue