1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #4252 from tertsdiepraam/track_caller

Put `#[track_caller]` on assertion functions in test utils
This commit is contained in:
Sylvestre Ledru 2023-01-02 09:58:15 +01:00 committed by GitHub
commit 75cf8ce6cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 106 deletions

View file

@ -2277,7 +2277,7 @@ fn test_copy_dir_preserve_permissions_inaccessible_file() {
// V V V V
ucmd.args(&["-p", "-R", "d1", "d2"])
.fails()
.status_code(1)
.code_is(1)
.stderr_only("cp: cannot open 'd1/f' for reading: Permission denied");
assert!(at.dir_exists("d2"));
assert!(!at.file_exists("d2/f"));

View file

@ -461,7 +461,7 @@ fn test_oversized_bs_32_bit() {
.run()
.no_stdout()
.failure()
.status_code(1)
.code_is(1)
.stderr_is(format!("dd: {}=N cannot fit into memory\n", bs_param));
}
}

View file

@ -5,25 +5,21 @@ use crate::common::util::*;
#[test]
fn test_simple_values() {
// null or 0 => EXIT_VALUE == 1
new_ucmd!()
.args(&[""])
.fails()
.status_code(1)
.stdout_only("\n");
new_ucmd!().args(&[""]).fails().code_is(1).stdout_only("\n");
new_ucmd!()
.args(&["0"])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("0\n");
new_ucmd!()
.args(&["00"])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("00\n");
new_ucmd!()
.args(&["-0"])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("-0\n");
// non-null and non-0 => EXIT_VALUE = 0
@ -40,7 +36,7 @@ fn test_simple_arithmetic() {
new_ucmd!()
.args(&["1", "-", "1"])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("0\n");
new_ucmd!()
@ -130,7 +126,7 @@ fn test_index() {
new_ucmd!()
.args(&["index", "αbcdef", "x"])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("0\n");
new_ucmd!()
.args(&["index", "αbcdef", "α"])
@ -213,18 +209,18 @@ fn test_invalid_substr() {
new_ucmd!()
.args(&["substr", "abc", "0", "1"])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("\n");
new_ucmd!()
.args(&["substr", "abc", &(std::usize::MAX.to_string() + "0"), "1"])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("\n");
new_ucmd!()
.args(&["substr", "abc", "0", &(std::usize::MAX.to_string() + "0")])
.fails()
.status_code(1)
.code_is(1)
.stdout_only("\n");
}

View file

@ -77,14 +77,14 @@ fn test_mknod_character_device_requires_major_and_minor() {
.arg("test_file")
.arg("c")
.fails()
.status_code(1)
.code_is(1)
.stderr_contains("Special files require major and minor device numbers.");
new_ucmd!()
.arg("test_file")
.arg("c")
.arg("1")
.fails()
.status_code(1)
.code_is(1)
.stderr_contains("Special files require major and minor device numbers.");
new_ucmd!()
.arg("test_file")
@ -122,6 +122,6 @@ fn test_mknod_invalid_mode() {
.arg("p")
.fails()
.no_stdout()
.status_code(1)
.code_is(1)
.stderr_contains("invalid mode");
}

View file

@ -844,7 +844,7 @@ fn test_nonexistent_file() {
new_ucmd!()
.arg("nonexistent.txt")
.fails()
.status_code(2)
.code_is(2)
.stderr_only(
#[cfg(not(windows))]
"sort: cannot read: nonexistent.txt: No such file or directory",
@ -1015,7 +1015,7 @@ fn test_verifies_out_file() {
.pipe_in(input)
.ignore_stdin_write_error()
.fails()
.status_code(2)
.code_is(2)
.stderr_only(
#[cfg(not(windows))]
"sort: open failed: nonexistent_dir/nonexistent_file: No such file or directory",
@ -1036,7 +1036,7 @@ fn test_verifies_files_after_keys() {
"nonexistent_dir/input_file",
])
.fails()
.status_code(2)
.code_is(2)
.stderr_contains("failed to parse key");
}
@ -1046,7 +1046,7 @@ fn test_verifies_input_files() {
new_ucmd!()
.args(&["/dev/random", "nonexistent_file"])
.fails()
.status_code(2)
.code_is(2)
.stderr_is("sort: cannot read: nonexistent_file: No such file or directory");
}
@ -1104,7 +1104,7 @@ fn test_wrong_args_exit_code() {
new_ucmd!()
.arg("--misspelled")
.fails()
.status_code(2)
.code_is(2)
.stderr_contains("--misspelled");
}

View file

@ -15,12 +15,12 @@ use std::thread::sleep;
#[test]
fn test_empty_test_equivalent_to_false() {
new_ucmd!().run().status_code(1);
new_ucmd!().run().code_is(1);
}
#[test]
fn test_empty_string_is_false() {
new_ucmd!().arg("").run().status_code(1);
new_ucmd!().arg("").run().code_is(1);
}
#[test]
@ -61,24 +61,24 @@ fn test_some_literals() {
// run the inverse of all these tests
for test in &tests {
scenario.ucmd().arg("!").arg(test).run().status_code(1);
scenario.ucmd().arg("!").arg(test).run().code_is(1);
}
}
#[test]
fn test_double_not_is_false() {
new_ucmd!().args(&["!", "!"]).run().status_code(1);
new_ucmd!().args(&["!", "!"]).run().code_is(1);
}
#[test]
fn test_and_not_is_false() {
new_ucmd!().args(&["-a", "!"]).run().status_code(1);
new_ucmd!().args(&["-a", "!"]).run().code_is(1);
}
#[test]
fn test_not_and_is_false() {
// `-a` is a literal here & has nonzero length
new_ucmd!().args(&["!", "-a"]).run().status_code(1);
new_ucmd!().args(&["!", "-a"]).run().code_is(1);
}
#[test]
@ -96,12 +96,12 @@ fn test_negated_or() {
new_ucmd!()
.args(&["!", "foo", "-o", "bar"])
.run()
.status_code(1);
.code_is(1);
new_ucmd!().args(&["foo", "-o", "!", "bar"]).succeeds();
new_ucmd!()
.args(&["!", "foo", "-o", "!", "bar"])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -112,10 +112,10 @@ fn test_string_length_of_nothing() {
#[test]
fn test_string_length_of_empty() {
new_ucmd!().args(&["-n", ""]).run().status_code(1);
new_ucmd!().args(&["-n", ""]).run().code_is(1);
// STRING equivalent to -n STRING
new_ucmd!().arg("").run().status_code(1);
new_ucmd!().arg("").run().code_is(1);
}
#[test]
@ -136,14 +136,14 @@ fn test_zero_len_equals_zero_len() {
#[test]
fn test_zero_len_not_equals_zero_len_is_false() {
new_ucmd!().args(&["", "!=", ""]).run().status_code(1);
new_ucmd!().args(&["", "!=", ""]).run().code_is(1);
}
#[test]
fn test_double_equal_is_string_comparison_op() {
// undocumented but part of the GNU test suite
new_ucmd!().args(&["t", "==", "t"]).succeeds();
new_ucmd!().args(&["t", "==", "f"]).run().status_code(1);
new_ucmd!().args(&["t", "==", "f"]).run().code_is(1);
}
#[test]
@ -165,12 +165,7 @@ fn test_string_comparison() {
// run the inverse of all these tests
for test in &tests {
scenario
.ucmd()
.arg("!")
.args(&test[..])
.run()
.status_code(1);
scenario.ucmd().arg("!").args(&test[..]).run().code_is(1);
}
}
@ -180,7 +175,7 @@ fn test_dangling_string_comparison_is_error() {
new_ucmd!()
.args(&["missing_something", "="])
.run()
.status_code(2)
.code_is(2)
.stderr_is("test: missing argument after '='");
}
@ -202,7 +197,7 @@ fn test_string_operator_is_literal_after_bang() {
];
for test in &tests {
scenario.ucmd().args(&test[..]).run().status_code(1);
scenario.ucmd().args(&test[..]).run().code_is(1);
}
}
@ -251,12 +246,7 @@ fn test_some_int_compares() {
// run the inverse of all these tests
for test in &tests {
scenario
.ucmd()
.arg("!")
.args(&test[..])
.run()
.status_code(1);
scenario.ucmd().arg("!").args(&test[..]).run().code_is(1);
}
}
@ -288,12 +278,7 @@ fn test_negative_int_compare() {
// run the inverse of all these tests
for test in &tests {
scenario
.ucmd()
.arg("!")
.args(&test[..])
.run()
.status_code(1);
scenario.ucmd().arg("!").args(&test[..]).run().code_is(1);
}
}
@ -302,7 +287,7 @@ fn test_float_inequality_is_error() {
new_ucmd!()
.args(&["123.45", "-ge", "6"])
.run()
.status_code(2)
.code_is(2)
.stderr_is("test: invalid integer '123.45'");
}
@ -320,7 +305,7 @@ fn test_invalid_utf8_integer_compare() {
cmd.raw.arg(arg);
cmd.run()
.status_code(2)
.code_is(2)
.stderr_is("test: invalid integer $'fo\\x80o'");
let mut cmd = new_ucmd!();
@ -328,7 +313,7 @@ fn test_invalid_utf8_integer_compare() {
cmd.arg("-eq").arg("456");
cmd.run()
.status_code(2)
.code_is(2)
.stderr_is("test: invalid integer $'fo\\x80o'");
}
@ -347,11 +332,11 @@ fn test_file_is_newer_than_and_older_than_itself() {
new_ucmd!()
.args(&["regular_file", "-nt", "regular_file"])
.run()
.status_code(1);
.code_is(1);
new_ucmd!()
.args(&["regular_file", "-ot", "regular_file"])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -417,7 +402,7 @@ fn test_nonexistent_file_does_not_exist() {
new_ucmd!()
.args(&["-e", "nonexistent_file"])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -425,7 +410,7 @@ fn test_nonexistent_file_is_not_regular() {
new_ucmd!()
.args(&["-f", "nonexistent_file"])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -517,7 +502,7 @@ fn test_nonexistent_file_size_test_is_false() {
new_ucmd!()
.args(&["-s", "nonexistent_file"])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -583,15 +568,12 @@ fn test_file_is_sticky() {
#[test]
fn test_file_is_not_sticky() {
new_ucmd!()
.args(&["-k", "regular_file"])
.run()
.status_code(1);
new_ucmd!().args(&["-k", "regular_file"]).run().code_is(1);
}
#[test]
fn test_solo_empty_parenthetical_is_error() {
new_ucmd!().args(&["(", ")"]).run().status_code(2);
new_ucmd!().args(&["(", ")"]).run().code_is(2);
}
#[test]
@ -630,7 +612,7 @@ fn test_parenthesized_literal() {
.arg(test)
.arg(")")
.run()
.status_code(1);
.code_is(1);
}
}
@ -638,7 +620,7 @@ fn test_parenthesized_literal() {
fn test_parenthesized_op_compares_literal_parenthesis() {
// ensure we arent treating this case as “string length of literal equal
// sign”
new_ucmd!().args(&["(", "=", ")"]).run().status_code(1);
new_ucmd!().args(&["(", "=", ")"]).run().code_is(1);
}
#[test]
@ -659,21 +641,13 @@ fn test_parenthesized_string_comparison() {
// run the inverse of all these tests
for test in &tests {
scenario
.ucmd()
.arg("!")
.args(&test[..])
.run()
.status_code(1);
scenario.ucmd().arg("!").args(&test[..]).run().code_is(1);
}
}
#[test]
fn test_parenthesized_right_parenthesis_as_literal() {
new_ucmd!()
.args(&["(", "-f", ")", ")"])
.run()
.status_code(1);
new_ucmd!().args(&["(", "-f", ")", ")"]).run().code_is(1);
}
#[test]
@ -688,7 +662,7 @@ fn test_nonexistent_file_not_owned_by_euid() {
new_ucmd!()
.args(&["-O", "nonexistent_file"])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -711,7 +685,7 @@ fn test_nonexistent_file_not_owned_by_egid() {
new_ucmd!()
.args(&["-G", "nonexistent_file"])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -732,7 +706,7 @@ fn test_op_precedence_and_or_1_overridden_by_parentheses() {
new_ucmd!()
.args(&["(", " ", "-o", "", ")", "-a", ""])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -747,7 +721,7 @@ fn test_op_precedence_and_or_2_overridden_by_parentheses() {
new_ucmd!()
.args(&["", "-a", "(", "", "-o", " ", ")", "-a", " "])
.run()
.status_code(1);
.code_is(1);
}
#[test]
@ -772,7 +746,7 @@ fn test_negated_boolean_precedence() {
];
for test in &negative_tests {
scenario.ucmd().args(&test[..]).run().status_code(1);
scenario.ucmd().args(&test[..]).run().code_is(1);
}
}
@ -785,25 +759,25 @@ fn test_bang_bool_op_precedence() {
new_ucmd!()
.args(&["!", "a value", "-o", "another value"])
.run()
.status_code(1);
.code_is(1);
// Introducing a UOP — even one that is equivalent to a bare string — causes
// bang to invert only the first term
new_ucmd!()
.args(&["!", "-n", "", "-a", ""])
.run()
.status_code(1);
.code_is(1);
new_ucmd!()
.args(&["!", "", "-a", "-n", ""])
.run()
.status_code(1);
.code_is(1);
// for compound Boolean expressions, bang inverts the _next_ expression
// only, not the entire compound expression
new_ucmd!()
.args(&["!", "", "-a", "", "-a", ""])
.run()
.status_code(1);
.code_is(1);
// parentheses can override this
new_ucmd!()
@ -817,7 +791,7 @@ fn test_inverted_parenthetical_bool_op_precedence() {
new_ucmd!()
.args(&["!", "a value", "-o", "another value"])
.run()
.status_code(1);
.code_is(1);
// only the parenthetical is inverted, not the entire expression
new_ucmd!()
@ -831,7 +805,7 @@ fn test_dangling_parenthesis() {
new_ucmd!()
.args(&["(", "(", "a", "!=", "b", ")", "-o", "-n", "c"])
.run()
.status_code(2);
.code_is(2);
new_ucmd!()
.args(&["(", "(", "a", "!=", "b", ")", "-o", "-n", "c", ")"])
.succeeds();
@ -852,22 +826,19 @@ fn test_erroneous_parenthesized_expression() {
new_ucmd!()
.args(&["a", "!=", "(", "b", "-a", "b", ")", "!=", "c"])
.run()
.status_code(2)
.code_is(2)
.stderr_is("test: extra argument 'b'");
}
#[test]
fn test_or_as_filename() {
new_ucmd!()
.args(&["x", "-a", "-z", "-o"])
.run()
.status_code(1);
new_ucmd!().args(&["x", "-a", "-z", "-o"]).run().code_is(1);
}
#[test]
#[ignore = "GNU considers this an error"]
fn test_string_length_and_nothing() {
new_ucmd!().args(&["-n", "a", "-a"]).run().status_code(2);
new_ucmd!().args(&["-n", "a", "-a"]).run().code_is(2);
}
#[test]
@ -883,7 +854,7 @@ fn test_bracket_syntax_failure() {
let scenario = TestScenario::new("[");
let mut ucmd = scenario.ucmd();
ucmd.args(&["1", "-eq", "2", "]"]).run().status_code(1);
ucmd.args(&["1", "-eq", "2", "]"]).run().code_is(1);
}
#[test]
@ -894,7 +865,7 @@ fn test_bracket_syntax_missing_right_bracket() {
// Missing closing bracket takes precedence over other possible errors.
ucmd.args(&["1", "-eq"])
.run()
.status_code(2)
.code_is(2)
.stderr_is("[: missing ']'");
}

View file

@ -13,7 +13,7 @@ fn test_invalid_arg() {
fn test_subcommand_return_code() {
new_ucmd!().arg("1").arg("true").succeeds();
new_ucmd!().arg("1").arg("false").run().status_code(1);
new_ucmd!().arg("1").arg("false").run().code_is(1);
}
#[test]

View file

@ -155,6 +155,7 @@ impl CmdResult {
.expect("Program must be run first or has not finished, yet")
}
#[track_caller]
pub fn code_is(&self, expected_code: i32) -> &Self {
assert_eq!(self.code(), expected_code);
self
@ -175,6 +176,7 @@ impl CmdResult {
}
/// asserts that the command resulted in a success (zero) status code
#[track_caller]
pub fn success(&self) -> &Self {
assert!(
self.success,
@ -186,6 +188,7 @@ impl CmdResult {
}
/// asserts that the command resulted in a failure (non-zero) status code
#[track_caller]
pub fn failure(&self) -> &Self {
assert!(
!self.success,
@ -196,17 +199,12 @@ impl CmdResult {
self
}
/// asserts that the command's exit code is the same as the given one
pub fn status_code(&self, code: i32) -> &Self {
assert_eq!(self.code, Some(code));
self
}
/// asserts that the command resulted in empty (zero-length) stderr stream output
/// generally, it's better to use `stdout_only()` instead,
/// but you might find yourself using this function if
/// 1. you can not know exactly what stdout will be or
/// 2. you know that stdout will also be empty
#[track_caller]
pub fn no_stderr(&self) -> &Self {
assert!(
self.stderr.is_empty(),
@ -222,6 +220,7 @@ impl CmdResult {
/// but you might find yourself using this function if
/// 1. you can not know exactly what stderr will be or
/// 2. you know that stderr will also be empty
#[track_caller]
pub fn no_stdout(&self) -> &Self {
assert!(
self.stdout.is_empty(),
@ -232,6 +231,7 @@ impl CmdResult {
}
/// Assert that there is output to neither stderr nor stdout.
#[track_caller]
pub fn no_output(&self) -> &Self {
self.no_stdout().no_stderr()
}
@ -239,12 +239,14 @@ impl CmdResult {
/// asserts that the command resulted in stdout stream output that equals the
/// passed in value, trailing whitespace are kept to force strict comparison (#1235)
/// `stdout_only()` is a better choice unless stderr may or will be non-empty
#[track_caller]
pub fn stdout_is<T: AsRef<str>>(&self, msg: T) -> &Self {
assert_eq!(self.stdout_str(), String::from(msg.as_ref()));
self
}
/// like `stdout_is`, but succeeds if any elements of `expected` matches stdout.
#[track_caller]
pub fn stdout_is_any<T: AsRef<str> + std::fmt::Debug>(&self, expected: &[T]) -> &Self {
assert!(
expected.iter().any(|msg| self.stdout_str() == msg.as_ref()),
@ -256,6 +258,7 @@ impl CmdResult {
}
/// Like `stdout_is` but newlines are normalized to `\n`.
#[track_caller]
pub fn normalized_newlines_stdout_is<T: AsRef<str>>(&self, msg: T) -> &Self {
let msg = msg.as_ref().replace("\r\n", "\n");
assert_eq!(self.stdout_str().replace("\r\n", "\n"), msg);
@ -264,12 +267,14 @@ impl CmdResult {
/// asserts that the command resulted in stdout stream output,
/// whose bytes equal those of the passed in slice
#[track_caller]
pub fn stdout_is_bytes<T: AsRef<[u8]>>(&self, msg: T) -> &Self {
assert_eq!(self.stdout, msg.as_ref());
self
}
/// like `stdout_is()`, but expects the contents of the file at the provided relative path
#[track_caller]
pub fn stdout_is_fixture<T: AsRef<OsStr>>(&self, file_rel_path: T) -> &Self {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stdout_is(String::from_utf8(contents).unwrap())
@ -291,6 +296,7 @@ impl CmdResult {
/// new_ucmd!().succeeds().stdout_is_fixture_bytes("expected.bin");
/// }
/// ```
#[track_caller]
pub fn stdout_is_fixture_bytes<T: AsRef<OsStr>>(&self, file_rel_path: T) -> &Self {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stdout_is_bytes(contents)
@ -298,6 +304,7 @@ impl CmdResult {
/// like `stdout_is_fixture()`, but replaces the data in fixture file based on values provided in `template_vars`
/// command output
#[track_caller]
pub fn stdout_is_templated_fixture<T: AsRef<OsStr>>(
&self,
file_rel_path: T,
@ -312,6 +319,7 @@ impl CmdResult {
}
/// like `stdout_is_templated_fixture`, but succeeds if any replacement by `template_vars` results in the actual stdout.
#[track_caller]
pub fn stdout_is_templated_fixture_any<T: AsRef<OsStr>>(
&self,
file_rel_path: T,
@ -331,6 +339,7 @@ impl CmdResult {
/// asserts that the command resulted in stderr stream output that equals the
/// passed in value, when both are trimmed of trailing whitespace
/// `stderr_only` is a better choice unless stdout may or will be non-empty
#[track_caller]
pub fn stderr_is<T: AsRef<str>>(&self, msg: T) -> &Self {
assert_eq!(
self.stderr_str().trim_end(),
@ -341,12 +350,14 @@ impl CmdResult {
/// asserts that the command resulted in stderr stream output,
/// whose bytes equal those of the passed in slice
#[track_caller]
pub fn stderr_is_bytes<T: AsRef<[u8]>>(&self, msg: T) -> &Self {
assert_eq!(self.stderr, msg.as_ref());
self
}
/// Like `stdout_is_fixture`, but for stderr
#[track_caller]
pub fn stderr_is_fixture<T: AsRef<OsStr>>(&self, file_rel_path: T) -> &Self {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stderr_is(String::from_utf8(contents).unwrap())
@ -356,6 +367,7 @@ impl CmdResult {
/// 1. the command resulted in stdout stream output that equals the
/// passed in value
/// 2. the command resulted in empty (zero-length) stderr stream output
#[track_caller]
pub fn stdout_only<T: AsRef<str>>(&self, msg: T) -> &Self {
self.no_stderr().stdout_is(msg)
}
@ -364,11 +376,13 @@ impl CmdResult {
/// 1. the command resulted in a stdout stream whose bytes
/// equal those of the passed in value
/// 2. the command resulted in an empty stderr stream
#[track_caller]
pub fn stdout_only_bytes<T: AsRef<[u8]>>(&self, msg: T) -> &Self {
self.no_stderr().stdout_is_bytes(msg)
}
/// like `stdout_only()`, but expects the contents of the file at the provided relative path
#[track_caller]
pub fn stdout_only_fixture<T: AsRef<OsStr>>(&self, file_rel_path: T) -> &Self {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stdout_only_bytes(contents)
@ -378,6 +392,7 @@ impl CmdResult {
/// 1. the command resulted in stderr stream output that equals the
/// passed in value, when both are trimmed of trailing whitespace
/// 2. the command resulted in empty (zero-length) stdout stream output
#[track_caller]
pub fn stderr_only<T: AsRef<str>>(&self, msg: T) -> &Self {
self.no_stdout().stderr_is(msg)
}
@ -386,10 +401,12 @@ impl CmdResult {
/// 1. the command resulted in a stderr stream whose bytes equal the ones
/// of the passed value
/// 2. the command resulted in an empty stdout stream
#[track_caller]
pub fn stderr_only_bytes<T: AsRef<[u8]>>(&self, msg: T) -> &Self {
self.no_stdout().stderr_is_bytes(msg)
}
#[track_caller]
pub fn fails_silently(&self) -> &Self {
assert!(!self.success);
assert!(self.stderr.is_empty());
@ -404,6 +421,7 @@ impl CmdResult {
/// `msg` should be the same as the one provided to `UUsageError::new` or `show_error!`
///
/// 2. the command resulted in empty (zero-length) stdout stream output
#[track_caller]
pub fn usage_error<T: AsRef<str>>(&self, msg: T) -> &Self {
self.stderr_only(format!(
"{0}: {2}\nTry '{1} {0} --help' for more information.",
@ -413,6 +431,7 @@ impl CmdResult {
))
}
#[track_caller]
pub fn stdout_contains<T: AsRef<str>>(&self, cmp: T) -> &Self {
assert!(
self.stdout_str().contains(cmp.as_ref()),
@ -423,6 +442,7 @@ impl CmdResult {
self
}
#[track_caller]
pub fn stderr_contains<T: AsRef<str>>(&self, cmp: T) -> &Self {
assert!(
self.stderr_str().contains(cmp.as_ref()),
@ -433,6 +453,7 @@ impl CmdResult {
self
}
#[track_caller]
pub fn stdout_does_not_contain<T: AsRef<str>>(&self, cmp: T) -> &Self {
assert!(
!self.stdout_str().contains(cmp.as_ref()),
@ -443,11 +464,13 @@ impl CmdResult {
self
}
#[track_caller]
pub fn stderr_does_not_contain<T: AsRef<str>>(&self, cmp: T) -> &Self {
assert!(!self.stderr_str().contains(cmp.as_ref()));
self
}
#[track_caller]
pub fn stdout_matches(&self, regex: &regex::Regex) -> &Self {
assert!(
regex.is_match(self.stdout_str().trim()),
@ -457,6 +480,7 @@ impl CmdResult {
self
}
#[track_caller]
pub fn stdout_does_not_match(&self, regex: &regex::Regex) -> &Self {
assert!(
!regex.is_match(self.stdout_str().trim()),
@ -1218,6 +1242,7 @@ impl UCommand {
/// Spawns the command, feeds the stdin if any, waits for the result,
/// asserts success, and returns a command result.
#[track_caller]
pub fn succeeds(&mut self) -> CmdResult {
let cmd_result = self.run();
cmd_result.success();
@ -1226,6 +1251,7 @@ impl UCommand {
/// Spawns the command, feeds the stdin if any, waits for the result,
/// asserts failure, and returns a command result.
#[track_caller]
pub fn fails(&mut self) -> CmdResult {
let cmd_result = self.run();
cmd_result.failure();
@ -1415,6 +1441,7 @@ impl<'a> UChildAssertion<'a> {
}
// Assert that the child process is alive
#[track_caller]
pub fn is_alive(&mut self) -> &mut Self {
match self
.uchild
@ -1436,6 +1463,7 @@ impl<'a> UChildAssertion<'a> {
}
// Assert that the child process has exited
#[track_caller]
pub fn is_not_alive(&mut self) -> &mut Self {
match self
.uchild