Skip to content

Commit

Permalink
Implement missing methods on Command and on CompletedProcess
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Jun 13, 2024
1 parent 56e112a commit 5523a62
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 27 deletions.
24 changes: 23 additions & 1 deletion src/tools/run-make-support/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ impl Command {
}
}

crate::impl_common_helpers_without_run!(Command);

impl std::ops::Deref for Command {
type Target = StdCommand;

fn deref(&self) -> &Self::Target {
&self.cmd
}
}

impl std::ops::DerefMut for Command {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.cmd
}
}

/// Represents the result of an executed process.
/// The various `assert_` helper methods should preferably be used for
/// checking the contents of stdout/stderr.
Expand Down Expand Up @@ -168,7 +184,13 @@ impl CompletedProcess {
}

#[track_caller]
pub fn assert_stdout_not_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
pub fn assert_stdout_contains<S: AsRef<str>>(self, content: S) -> Self {
assert!(self.stdout_utf8().contains(content.as_ref()));
self
}

#[track_caller]
pub fn assert_stdout_not_contains<S: AsRef<str>>(self, needle: S) -> Self {
assert_not_contains(&self.stdout_utf8(), needle.as_ref());
self
}
Expand Down
67 changes: 41 additions & 26 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,32 +348,7 @@ pub fn run_in_tmpdir<F: FnOnce()>(callback: F) {
fs::remove_dir_all(tmpdir).unwrap();
}

/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
/// containing a `cmd: Command` field. The provided helpers are:
///
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
/// new specific helper methods over relying on these generic argument providers.
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
/// methods of the same name on [`Command`].
/// 3. Output and execution: `run` and `run_fail` are provided. These are
/// higher-level convenience methods which wait for the command to finish running and assert
/// that the command successfully ran or failed as expected. They return
/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
/// process.
///
/// Example usage:
///
/// ```ignore (illustrative)
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
///
/// crate::impl_common_helpers!(CommandWrapper);
///
/// impl CommandWrapper {
/// // ... additional specific helper methods
/// }
/// ```
macro_rules! impl_common_helpers {
macro_rules! impl_common_helpers_without_run {
($wrapper: ident) => {
impl $wrapper {
/// Specify an environment variable.
Expand Down Expand Up @@ -426,6 +401,45 @@ macro_rules! impl_common_helpers {
self.cmd.inspect(inspector);
self
}
}
};
}

/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
/// containing a `cmd: Command` field. The provided helpers are:
///
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
/// new specific helper methods over relying on these generic argument providers.
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
/// methods of the same name on [`Command`].
/// 3. Output and execution: `run` and `run_fail` are provided. These are
/// higher-level convenience methods which wait for the command to finish running and assert
/// that the command successfully ran or failed as expected. They return
/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
/// process.
///
/// Example usage:
///
/// ```ignore (illustrative)
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
///
/// crate::impl_common_helpers!(CommandWrapper);
///
/// impl CommandWrapper {
/// // ... additional specific helper methods
/// }
/// ```
macro_rules! impl_common_helpers {
($wrapper: ident) => {
crate::impl_common_helpers_without_run!($wrapper);

impl $wrapper {
/// Set the path where the command will be run.
pub fn current_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.current_dir(path);
self
}

/// Run the constructed command and assert that it is successfully run.
#[track_caller]
Expand All @@ -450,3 +464,4 @@ macro_rules! impl_common_helpers {

use crate::command::{Command, CompletedProcess};
pub(crate) use impl_common_helpers;
pub(crate) use impl_common_helpers_without_run;

0 comments on commit 5523a62

Please sign in to comment.