From 41f4e100256691f0ecafd15f253b7c17a47bbe7f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 12 Oct 2017 18:40:46 -0600 Subject: [PATCH 1/3] fix(error): Report context for spawmn failures --- src/assert.rs | 7 +++++-- src/errors.rs | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/assert.rs b/src/assert.rs index b950d4b..7b1152c 100644 --- a/src/assert.rs +++ b/src/assert.rs @@ -1,4 +1,5 @@ use environment::Environment; +use error_chain::ChainedError; use errors::*; use output::{OutputAssertion, OutputKind}; use std::default; @@ -332,7 +333,9 @@ impl Assert { None => command, }; - let mut spawned = command.spawn()?; + let mut spawned = command + .spawn() + .chain_err(|| ErrorKind::SpawnFailed(self.cmd.clone()))?; if let Some(ref contents) = self.stdin_contents { spawned @@ -389,7 +392,7 @@ impl Assert { /// ``` pub fn unwrap(self) { if let Err(err) = self.execute() { - panic!("{}", err); + panic!("{}", err.display_chain()); } } } diff --git a/src/errors.rs b/src/errors.rs index af9ab5e..ab0f7b1 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -6,6 +6,14 @@ error_chain! { Fmt(::std::fmt::Error); } errors { + SpawnFailed(cmd: Vec) { + description("Spawn failed") + display( + "{}: (command `{}` failed to run)", + ERROR_PREFIX, + cmd.join(" "), + ) + } StatusMismatch(cmd: Vec, expected: bool, out: String, err: String) { description("Wrong status") display( From 6c3550c58ae809da7a16003bfcbde0d3c83f2353 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 12 Oct 2017 18:41:33 -0600 Subject: [PATCH 2/3] tests: Validate main_binary / cargo_binary `clap` couldn't be used for command line arguments. I didn't want to add it as a dependency for clients, which meant it had to be optional. The problem is that `main_binary` and `cargo_binary` run with optional features enabled. Note: you cannot use `main_binary` or `cargo_binary` - With `Environment::empty` because the executable can't be found - In skeptic tests (like the README) because the working dir is changed --- Cargo.toml | 3 +++ src/bin/assert_fixture.rs | 31 +++++++++++++++++++++++++++++++ tests/cargo.rs | 19 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/bin/assert_fixture.rs create mode 100644 tests/cargo.rs diff --git a/Cargo.toml b/Cargo.toml index 5d17ad8..942be02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,9 @@ categories = ["development-tools::testing"] keywords = ["cli", "testing", "assert"] build = "build.rs" +[[bin]] +name = "assert_fixture" + [dependencies] colored = "1.5" difference = "1.0" diff --git a/src/bin/assert_fixture.rs b/src/bin/assert_fixture.rs new file mode 100644 index 0000000..f22ba0c --- /dev/null +++ b/src/bin/assert_fixture.rs @@ -0,0 +1,31 @@ +#[macro_use] +extern crate error_chain; + +use std::env; +use std::process; + +error_chain! { + foreign_links { + Env(env::VarError); + ParseInt(std::num::ParseIntError); + } +} + +fn run() -> Result<()> { + if let Ok(text) = env::var("stdout") { + println!("{}", text); + } + if let Ok(text) = env::var("stderr") { + eprintln!("{}", text); + } + + let code = env::var("exit") + .ok() + .map(|v| v.parse::()) + .map_or(Ok(None), |r| r.map(Some)) + .chain_err(|| "Invalid exit code")? + .unwrap_or(0); + process::exit(code); +} + +quick_main!(run); diff --git a/tests/cargo.rs b/tests/cargo.rs new file mode 100644 index 0000000..6c211ce --- /dev/null +++ b/tests/cargo.rs @@ -0,0 +1,19 @@ +extern crate assert_cli; + +#[test] +fn main_binary() { + assert_cli::Assert::main_binary() + .with_env(assert_cli::Environment::inherit().insert("stdout", "42")) + .stdout() + .contains("42") + .unwrap(); +} + +#[test] +fn cargo_binary() { + assert_cli::Assert::cargo_binary("assert_fixture") + .with_env(assert_cli::Environment::inherit().insert("stdout", "42")) + .stdout() + .contains("42") + .unwrap(); +} From 45a4aa600d4e6ed16a512afce11d9d69d4571c2e Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 12 Oct 2017 18:45:13 -0600 Subject: [PATCH 3/3] fix: Remove unrelated output in main_binary We use cargo run behind the scenes to run the main binary but that should only be an implementation detail. Fixes #45 --- src/assert.rs | 4 ++-- tests/cargo.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/assert.rs b/src/assert.rs index 7b1152c..47c6e2a 100644 --- a/src/assert.rs +++ b/src/assert.rs @@ -26,7 +26,7 @@ impl default::Default for Assert { /// Defaults to asserting _successful_ execution. fn default() -> Self { Assert { - cmd: vec!["cargo", "run", "--"] + cmd: vec!["cargo", "run", "--quiet", "--"] .into_iter() .map(String::from) .collect(), @@ -53,7 +53,7 @@ impl Assert { /// Defaults to asserting _successful_ execution. pub fn cargo_binary(name: &str) -> Self { Assert { - cmd: vec!["cargo", "run", "--bin", name, "--"] + cmd: vec!["cargo", "run", "--quiet", "--bin", name, "--"] .into_iter() .map(String::from) .collect(), diff --git a/tests/cargo.rs b/tests/cargo.rs index 6c211ce..f476ee1 100644 --- a/tests/cargo.rs +++ b/tests/cargo.rs @@ -5,7 +5,9 @@ fn main_binary() { assert_cli::Assert::main_binary() .with_env(assert_cli::Environment::inherit().insert("stdout", "42")) .stdout() - .contains("42") + .is("42") + .stderr() + .is("") .unwrap(); } @@ -14,6 +16,8 @@ fn cargo_binary() { assert_cli::Assert::cargo_binary("assert_fixture") .with_env(assert_cli::Environment::inherit().insert("stdout", "42")) .stdout() - .contains("42") + .is("42") + .stderr() + .is("") .unwrap(); }