From 9379147429ff1eb8cb0766c696d1ae6141b66a33 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Sat, 26 Jan 2019 16:28:31 -0700 Subject: [PATCH 1/2] perf(cargo): Faster bin lookup This is an experiemnt in a new direction in trying to resolve - Cargo overhead (#6) - Compile times from mismatched `--target` (#57) - Suprising behavior if `--target ` isn't specified (#4) The new downsides this introduces - No `main_binary` or `cargo_example` - Can only work within integration tests We're recommending the use of `escargot` in these cases which I think might be reasonable because instead of making policy decisions for the user, and no one ever being happy, the user can choose which policy they want. Plus, in more complex cases they should already be using `escargot` so they can cache. Fixes #6 Fixes #57 BREAKING CHANGE: `main_binary` / `cargo_example` no longer exist. Also, successfully running `cargo_bin` has been restricted to integration tests. --- README.md | 4 +- src/assert.rs | 106 +++++++++++++++--------------- src/cargo.rs | 163 ++++++++++++++++++++++++---------------------- src/cmd.rs | 21 +++--- src/lib.rs | 44 +++++++++++-- tests/assert.rs | 111 ++++++++++++++++++++++++++----- tests/cargo.rs | 58 ++++++++--------- tests/examples.rs | 22 +++++++ 8 files changed, 329 insertions(+), 200 deletions(-) create mode 100644 tests/examples.rs diff --git a/README.md b/README.md index 6a46e02..9487dff 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,13 @@ assert_cmd = "0.10" Here's a trivial example: -```rust +```rust,no_run extern crate assert_cmd; use std::process::Command; use assert_cmd::prelude::*; -Command::main_binary() +Command::cargo_bin("bin_fixture") .unwrap() .assert() .success(); diff --git a/src/assert.rs b/src/assert.rs index 9203e3c..4884db8 100644 --- a/src/assert.rs +++ b/src/assert.rs @@ -18,15 +18,15 @@ use cmd::output_fmt; /// /// # Examples /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// let mut cmd = Command::main_binary() +/// let mut cmd = Command::cargo_bin("bin_fixture") /// .unwrap(); /// cmd.assert() -/// .success(); +/// .success(); /// ``` /// /// [`Output`]: https://doc.rust-lang.org/std/process/struct.Output.html @@ -35,15 +35,15 @@ pub trait OutputAssertExt { /// /// # Examples /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// let mut cmd = Command::main_binary() + /// let mut cmd = Command::cargo_bin("bin_fixture") /// .unwrap(); /// cmd.assert() - /// .success(); + /// .success(); /// ``` /// /// [`Output`]: https://doc.rust-lang.org/std/process/struct.Output.html @@ -69,15 +69,15 @@ impl<'c> OutputAssertExt for &'c mut process::Command { /// /// # Examples /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// let mut cmd = Command::main_binary() +/// let mut cmd = Command::cargo_bin("bin_fixture") /// .unwrap(); /// cmd.assert() -/// .success(); +/// .success(); /// ``` /// /// [`Output`]: https://doc.rust-lang.org/std/process/struct.Output.html @@ -102,12 +102,12 @@ impl Assert { /// /// # Examples /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .assert() /// .append_context("main", "no args") @@ -132,12 +132,12 @@ impl Assert { /// /// # Examples /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .assert() /// .success(); @@ -165,12 +165,12 @@ impl Assert { /// /// # Examples /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "1") /// .assert() @@ -200,7 +200,7 @@ impl Assert { /// # Examples /// /// Accepting a predicate: - /// ```rust + /// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -209,7 +209,7 @@ impl Assert { /// use std::process::Command; /// use predicates::prelude::*; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "42") /// .assert() @@ -217,12 +217,12 @@ impl Assert { /// ``` /// /// Accepting an exit code: - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "42") /// .assert() @@ -230,12 +230,12 @@ impl Assert { /// ``` /// /// Accepting multiple exit codes: - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "42") /// .assert() @@ -273,7 +273,7 @@ impl Assert { /// # Examples /// /// Accepting a bytes predicate: - /// ```rust + /// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -282,7 +282,7 @@ impl Assert { /// use std::process::Command; /// use predicates::prelude::*; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -291,7 +291,7 @@ impl Assert { /// ``` /// /// Accepting a `str` predicate: - /// ```rust + /// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -300,7 +300,7 @@ impl Assert { /// use std::process::Command; /// use predicates::prelude::*; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -309,12 +309,12 @@ impl Assert { /// ``` /// /// Accepting bytes: - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -323,12 +323,12 @@ impl Assert { /// ``` /// /// Accepting a `str`: - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -365,7 +365,7 @@ impl Assert { /// # Examples /// /// Accepting a bytes predicate: - /// ```rust + /// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -374,7 +374,7 @@ impl Assert { /// use std::process::Command; /// use predicates::prelude::*; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -383,7 +383,7 @@ impl Assert { /// ``` /// /// Accepting a `str` predicate: - /// ```rust + /// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -392,7 +392,7 @@ impl Assert { /// use std::process::Command; /// use predicates::prelude::*; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -401,12 +401,12 @@ impl Assert { /// ``` /// /// Accepting bytes: - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -415,12 +415,12 @@ impl Assert { /// ``` /// /// Accepting a `str`: - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// Command::main_binary() + /// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -471,7 +471,7 @@ impl fmt::Debug for Assert { /// /// # Examples /// -/// ```rust +/// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -480,14 +480,14 @@ impl fmt::Debug for Assert { /// use std::process::Command; /// use predicates::prelude::*; /// -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "42") /// .assert() /// .code(predicate::eq(42)); /// /// // which can be shortened to: -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "42") /// .assert() @@ -523,12 +523,12 @@ where /// /// # Example /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "42") /// .assert() @@ -593,12 +593,12 @@ impl IntoCodePredicate for i32 { /// /// # Example /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("exit", "42") /// .assert() @@ -671,7 +671,7 @@ impl IntoCodePredicate for &'static [i32] { /// /// # Examples /// -/// ```rust +/// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -680,7 +680,7 @@ impl IntoCodePredicate for &'static [i32] { /// use std::process::Command; /// use predicates::prelude::*; /// -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -688,7 +688,7 @@ impl IntoCodePredicate for &'static [i32] { /// .stdout(predicate::str::similar("hello\n").from_utf8()); /// /// // which can be shortened to: -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -726,12 +726,12 @@ where /// /// # Example /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -797,12 +797,12 @@ impl IntoOutputPredicate for &'static [u8] { /// /// # Example /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") @@ -884,7 +884,7 @@ impl IntoOutputPredicate for &'static str { /// /// # Example /// -/// ```rust +/// ```rust,no_run /// extern crate assert_cmd; /// extern crate predicates; /// @@ -893,7 +893,7 @@ impl IntoOutputPredicate for &'static str { /// use std::process::Command; /// use predicates::prelude::*; /// -/// Command::main_binary() +/// Command::cargo_bin("bin_fixture") /// .unwrap() /// .env("stdout", "hello") /// .env("stderr", "world") diff --git a/src/cargo.rs b/src/cargo.rs index b7c5942..92b57ac 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -7,25 +7,26 @@ //! //! Simple case: //! -//! ```rust +//! ```rust,no_run //! use assert_cmd::prelude::*; //! //! use std::process::Command; //! -//! let mut cmd = Command::main_binary() +//! let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")) //! .unwrap(); //! let output = cmd.unwrap(); //! ``` //! -//! # Further customizations +//! # Limitations //! -//! There are times when you might want to drop down to the underlying API, [`escargot`]: -//! - Specifying feature flags -//! - Workaround the [per-call cargo overhead][cargo-overhead] by caching the binary location with [`lazy_static`]. -//! - [If not using `--target `, bypass the first call overhead][first-call] by not -//! passing `current_target()` to [`escargot`]. +//! - Only works within the context of integration tests. See [`escargot`] for a more +//! flexible API. +//! - Only reuses your existing feature flags, targets, or build mode. +//! - Only works with cargo binaries (`cargo test` ensures they are built). //! -//! ```rust +//! If you run into these limitations, we recommend trying out [`escargot`]: +//! +//! ```rust,no_run //! extern crate assert_cmd; //! extern crate escargot; //! @@ -42,8 +43,15 @@ //! .unwrap(); //! let mut cmd = bin_under_test.command(); //! let output = cmd.unwrap(); +//! println!("{:?}", output); //! ``` //! +//! Notes: +//! - There is a [noticeable per-call overhead](cargo-overhead) for `CargoBuild`. We recommend +//! caching the binary location (`.path()` instead of `.command()`) with [`lazy_static`]. +//! - `.current_target()` improves platform coverage at the cost of [slower test runs if you don't +//! explicitly pass `--target ` on the command line](first-call). +//! //! [`lazy_static`]: https://crates.io/crates/lazy_static //! [`CommandCargoExt`]: trait.CommandCargoExt.html //! [`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html @@ -51,13 +59,12 @@ //! [cargo-overhead]: https://github.com/assert-rs/assert_cmd/issues/6 //! [first-call]: https://github.com/assert-rs/assert_cmd/issues/57 +use std::env; use std::error::Error; -use std::ffi; use std::fmt; +use std::path; use std::process; -use escargot; - /// Create a [`Command`] for a `bin` in the Cargo project. /// /// `CommandCargoExt` is an extension trait for [`Command`][Command] to easily launch a crate's @@ -67,14 +74,15 @@ use escargot; /// /// # Examples /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// let mut cmd = Command::main_binary() +/// let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")) /// .unwrap(); /// let output = cmd.unwrap(); +/// println!("{:?}", output); /// ``` /// /// [`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html @@ -83,97 +91,47 @@ pub trait CommandCargoExt where Self: Sized, { - /// Create a [`Command`] to run the crate's main binary. - /// - /// Note: only works if there one bin in the crate. - /// - /// See the [`cargo` module documentation][`cargo`] for caveats and workarounds. - /// - /// # Examples - /// - /// ```rust - /// use assert_cmd::prelude::*; - /// - /// use std::process::Command; - /// - /// let mut cmd = Command::main_binary() - /// .unwrap(); - /// let output = cmd.unwrap(); - /// ``` - /// - /// [`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html - /// [`cargo`]: index.html - fn main_binary() -> Result; - /// Create a [`Command`] to run a specific binary of the current crate. /// /// See the [`cargo` module documentation][`cargo`] for caveats and workarounds. /// /// # Examples /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// let mut cmd = Command::cargo_bin("bin_fixture") + /// let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")) /// .unwrap(); /// let output = cmd.unwrap(); + /// println!("{:?}", output); /// ``` /// - /// [`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html - /// [`cargo`]: index.html - fn cargo_bin>(name: S) -> Result; - - /// Create a [`Command`] to run a specific example of the current crate. - /// - /// See the [`cargo` module documentation][`cargo`] for caveats and workarounds. - /// - /// # Examples - /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// let mut cmd = Command::cargo_example("example_fixture") + /// let mut cmd = Command::cargo_bin("bin_fixture") /// .unwrap(); /// let output = cmd.unwrap(); + /// println!("{:?}", output); /// ``` /// /// [`Command`]: https://doc.rust-lang.org/std/process/struct.Command.html /// [`cargo`]: index.html - fn cargo_example>(name: S) -> Result; + fn cargo_bin>(name: S) -> Result; } impl CommandCargoExt for process::Command { - fn main_binary() -> Result { - let runner = escargot::CargoBuild::new() - .current_release() - .current_target() - .run() - .map_err(CargoError::with_cause)?; - Ok(runner.command()) - } - - fn cargo_bin>(name: S) -> Result { - let runner = escargot::CargoBuild::new() - .bin(name) - .current_release() - .current_target() - .run() - .map_err(CargoError::with_cause)?; - Ok(runner.command()) - } - - fn cargo_example>(name: S) -> Result { - let runner = escargot::CargoBuild::new() - .example(name) - .current_release() - .current_target() - .run() - .map_err(CargoError::with_cause)?; - Ok(runner.command()) + fn cargo_bin>(name: S) -> Result { + let path = cargo_bin(name); + if path.is_file() { + Ok(process::Command::new(path)) + } else { + Err(CargoError::with_cause(NotFoundError { path })) + } } } @@ -184,7 +142,8 @@ pub struct CargoError { } impl CargoError { - fn with_cause(cause: E) -> Self + /// Wrap the underlying error for passing up. + pub fn with_cause(cause: E) -> Self where E: Error + Send + Sync + 'static, { @@ -214,3 +173,49 @@ impl fmt::Display for CargoError { Ok(()) } } + +/// Error when finding crate binary. +#[derive(Debug)] +struct NotFoundError { + path: path::PathBuf, +} + +impl Error for NotFoundError { + fn description(&self) -> &str { + "Cargo command not found." + } + + fn cause(&self) -> Option<&Error> { + None + } +} + +impl fmt::Display for NotFoundError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln!(f, "Cargo command not found: {}", self.path.display()) + } +} + +// Adapted from +// https://github.com/rust-lang/cargo/blob/485670b3983b52289a2f353d589c57fae2f60f82/tests/testsuite/support/mod.rs#L507 +fn target_dir() -> path::PathBuf { + env::current_exe() + .ok() + .map(|mut path| { + path.pop(); + if path.ends_with("deps") { + path.pop(); + } + path + }) + .unwrap() +} + +/// Look up the path to a cargo-built binary within an integration test. +pub fn cargo_bin>(name: S) -> path::PathBuf { + cargo_bin_str(name.as_ref()) +} + +fn cargo_bin_str(name: &str) -> path::PathBuf { + target_dir().join(format!("{}{}", name, env::consts::EXE_SUFFIX)) +} diff --git a/src/cmd.rs b/src/cmd.rs index c19acb2..cd6431f 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -73,14 +73,13 @@ where /// /// # Examples /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// let err = Command::main_binary() - /// .unwrap() - /// .env("exit", "42") + /// let err = Command::new("a-command") + /// .args(&["--will-fail"]) /// .unwrap_err(); /// ``` /// @@ -158,14 +157,13 @@ pub type OutputResult = Result; /// /// # Examples /// -/// ```rust +/// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// -/// let err = Command::main_binary() -/// .unwrap() -/// .env("exit", "42") +/// let err = Command::new("a-command") +/// .args(&["--will-fail"]) /// .unwrap_err(); /// ``` /// @@ -221,14 +219,13 @@ impl OutputError { /// /// # Examples /// - /// ```rust + /// ```rust,no_run /// use assert_cmd::prelude::*; /// /// use std::process::Command; /// - /// let err = Command::main_binary() - /// .unwrap() - /// .env("exit", "42") + /// let err = Command::new("a-command") + /// .args(&["--will-fail"]) /// .unwrap_err(); /// let output = err /// .as_output() diff --git a/src/lib.rs b/src/lib.rs index 96071d9..b024b23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,9 +13,7 @@ //! //! Create a [`Command`]: //! - `Command::new(path)`, see [`Command`] -//! - `Command::main_binary()`, see [`CommandCargoExt`] //! - `Command::cargo_bin(name)`, see [`CommandCargoExt`] -//! - `Command::cargo_example(name)`, see [`CommandCargoExt`] //! //! Configure a [`Command`]: //! - `arg` / `args`, see [`Command`] @@ -36,27 +34,27 @@ //! ## Examples //! //! Here's a trivial example: -//! ```rust +//! ```rust,no_run //! extern crate assert_cmd; //! //! use std::process::Command; //! use assert_cmd::prelude::*; //! //! fn main() { -//! let mut cmd = Command::main_binary().unwrap(); +//! let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); //! cmd.assert().success(); //! } //! ``` //! //! And a little of everything: -//! ```rust +//! ```rust,no_run //! extern crate assert_cmd; //! //! use std::process::Command; //! use assert_cmd::prelude::*; //! //! fn main() { -//! let mut cmd = Command::main_binary().unwrap(); +//! let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); //! cmd //! .arg("-A") //! .env("stdout", "hello") @@ -114,6 +112,40 @@ extern crate predicates; extern crate predicates_core; extern crate predicates_tree; +/// Allows you to pull the name from your Cargo.toml at compile time. +/// +/// # Examples +/// +/// ```should_panic +/// #[macro_use] +/// extern crate assert_cmd; +/// +/// use std::process::Command; +/// use assert_cmd::prelude::*; +/// +/// fn main() { +/// let mut cmd = Command::cargo_bin(crate_name!()).unwrap(); +/// cmd +/// .arg("-A") +/// .env("stdout", "hello") +/// .env("exit", "42") +/// .with_stdin() +/// .buffer("42"); +/// let assert = cmd.assert(); +/// assert +/// .failure() +/// .code(42) +/// .stdout("hello\n"); +/// } +/// ``` +#[cfg(not(feature = "no_cargo"))] +#[macro_export] +macro_rules! crate_name { + () => { + env!("CARGO_PKG_NAME") + }; +} + pub mod assert; pub mod cargo; pub mod cmd; diff --git a/tests/assert.rs b/tests/assert.rs index fac4124..24b579f 100644 --- a/tests/assert.rs +++ b/tests/assert.rs @@ -6,33 +6,106 @@ use std::process::Command; use assert_cmd::prelude::*; use predicates::prelude::*; +#[test] +fn stdout_string() { + let expected = "hello\n".to_owned(); + Command::cargo_bin("bin_fixture") + .unwrap() + .env("stdout", "hello") + .env("stderr", "world") + .assert() + .stdout(expected); +} + +#[test] +fn trait_example() { + let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + cmd.assert().success(); +} + +#[test] +fn trait_assert_example() { + let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + cmd.assert().success(); +} + +#[test] +fn struct_example() { + let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + cmd.assert().success(); +} + +#[test] +fn append_context_example() { + Command::cargo_bin("bin_fixture") + .unwrap() + .assert() + .append_context("main", "no args") + .success(); +} + +#[test] +fn success_example() { + Command::cargo_bin("bin_fixture") + .unwrap() + .assert() + .success(); +} + +#[test] +fn failure_example() { + Command::cargo_bin("bin_fixture") + .unwrap() + .env("exit", "1") + .assert() + .failure(); +} + #[test] fn code_example() { - Command::main_binary() + Command::cargo_bin("bin_fixture") .unwrap() .env("exit", "42") .assert() .code(predicate::eq(42)); - // which can be shortened to: - Command::main_binary() + Command::cargo_bin("bin_fixture") .unwrap() .env("exit", "42") .assert() .code(42); + + Command::cargo_bin("bin_fixture") + .unwrap() + .env("exit", "42") + .assert() + .code(&[2, 42] as &[i32]); } #[test] fn stdout_example() { - Command::main_binary() + Command::cargo_bin("bin_fixture") + .unwrap() + .env("stdout", "hello") + .env("stderr", "world") + .assert() + .stdout(predicate::eq(b"hello\n" as &[u8])); + + Command::cargo_bin("bin_fixture") + .unwrap() + .env("stdout", "hello") + .env("stderr", "world") + .assert() + .stdout(predicate::str::similar("hello\n")); + + Command::cargo_bin("bin_fixture") .unwrap() .env("stdout", "hello") .env("stderr", "world") .assert() - .stdout(predicate::str::similar("hello\n").from_utf8()); + .stdout(b"hello\n" as &[u8]); - // which can be shortened to: - Command::main_binary() + Command::cargo_bin("bin_fixture") .unwrap() .env("stdout", "hello") .env("stderr", "world") @@ -42,29 +115,31 @@ fn stdout_example() { #[test] fn stderr_example() { - Command::main_binary() + Command::cargo_bin("bin_fixture") .unwrap() .env("stdout", "hello") .env("stderr", "world") .assert() - .stderr(predicate::str::similar("world\n").from_utf8()); + .stderr(predicate::eq(b"world\n" as &[u8])); - // which can be shortened to: - Command::main_binary() + Command::cargo_bin("bin_fixture") .unwrap() .env("stdout", "hello") .env("stderr", "world") .assert() - .stderr("world\n"); -} + .stderr(predicate::str::similar("world\n")); -#[test] -fn stdout_string() { - let expected = "hello\n".to_owned(); - Command::main_binary() + Command::cargo_bin("bin_fixture") .unwrap() .env("stdout", "hello") .env("stderr", "world") .assert() - .stdout(expected); + .stderr(b"world\n" as &[u8]); + + Command::cargo_bin("bin_fixture") + .unwrap() + .env("stdout", "hello") + .env("stderr", "world") + .assert() + .stderr("world\n"); } diff --git a/tests/cargo.rs b/tests/cargo.rs index 61a435f..7d166a8 100644 --- a/tests/cargo.rs +++ b/tests/cargo.rs @@ -3,23 +3,10 @@ extern crate escargot; extern crate predicates; use std::process; +use std::process::Command; use assert_cmd::prelude::*; -#[test] -fn main_binary() { - let mut cmd = process::Command::main_binary().unwrap(); - cmd.env("stdout", "42"); - cmd.assert().success().stdout("42\n"); -} - -#[test] -fn main_binary_with_empty_env() { - let mut cmd = process::Command::main_binary().unwrap(); - cmd.env_clear().env("stdout", "42"); - cmd.assert().success().stdout("42\n"); -} - #[test] fn cargo_binary() { let mut cmd = process::Command::cargo_bin("bin_fixture").unwrap(); @@ -35,26 +22,37 @@ fn cargo_binary_with_empty_env() { } #[test] -fn cargo_example() { - let mut cmd = process::Command::cargo_example("example_fixture").unwrap(); - cmd.env("stdout", "42"); - cmd.assert().success().stdout("42\n"); -} - -#[test] -fn cargo_example_with_empty_env() { - let mut cmd = process::Command::cargo_example("example_fixture").unwrap(); - cmd.env_clear().env("stdout", "42"); - cmd.assert().success().stdout("42\n"); -} - -#[test] -fn cargo_example_cache() { +fn mod_example() { let bin_under_test = escargot::CargoBuild::new() .bin("bin_fixture") .current_release() .current_target() .run() .unwrap(); - bin_under_test.command().unwrap(); + let mut cmd = bin_under_test.command(); + let output = cmd.unwrap(); + println!("{:?}", output); +} + +#[test] +#[should_panic] // No bin named `assert_cmd +fn trait_example() { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); + let output = cmd.unwrap(); + println!("{:?}", output); +} + +#[test] +#[should_panic] // No bin named `assert_cmd +fn cargo_bin_example_1() { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); + let output = cmd.unwrap(); + println!("{:?}", output); +} + +#[test] +fn cargo_bin_example_2() { + let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + let output = cmd.unwrap(); + println!("{:?}", output); } diff --git a/tests/examples.rs b/tests/examples.rs new file mode 100644 index 0000000..cfe3cf2 --- /dev/null +++ b/tests/examples.rs @@ -0,0 +1,22 @@ +extern crate assert_cmd; +extern crate escargot; +extern crate predicates; + +use std::process::Command; + +use assert_cmd::prelude::*; + +#[test] +fn lib_example() { + let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + cmd.assert().success(); + + let mut cmd = Command::cargo_bin("bin_fixture").unwrap(); + cmd.arg("-A") + .env("stdout", "hello") + .env("exit", "42") + .with_stdin() + .buffer("42"); + let assert = cmd.assert(); + assert.failure().code(42).stdout("hello\n"); +} From bf5d716c73e97e6cfe05ef10a35ac2d74f2d5780 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Sat, 26 Jan 2019 16:48:37 -0700 Subject: [PATCH 2/2] chore: Update CI --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index f731705..a0fdf37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,22 +11,22 @@ os: matrix: include: - env: RUSTFMT - rust: 1.29.1 # `stable`: Locking down for consistent behavior + rust: 1.31.0 # `stable`: Locking down for consistent behavior install: - - rustup component add rustfmt-preview + - rustup component add rustfmt script: - cargo fmt -- --check - env: RUSTFLAGS="-D warnings" - rust: 1.29.1 # `stable`: Locking down for consistent behavior + rust: 1.31.0 # `stable`: Locking down for consistent behavior install: script: - cargo check --tests --all-features - env: CLIPPY - rust: nightly-2018-07-17 + rust: 1.31.0 # `stable`: Locking down for consistent behavior install: - - rustup component add clippy-preview + - rustup component add clippy script: - - cargo clippy --all-features -- -D clippy + - cargo clippy --all-features install: - rustc -Vv