Add a helper method to show stdout/err in tests

This commit is contained in:
Aleksey Kladov 2018-03-15 10:40:26 +03:00
parent 805fbebc83
commit 005bd4b4fb
2 changed files with 43 additions and 7 deletions

View File

@ -7,13 +7,10 @@ interested in the inner workings of Cargo.
## Subcommands ## Subcommands
Cargo is organized as a set of subcommands. All subcommands live in Cargo is organized as a set of `clap` subcommands. All subcommands live in
`src/bin` directory. However, only `src/bin/cargo.rs` file produces an `src/bin/commands` directory. `src/bin/cargo.rs` is the entry point.
executable, other files inside the `bin` directory are submodules. See
`src/bin/cargo.rs` for how these subcommands get wired up with the
main executable.
A typical subcommand, such as `src/bin/build.rs`, parses command line A typical subcommand, such as `src/bin/commands/build.rs`, parses command line
options, reads the configuration files, discovers the Cargo project in options, reads the configuration files, discovers the Cargo project in
the current directory and delegates the actual implementation to one the current directory and delegates the actual implementation to one
of the functions in `src/cargo/ops/mod.rs`. This short file is a good of the functions in `src/cargo/ops/mod.rs`. This short file is a good
@ -88,3 +85,21 @@ verified against the expected output. To simplify testing, several
macros of the form `[MACRO]` are used in the expected output. For macros of the form `[MACRO]` are used in the expected output. For
example, `[..]` matches any string and `[/]` matches `/` on Unixes and example, `[..]` matches any string and `[/]` matches `/` on Unixes and
`\` on windows. `\` on windows.
To see stdout and stderr streams of the subordinate process, add `.stream()`
call to `execs()`:
```rust
// Before
assert_that(
p.cargo("run"),
execs().with_status(0)
);
// After
assert_that(
p.cargo("run"),
execs().stream().with_status(0)
);
```

View File

@ -365,6 +365,7 @@ pub struct Execs {
expect_stderr_not_contains: Vec<String>, expect_stderr_not_contains: Vec<String>,
expect_neither_contains: Vec<String>, expect_neither_contains: Vec<String>,
expect_json: Option<Vec<Value>>, expect_json: Option<Vec<Value>>,
stream_output: bool,
} }
impl Execs { impl Execs {
@ -428,6 +429,14 @@ impl Execs {
self self
} }
/// Forward subordinate process stdout/stderr to the terminal.
/// Useful for prtintf debugging of the tests.
#[allow(unused)]
pub fn stream(mut self) -> Execs {
self.stream_output = true;
self
}
fn match_output(&self, actual: &Output) -> ham::MatchResult { fn match_output(&self, actual: &Output) -> ham::MatchResult {
self.match_status(actual) self.match_status(actual)
.and(self.match_stdout(actual)) .and(self.match_stdout(actual))
@ -855,7 +864,18 @@ impl ham::Matcher<ProcessBuilder> for Execs {
impl<'a> ham::Matcher<&'a mut ProcessBuilder> for Execs { impl<'a> ham::Matcher<&'a mut ProcessBuilder> for Execs {
fn matches(&self, process: &'a mut ProcessBuilder) -> ham::MatchResult { fn matches(&self, process: &'a mut ProcessBuilder) -> ham::MatchResult {
println!("running {}", process); println!("running {}", process);
let res = process.exec_with_output(); let res = if self.stream_output {
if env::var("CI").is_ok() {
panic!("`.stream()` is for local debugging")
}
process.exec_with_streaming(
&mut |out| Ok(println!("{}", out)),
&mut |err| Ok(eprintln!("{}", err)),
false,
)
} else {
process.exec_with_output()
};
match res { match res {
Ok(out) => self.match_output(&out), Ok(out) => self.match_output(&out),
@ -898,6 +918,7 @@ pub fn execs() -> Execs {
expect_stderr_not_contains: Vec::new(), expect_stderr_not_contains: Vec::new(),
expect_neither_contains: Vec::new(), expect_neither_contains: Vec::new(),
expect_json: None, expect_json: None,
stream_output: false,
} }
} }