Skip to content

Commit

Permalink
Merge pull request uutils#1870 from nomius10/document_macros
Browse files Browse the repository at this point in the history
documentation for usual macros
  • Loading branch information
sylvestre authored Mar 22, 2021
2 parents b9662c7 + 93c7cbe commit f593cf5
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 11 deletions.
16 changes: 16 additions & 0 deletions src/uucore/src/lib/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

/// Deduce the name of the binary from the current source code filename.
///
/// e.g.: `src/uu/cp/src/cp.rs` -> `cp`
#[macro_export]
macro_rules! executable(
() => ({
Expand All @@ -18,6 +21,7 @@ macro_rules! executable(
})
);

/// Show an error to stderr in a silimar style to GNU coreutils.
#[macro_export]
macro_rules! show_error(
($($args:tt)+) => ({
Expand All @@ -26,6 +30,7 @@ macro_rules! show_error(
})
);

/// Show a warning to stderr in a silimar style to GNU coreutils.
#[macro_export]
macro_rules! show_warning(
($($args:tt)+) => ({
Expand All @@ -34,6 +39,7 @@ macro_rules! show_warning(
})
);

/// Show an info message to stderr in a silimar style to GNU coreutils.
#[macro_export]
macro_rules! show_info(
($($args:tt)+) => ({
Expand All @@ -42,6 +48,7 @@ macro_rules! show_info(
})
);

/// Show a bad inocation help message in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_usage_error(
($($args:tt)+) => ({
Expand All @@ -51,6 +58,7 @@ macro_rules! show_usage_error(
})
);

/// Display the provided error message, then `exit()` with the provided exit code
#[macro_export]
macro_rules! crash(
($exit_code:expr, $($args:tt)+) => ({
Expand All @@ -59,13 +67,16 @@ macro_rules! crash(
})
);

/// Calls `exit()` with the provided exit code.
#[macro_export]
macro_rules! exit(
($exit_code:expr) => ({
::std::process::exit($exit_code)
})
);

/// Unwraps the Result. Instead of panicking, it exists the program with the
/// provided exit code.
#[macro_export]
macro_rules! crash_if_err(
($exit_code:expr, $exp:expr) => (
Expand All @@ -76,6 +87,9 @@ macro_rules! crash_if_err(
)
);

/// Unwraps the Result. Instead of panicking, it shows the error and then
/// returns from the function with the provided exit code.
/// Assumes the current function returns an i32 value.
#[macro_export]
macro_rules! return_if_err(
($exit_code:expr, $exp:expr) => (
Expand Down Expand Up @@ -109,6 +123,8 @@ macro_rules! safe_writeln(
)
);

/// Unwraps the Result. Instead of panicking, it exists the program with exit
/// code 1.
#[macro_export]
macro_rules! safe_unwrap(
($exp:expr) => (
Expand Down
2 changes: 1 addition & 1 deletion tests/by-util/test_pathchk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn test_default_mode() {

// fail on long inputs
new_ucmd!()
.args(&[repeat_str("test", 20000)])
.args(&["test".repeat(20000)])
.fails()
.no_stdout();
}
35 changes: 35 additions & 0 deletions tests/common/macros.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/// Assertion helper macro for [`CmdResult`] types
///
/// [`CmdResult`]: crate::tests::common::util::CmdResult
#[macro_export]
macro_rules! assert_empty_stderr(
($cond:expr) => (
Expand All @@ -7,6 +10,9 @@ macro_rules! assert_empty_stderr(
);
);

/// Assertion helper macro for [`CmdResult`] types
///
/// [`CmdResult`]: crate::tests::common::util::CmdResult
#[macro_export]
macro_rules! assert_empty_stdout(
($cond:expr) => (
Expand All @@ -16,6 +22,9 @@ macro_rules! assert_empty_stdout(
);
);

/// Assertion helper macro for [`CmdResult`] types
///
/// [`CmdResult`]: crate::tests::common::util::CmdResult
#[macro_export]
macro_rules! assert_no_error(
($cond:expr) => (
Expand All @@ -26,6 +35,7 @@ macro_rules! assert_no_error(
);
);

/// Platform-independent helper for constructing a PathBuf from individual elements
#[macro_export]
macro_rules! path_concat {
($e:expr, ..$n:expr) => {{
Expand All @@ -47,20 +57,45 @@ macro_rules! path_concat {
}};
}

/// Deduce the name of the test binary from the test filename.
///
/// e.g.: `tests/by-util/test_cat.rs` -> `cat`
#[macro_export]
macro_rules! util_name {
() => {
module_path!().split("_").nth(1).expect("no test name")
};
}

/// Convenience macro for acquiring a [`UCommand`] builder.
///
/// Returns the following:
/// - a [`UCommand`] builder for invoking the binary to be tested
///
/// This macro is intended for quick, single-call tests. For more complex tests
/// that require multiple invocations of the tested binary, see [`TestScenario`]
///
/// [`UCommand`]: crate::tests::common::util::UCommand
/// [`TestScenario]: crate::tests::common::util::TestScenario
#[macro_export]
macro_rules! new_ucmd {
() => {
TestScenario::new(util_name!()).ucmd()
};
}

/// Convenience macro for acquiring a [`UCommand`] builder and a test path.
///
/// Returns a tuple containing the following:
/// - an [`AsPath`] that points to a unique temporary test directory
/// - a [`UCommand`] builder for invoking the binary to be tested
///
/// This macro is intended for quick, single-call tests. For more complex tests
/// that require multiple invocations of the tested binary, see [`TestScenario`]
///
/// [`UCommand`]: crate::tests::common::util::UCommand
/// [`AsPath`]: crate::tests::common::util::AsPath
/// [`TestScenario]: crate::tests::common::util::TestScenario
#[macro_export]
macro_rules! at_and_ucmd {
() => {{
Expand Down
24 changes: 14 additions & 10 deletions tests/common/util.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(dead_code)]

use std::env;
use std::ffi::OsStr;
use std::fs::{self, File, OpenOptions};
Expand Down Expand Up @@ -27,7 +29,7 @@ static ALREADY_RUN: &str = " you have already run this UCommand, if you want to
testing();";
static MULTIPLE_STDIN_MEANINGLESS: &str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly.";

/// Test if the program are running under CI
/// Test if the program is running under CI
pub fn is_ci() -> bool {
std::env::var("CI")
.unwrap_or(String::from("false"))
Expand Down Expand Up @@ -55,14 +57,6 @@ fn read_scenario_fixture<S: AsRef<OsStr>>(tmpd: &Option<Rc<TempDir>>, file_rel_p
AtPath::new(tmpdir_path).read(file_rel_path.as_ref().to_str().unwrap())
}

pub fn repeat_str(s: &str, n: u32) -> String {
let mut repeated = String::new();
for _ in 0..n {
repeated.push_str(s);
}
repeated
}

/// 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)]
Expand Down Expand Up @@ -384,8 +378,10 @@ impl AtPath {

/// An environment for running a single uutils test case, serves three functions:
/// 1. centralizes logic for locating the uutils binary and calling the utility
/// 2. provides a temporary directory for the test case
/// 2. provides a unique temporary directory for the test case
/// 3. copies over fixtures for the utility to the temporary directory
///
/// Fixtures can be found under `tests/fixtures/$util_name/`
pub struct TestScenario {
bin_path: PathBuf,
util_name: String,
Expand Down Expand Up @@ -420,12 +416,16 @@ impl TestScenario {
ts
}

/// Returns builder for invoking the target uutils binary. Paths given are
/// treated relative to the environment's unique temporary test directory.
pub fn ucmd(&self) -> UCommand {
let mut cmd = self.cmd(&self.bin_path);
cmd.arg(&self.util_name);
cmd
}

/// Returns builder for invoking any system command. Paths given are treated
/// relative to the environment's unique temporary test directory.
pub fn cmd<S: AsRef<OsStr>>(&self, bin: S) -> UCommand {
UCommand::new_from_tmp(bin, self.tmpd.clone(), true)
}
Expand Down Expand Up @@ -495,6 +495,8 @@ impl UCommand {
ucmd
}

/// Add a parameter to the invocation. Path arguments are treated relative
/// to the test environment directory.
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> Box<&mut UCommand> {
if self.has_run {
panic!(ALREADY_RUN);
Expand All @@ -505,6 +507,8 @@ impl UCommand {
Box::new(self)
}

/// Add multiple parameters to the invocation. Path arguments are treated relative
/// to the test environment directory.
pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> Box<&mut UCommand> {
if self.has_run {
panic!(MULTIPLE_STDIN_MEANINGLESS);
Expand Down

0 comments on commit f593cf5

Please sign in to comment.