use std::borrow::Borrow;
use std::fmt::Debug;
use crate::assert_that;
use crate::base::{AssertionApi, AssertionResult, AssertionStrategy, Subject};
pub trait ResultAssertion<R, OK, ERR> {
#[track_caller]
fn is_ok(&self) -> R;
#[track_caller]
fn is_err(&self) -> R;
#[track_caller]
fn has_ok<B: Borrow<OK>>(&self, expected: B) -> R
where
OK: PartialEq;
#[track_caller]
fn has_err<B: Borrow<ERR>>(&self, expected: B) -> R
where
ERR: PartialEq;
#[track_caller]
fn ok(&self) -> Subject<OK, (), R>;
#[track_caller]
fn err(&self) -> Subject<ERR, (), R>;
}
impl<R, OK: Debug, ERR: Debug> ResultAssertion<R, OK, ERR> for Subject<'_, Result<OK, ERR>, (), R>
where
AssertionResult: AssertionStrategy<R>,
{
fn is_ok(&self) -> R {
if self.actual().is_ok() {
self.new_result().do_ok()
} else {
self.new_result()
.add_fact("expected", "Result::Err")
.add_fact("actual", "Result::Ok")
.add_splitter()
.add_fact("actual", format!("{:?}", self.actual()))
.do_fail()
}
}
fn is_err(&self) -> R {
if self.actual().is_err() {
self.new_result().do_ok()
} else {
self.new_result()
.add_fact("expected", "Result::Err")
.add_fact("actual", "Result::Ok")
.add_splitter()
.add_fact("actual", format!("{:?}", self.actual()))
.do_fail()
}
}
fn has_ok<B: Borrow<OK>>(&self, expected: B) -> R
where
OK: PartialEq,
{
match self.actual() {
Ok(actual) if actual.eq(expected.borrow()) => self.new_result().do_ok(),
Ok(actual) => self
.new_result()
.add_fact("expected", format!("Ok({:?})", expected.borrow()))
.add_fact("actual", format!("Ok({:?})", actual))
.do_fail(),
Err(actual) => self
.new_result()
.add_fact("expected", format!("Ok({:?})", expected.borrow()))
.add_fact("actual", format!("Err({:?})", actual))
.do_fail(),
}
}
fn has_err<B: Borrow<ERR>>(&self, expected: B) -> R
where
ERR: PartialEq,
{
match self.actual() {
Err(actual) if actual.eq(expected.borrow()) => self.new_result().do_ok(),
Err(actual) => self
.new_result()
.add_fact("expected", format!("Err({:?})", expected.borrow()))
.add_fact("actual", format!("Err({:?})", actual))
.do_fail(),
Ok(actual) => self
.new_result()
.add_fact("expected", format!("Err({:?})", expected.borrow()))
.add_fact("actual", format!("Ok({:?})", actual))
.do_fail(),
}
}
fn ok(&self) -> Subject<OK, (), R> {
assert_that!(*self.actual()).is_ok();
self.new_subject(self.actual().as_ref().ok().unwrap(), Some(format!("{}.ok", self.description_or_expr())), ())
}
fn err(&self) -> Subject<ERR, (), R> {
assert_that!(*self.actual()).is_err();
self.new_subject(self.actual().as_ref().err().unwrap(), Some(format!("{}.err", self.description_or_expr())), ())
}
}
#[cfg(test)]
mod tests {
use crate::ComparableAssertion;
use crate::testing::*;
use super::*;
#[test]
fn is_ok() {
assert_that!(Result::<_, ()>::Ok(0)).is_ok();
assert_that!(Result::<_, ()>::Ok("23")).is_ok();
assert_that!(Result::<_, ()>::Ok(())).is_ok();
}
#[test]
fn is_err() {
assert_that!(Result::<(), _>::Err(0)).is_err();
assert_that!(Result::<(), _>::Err("23")).is_err();
assert_that!(Result::<(), _>::Err(())).is_err();
}
#[test]
fn has_ok() {
assert_that!(Result::<_, ()>::Ok(0)).has_ok(0);
assert_that!(Result::<_, ()>::Ok("23")).has_ok("23");
assert_that!(Result::<_, ()>::Ok(())).has_ok(());
assert_that!(check_that!(Result::<_, ()>::Ok(0)).has_ok(1)).facts_are(vec![
Fact::new("expected", "Ok(1)"),
Fact::new("actual", "Ok(0)"),
]);
assert_that!(check_that!(Result::<(), ()>::Err(())).has_ok(())).facts_are(vec![
Fact::new("expected", "Ok(())"),
Fact::new("actual", "Err(())"),
]);
assert_that!(check_that!(Result::<&str, &str>::Err("")).has_ok("")).facts_are(vec![
Fact::new("expected", r#"Ok("")"#),
Fact::new("actual", r#"Err("")"#),
]);
assert_that!(check_that!(Result::<&str, &str>::Ok("")).has_ok("expected")).facts_are(vec![
Fact::new("expected", r#"Ok("expected")"#),
Fact::new("actual", r#"Ok("")"#),
]);
}
#[test]
fn has_err() {
assert_that!(Result::<(), _>::Err(0)).has_err(0);
assert_that!(Result::<(), _>::Err("23")).has_err("23");
assert_that!(Result::<(), _>::Err(())).has_err(());
assert_that!(check_that!(Result::<(), _>::Err(0)).has_err(1)).facts_are(vec![
Fact::new("expected", "Err(1)"),
Fact::new("actual", "Err(0)"),
]);
assert_that!(check_that!(Result::<(), ()>::Ok(())).has_err(())).facts_are(vec![
Fact::new("expected", "Err(())"),
Fact::new("actual", "Ok(())"),
]);
assert_that!(check_that!(Result::<&str, &str>::Ok("")).has_err("")).facts_are(vec![
Fact::new("expected", r#"Err("")"#),
Fact::new("actual", r#"Ok("")"#),
]);
assert_that!(check_that!(Result::<&str, &str>::Err("")).has_err("expected")).facts_are(
vec![
Fact::new("expected", r#"Err("expected")"#),
Fact::new("actual", r#"Err("")"#),
],
);
}
#[test]
fn ok() {
assert_that!(Result::<f64,()>::Ok(0.)).ok().is_at_most(1.);
}
#[test]
#[should_panic]
fn ok_panic() {
assert_that!(Result::<f64,()>::Err(())).ok().is_at_most(1.);
}
#[test]
fn err() {
assert_that!(Result::<(), f64>::Err(0.)).err().is_at_most(1.);
}
#[test]
#[should_panic]
fn err_panic() {
assert_that!(Result::<(), f64>::Ok(())).err().is_at_most(1.);
}
}