diff --git a/src/lib.rs b/src/lib.rs index 215c1fe..2edd454 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -309,6 +309,7 @@ impl Assert { self.expect_stdout = Some(OutputAssertion { expect: output.into(), fuzzy: true, + expected_result: true, kind: StdOut, }); self @@ -329,6 +330,7 @@ impl Assert { self.expect_stdout = Some(OutputAssertion { expect: output.into(), fuzzy: false, + expected_result: true, kind: StdOut, }); self @@ -351,6 +353,7 @@ impl Assert { self.expect_stderr = Some(OutputAssertion { expect: output.into(), fuzzy: true, + expected_result: true, kind: StdErr, }); self @@ -373,6 +376,99 @@ impl Assert { self.expect_stderr = Some(OutputAssertion { expect: output.into(), fuzzy: false, + expected_result: true, + kind: StdErr, + }); + self + } + + /// Expect the command's output to not **contain** `output`. + /// + /// # Examples + /// + /// ```rust + /// extern crate assert_cli; + /// + /// assert_cli::Assert::command(&["echo", "42"]) + /// .doesnt_print("73") + /// .execute() + /// .unwrap(); + /// ``` + pub fn doesnt_print>(mut self, output: O) -> Self { + self.expect_stdout = Some(OutputAssertion { + expect: output.into(), + fuzzy: true, + expected_result: false, + kind: StdOut, + }); + self + } + + /// Expect the command to output to not be **exactly** this `output`. + /// + /// # Examples + /// + /// ```rust + /// extern crate assert_cli; + /// + /// assert_cli::Assert::command(&["echo", "42"]) + /// .doesnt_print_exactly("73") + /// .execute() + /// .unwrap(); + /// ``` + pub fn doesnt_print_exactly>(mut self, output: O) -> Self { + self.expect_stdout = Some(OutputAssertion { + expect: output.into(), + fuzzy: false, + expected_result: false, + kind: StdOut, + }); + self + } + + /// Expect the command's stderr output to not **contain** `output`. + /// + /// # Examples + /// + /// ```rust + /// extern crate assert_cli; + /// + /// assert_cli::Assert::command(&["cat", "non-existing-file"]) + /// .fails() + /// .and() + /// .doesnt_print_error("content") + /// .execute() + /// .unwrap(); + /// ``` + pub fn doesnt_print_error>(mut self, output: O) -> Self { + self.expect_stderr = Some(OutputAssertion { + expect: output.into(), + fuzzy: true, + expected_result: false, + kind: StdErr, + }); + self + } + + /// Expect the command to output to not be **exactly** this `output` to stderr. + /// + /// # Examples + /// + /// ```rust + /// extern crate assert_cli; + /// + /// assert_cli::Assert::command(&["cat", "non-existing-file"]) + /// .fails_with(1) + /// .and() + /// .doesnt_print_error_exactly("content") + /// .execute() + /// .unwrap(); + /// ``` + pub fn doesnt_print_error_exactly>(mut self, output: O) -> Self { + self.expect_stderr = Some(OutputAssertion { + expect: output.into(), + fuzzy: false, + expected_result: false, kind: StdErr, }); self diff --git a/src/output.rs b/src/output.rs index 34c975c..b95fee2 100644 --- a/src/output.rs +++ b/src/output.rs @@ -11,13 +11,19 @@ use diff; pub struct OutputAssertion { pub expect: String, pub fuzzy: bool, + pub expected_result: bool, pub kind: T, } impl OutputAssertion { fn matches_fuzzy(&self, got: &str) -> Result<()> { - if !got.contains(&self.expect) { - bail!(ErrorKind::OutputMismatch(self.expect.clone(), got.into())); + let result = got.contains(&self.expect); + if result != self.expected_result { + if self.expected_result { + bail!(ErrorKind::OutputDoesntContain(self.expect.clone(), got.into())); + } else { + bail!(ErrorKind::OutputContains(self.expect.clone(), got.into())); + } } Ok(()) @@ -25,10 +31,15 @@ impl OutputAssertion { fn matches_exact(&self, got: &str) -> Result<()> { let differences = Changeset::new(self.expect.trim(), got.trim(), "\n"); - - if differences.distance > 0 { - let nice_diff = diff::render(&differences)?; - bail!(ErrorKind::ExactOutputMismatch(nice_diff)); + let result = differences.distance == 0; + + if result != self.expected_result { + if self.expected_result { + let nice_diff = diff::render(&differences)?; + bail!(ErrorKind::OutputDoesntMatch(nice_diff)); + } else { + bail!(ErrorKind::OutputMatches(got.to_owned())); + } } Ok(()) @@ -88,14 +99,22 @@ mod errors { Fmt(::std::fmt::Error); } errors { - OutputMismatch(expected: String, got: String) { + OutputDoesntContain(expected: String, got: String) { description("Output was not as expected") display("expected to contain {:?}, got {:?}", expected, got) } - ExactOutputMismatch(diff: String) { + OutputContains(expected: String, got: String) { + description("Output was not as expected") + display("expected to not contain {:?}, got {:?}", expected, got) + } + OutputDoesntMatch(diff: String) { description("Output was not as expected") display("{}", diff) } + OutputMatches(got: String) { + description("Output was not as expected") + display("{}", got) + } } } }