use std::convert::Infallible;
use std::fmt;
use std::marker::PhantomData;
use crate::core::{style, Format, Formatter, MatchFailure, Matcher, NegFormat};
use crate::matchers::option::BeSomeMatcher;
use crate::matchers::Expectation;
#[derive(Debug)]
pub struct ExpectationFormat<Actual> {
marker: PhantomData<Actual>,
pos_msg: String,
neg_msg: String,
}
impl<Actual> ExpectationFormat<Actual> {
pub fn new(pos_msg: impl Into<String>, neg_msg: impl Into<String>) -> Self {
Self {
marker: PhantomData,
pos_msg: pos_msg.into(),
neg_msg: neg_msg.into(),
}
}
}
impl<Actual> Format for ExpectationFormat<Actual>
where
Actual: fmt::Debug,
{
type Value = MatchFailure<Expectation<Actual>>;
fn fmt(&self, f: &mut Formatter, value: Self::Value) -> crate::Result<()> {
let expectation = value.unwrap();
f.set_style(style::important());
f.write_str("Expected:\n");
f.set_style(style::bad());
f.indented(style::indent(1), |f| {
f.write_str(format!("{:?}", expectation.actual));
Ok(())
})?;
f.write_char('\n');
f.set_style(style::important());
if value.is_pos() {
f.write_str(&self.pos_msg);
} else {
f.write_str(&self.neg_msg);
}
f.write_char('\n');
Ok(())
}
}
fn option_format<T>() -> ExpectationFormat<Option<T>> {
ExpectationFormat::new("to be Some(_)", "to be None")
}
pub fn be_some<'a, T>() -> Matcher<'a, Option<T>, T, Option<Infallible>>
where
T: fmt::Debug + 'a,
{
Matcher::transform(BeSomeMatcher::new(), option_format())
}
pub fn be_none<'a, T>() -> Matcher<'a, Option<T>, Option<Infallible>, T>
where
T: fmt::Debug + 'a,
{
Matcher::transform_neg(BeSomeMatcher::new(), NegFormat(option_format()))
}
#[cfg(test)]
mod tests {
use super::{be_none, be_some};
use crate::expect;
fn some() -> Option<()> {
Some(())
}
fn none() -> Option<()> {
None
}
#[test]
fn succeeds_when_some() {
expect!(some()).to(be_some());
}
#[test]
fn succeeds_when_not_some() {
expect!(none()).to_not(be_some());
}
#[test]
#[should_panic]
fn fails_when_some() {
expect!(some()).to_not(be_some());
}
#[test]
#[should_panic]
fn fails_when_not_some() {
expect!(none()).to(be_some());
}
#[test]
fn succeeds_when_none() {
expect!(none()).to(be_none());
}
#[test]
fn succeeds_when_not_none() {
expect!(some()).to_not(be_none());
}
#[test]
#[should_panic]
fn fails_when_none() {
expect!(none()).to_not(be_none());
}
#[test]
#[should_panic]
fn fails_when_not_none() {
expect!(some()).to(be_none());
}
}