use std::fmt;
use std::process;
use std::str;
use predicates;
use errors::output_fmt;
pub trait OutputAssertExt {
fn assert(self) -> Assert;
}
impl OutputAssertExt for process::Output {
fn assert(self) -> Assert {
Assert::new(self)
}
}
impl<'c> OutputAssertExt for &'c mut process::Command {
fn assert(self) -> Assert {
let output = self.output().unwrap();
Assert::new(output).set_cmd(format!("{:?}", self))
}
}
#[derive(Debug)]
pub struct Assert {
output: process::Output,
cmd: Option<String>,
stdin: Option<Vec<u8>>,
}
impl Assert {
pub fn new(output: process::Output) -> Self {
Self {
output,
cmd: None,
stdin: None,
}
}
pub fn set_cmd(mut self, cmd: String) -> Self {
self.cmd = Some(cmd);
self
}
pub fn set_stdin(mut self, stdin: Vec<u8>) -> Self {
self.stdin = Some(stdin);
self
}
pub fn get_output(&self) -> &process::Output {
&self.output
}
pub fn success(self) -> Self {
if !self.output.status.success() {
panic!("Unexpected failure\n{}", self);
}
self
}
pub fn failure(self) -> Self {
if self.output.status.success() {
panic!("Unexpected success\n{}", self);
}
self
}
pub fn interrupted(self) -> Self {
if self.output.status.code().is_some() {
panic!("Unexpected completion\n{}", self);
}
self
}
pub fn code(self, pred: &predicates::Predicate<i32>) -> Self {
let actual_code = self.output
.status
.code()
.unwrap_or_else(|| panic!("Command interrupted\n{}", self));
if !pred.eval(&actual_code) {
panic!("Unexpected return code\n{}", self);
}
self
}
pub fn stdout(self, pred: &predicates::Predicate<Vec<u8>>) -> Self {
{
let actual = &self.output.stdout;
if !pred.eval(actual) {
panic!("Unexpected stdout\n{}", self);
}
}
self
}
pub fn stderr(self, pred: &predicates::Predicate<Vec<u8>>) -> Self {
{
let actual = &self.output.stderr;
if !pred.eval(actual) {
panic!("Unexpected stderr\n{}", self);
}
}
self
}
}
impl fmt::Display for Assert {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref cmd) = self.cmd {
writeln!(f, "command=`{}`", cmd)?;
}
if let Some(ref stdin) = self.stdin {
if let Ok(stdin) = str::from_utf8(stdin) {
writeln!(f, "stdin=```{}```", stdin)?;
} else {
writeln!(f, "stdin=```{:?}```", stdin)?;
}
}
output_fmt(&self.output, f)
}
}