use super::{AssertionFailure, Spec};
use std::borrow::Borrow;
use std::fmt::Debug;
pub trait ResultAssertions<'s, T, E>
where
T: Debug,
E: Debug,
{
fn is_ok(&mut self) -> Spec<'s, T>;
fn is_err(&mut self) -> Spec<'s, E>;
}
pub trait ContainingResultAssertions<T, E>
where
T: Debug,
E: Debug,
{
fn is_ok_containing<V: Borrow<T>>(&mut self, expected_value: V)
where
T: PartialEq;
fn is_err_containing<V: Borrow<E>>(&mut self, expected_value: V)
where
E: PartialEq;
}
impl<'s, T, E> ContainingResultAssertions<T, E> for Spec<'s, Result<T, E>>
where
T: Debug,
E: Debug,
{
fn is_ok_containing<V: Borrow<T>>(&mut self, expected_value: V)
where
T: PartialEq,
{
let borrowed_expected_value = expected_value.borrow();
match *self.subject {
Ok(ref val) => {
if !val.eq(borrowed_expected_value) {
AssertionFailure::from_spec(self)
.with_expected(build_detail_message("ok", borrowed_expected_value))
.with_actual(build_detail_message("ok", val))
.fail();
}
}
Err(ref val) => {
AssertionFailure::from_spec(self)
.with_expected(build_detail_message("ok", borrowed_expected_value))
.with_actual(build_detail_message("err", val))
.fail();
}
}
}
fn is_err_containing<V: Borrow<E>>(&mut self, expected_value: V)
where
E: PartialEq,
{
let borrowed_expected_value = expected_value.borrow();
match *self.subject {
Err(ref val) => {
if !val.eq(borrowed_expected_value) {
AssertionFailure::from_spec(self)
.with_expected(build_detail_message("err", borrowed_expected_value))
.with_actual(build_detail_message("err", val))
.fail();
}
}
Ok(ref val) => {
AssertionFailure::from_spec(self)
.with_expected(build_detail_message("err", borrowed_expected_value))
.with_actual(build_detail_message("ok", val))
.fail();
}
}
}
}
fn build_detail_message<T: Debug>(variant: &'static str, value: T) -> String {
format!("Result[{}] containing <{:?}>", variant, value)
}
impl<'s, T, E> ResultAssertions<'s, T, E> for Spec<'s, Result<T, E>>
where
T: Debug,
E: Debug,
{
fn is_ok(&mut self) -> Spec<'s, T> {
match *self.subject {
Ok(ref val) => Spec {
subject: val,
subject_name: self.subject_name,
location: self.location.clone(),
description: self.description,
},
Err(ref err) => {
AssertionFailure::from_spec(self)
.with_expected("result[ok]".to_string())
.with_actual(format!("result[error]<{:?}>", err))
.fail();
unreachable!();
}
}
}
fn is_err(&mut self) -> Spec<'s, E> {
match *self.subject {
Err(ref val) => Spec {
subject: val,
subject_name: self.subject_name,
location: self.location.clone(),
description: self.description,
},
Ok(ref val) => {
AssertionFailure::from_spec(self)
.with_expected("result[error]".to_string())
.with_actual(format!("result[ok]<{:?}>", val))
.fail();
unreachable!();
}
}
}
}
#[cfg(test)]
mod tests {
use super::super::prelude::*;
#[test]
fn should_not_panic_if_result_is_expected_to_be_ok_and_is() {
let result: Result<&str, &str> = Ok("Hello");
assert_that(&result).is_ok();
}
#[test]
#[should_panic(expected = "\n\texpected: result[ok]\n\t but was: result[error]<\"Oh no\">")]
fn should_panic_if_result_is_expected_to_be_ok_and_is_not() {
let result: Result<&str, &str> = Err("Oh no");
assert_that(&result).is_ok();
}
#[test]
fn should_return_unwrapped_value_if_subject_is_ok() {
let result: Result<&str, &str> = Ok("Hello");
assert_that(&result).is_ok().is_equal_to(&"Hello");
}
#[test]
fn should_not_panic_if_result_is_expected_to_be_error_and_is() {
let result: Result<&str, &str> = Err("Oh no");
assert_that(&result).is_err();
}
#[test]
#[should_panic(expected = "\n\texpected: result[error]\n\t but was: result[ok]<\"Hello\">")]
fn should_panic_if_result_is_expected_to_be_error_and_is_not() {
let result: Result<&str, &str> = Ok("Hello");
assert_that(&result).is_err();
}
#[test]
fn should_return_unwrapped_value_if_subject_is_err() {
let result: Result<&str, &str> = Err("Hello");
assert_that(&result).is_err().is_equal_to(&"Hello");
}
#[test]
fn is_ok_containing_should_allow_multiple_borrow_forms() {
let result: Result<&str, &str> = Ok("Hello");
assert_that(&result).is_ok_containing("Hello");
assert_that(&result).is_ok_containing(&mut "Hello");
assert_that(&result).is_ok_containing(&"Hello");
}
#[test]
fn should_not_panic_if_result_is_ok_with_expected_value() {
let result: Result<&str, &str> = Ok("Hello");
assert_that(&result).is_ok_containing(&"Hello");
}
#[test]
fn should_not_panic_if_result_is_ok_with_uncomparable_ok() {
#[derive(Debug)]
struct Incomparable;
let result: Result<&str, Incomparable> = Ok("Hello");
assert_that(&result).is_ok_containing(&"Hello");
}
#[test]
#[should_panic(expected = "\n\texpected: Result[ok] containing <\"Hi\">\
\n\t but was: Result[ok] containing <\"Hello\">")]
fn should_panic_if_result_is_ok_without_expected_value() {
let result: Result<&str, &str> = Ok("Hello");
assert_that(&result).is_ok_containing(&"Hi");
}
#[test]
#[should_panic(expected = "\n\texpected: Result[ok] containing <\"Hi\">\
\n\t but was: Result[err] containing <\"Hi\">")]
fn should_panic_if_result_is_err_if_ok_with_value_expected() {
let result: Result<&str, &str> = Err("Hi");
assert_that(&result).is_ok_containing(&"Hi");
}
#[test]
fn is_error_containing_should_allow_multiple_borrow_forms() {
let result: Result<&str, &str> = Err("Oh no");
assert_that(&result).is_err_containing("Oh no");
assert_that(&result).is_err_containing(&mut "Oh no");
assert_that(&result).is_err_containing(&"Oh no");
}
#[test]
fn should_not_panic_if_result_is_err_with_expected_value() {
let result: Result<&str, &str> = Err("Oh no");
assert_that(&result).is_err_containing(&"Oh no");
}
#[test]
fn should_not_panic_if_result_is_err_with_uncomparable_ok() {
#[derive(Debug)]
struct Incomparable;
let result: Result<Incomparable, &str> = Err("Oh no");
assert_that(&result).is_err_containing(&"Oh no");
}
#[test]
#[should_panic(expected = "\n\texpected: Result[err] containing <\"Oh no\">\
\n\t but was: Result[err] containing <\"Whoops\">")]
fn should_panic_if_result_is_err_without_expected_value() {
let result: Result<&str, &str> = Err("Whoops");
assert_that(&result).is_err_containing(&"Oh no");
}
#[test]
#[should_panic(expected = "\n\texpected: Result[err] containing <\"Oh no\">\
\n\t but was: Result[ok] containing <\"Oh no\">")]
fn should_panic_if_result_is_ok_if_err_with_value_expected() {
let result: Result<&str, &str> = Ok("Oh no");
assert_that(&result).is_err_containing(&"Oh no");
}
}