//! This module has some functions that permit to see the
//! assert messages. Unfortunately, this cannot be reliably
//! unit-tested, because, well a human must see the output
//! message to see if it is human-readable.
//!
//! Each module is deactivated by default, and must be
//! activated by hand to see the assertion error message:
//! just comment the `cfg` line to run it.

#[cfg(not(test))]
#[test]
fn answer_example() {
    use prelude::*;

    let the_answer: Result<i32, _> = Err("Oops, error!");
    theory!(the_answer).should().not().be_an_error()
        .and_should().contain(42)
        .because("we need the answer");
}

#[cfg(not(test))]
mod be_equal_to {
    use prelude::*;

    #[test]
    fn left_and_right_have_same_display() {
        let zero = 2; //Oops
        theory!(zero).should().not().be_equal_to(2)
            .and_should().be_equal_to(0)
            .because("of basic arithmetic");
    }

    #[derive(Debug)]
    struct Foo(i32);

    #[derive(Debug)]
    struct Bar(i32);

    impl PartialEq<Bar> for Foo {
        fn eq(&self, other: &Bar) -> bool {
            other.0 == self.0
        }
    }

    #[test]
    fn left_and_right_do_not_have_same_display_positive() {
        let foo = Foo(2);
        let bar = Bar(3);
        theory!(foo).should().be_equal_to(bar);
    }

    #[test]
    fn left_and_right_do_not_have_same_display_negative() {
        let foo = Foo(2);
        let bar = Bar(2);
        theory!(foo).should().not().be_equal_to(bar);
    }
}

#[cfg(not(test))]
mod be_equal_to_precision {
    use prelude::*;

    #[test]
    fn positive() {
        let one = 1.01; //Oops
        theory!(one).should().be_equal_to(1.).with_precision(0.01);
    }

    #[test]
    fn negative() {
        let far_from_one = 1.01; //Oops
        theory!(far_from_one).should().not().be_equal_to(1.).with_precision(0.1);
    }
}

#[cfg(not(test))]
mod be_an_error {
    use prelude::*;

    #[test]
    fn negative() {
        let result = "two".parse::<i32>();
        theory!(result).should().not().be_an_error();
    }

    #[test]
    fn positive() {
        let result = "2".parse::<i32>();
        theory!(result).should().be_an_error();
    }
}

#[cfg(not(test))]
mod be_this_error {
    use prelude::*;

    #[test]
    fn negative() {
        let parse_error = match "?".parse::<i32>().unwrap_err();
        let result = "two".parse::<i32>();
        theory!(result).should().not().be_this_error(parse_error);
    }

    #[test]
    fn positive_ok() {
        let parse_error = match "".parse::<i32>().unwrap_err();
        let result = Ok(0);//"two".parse::<i32>();
        theory!(result).should().be_this_error(parse_error);
    }

    #[test]
    fn positive_err() {
        let parse_error = match "".parse::<i32>().unwrap_err();
        let result = "two".parse::<i32>();
        theory!(result).should().be_this_error(parse_error);
    }
}

#[cfg(not(test))]
mod big_message {
    use prelude::*;

    #[test]
    fn big_iterator() {
        let v1: Vec<_> = (1..100).collect();
        let v2: Vec<_> = (1..101).collect();
        theory!(v1).should().be_equal_to(v2);
    }
}

#[cfg(not(test))]
mod contain {
    use prelude::*;

    #[test]
    fn positive() {
        let x = vec![1, 2];
        theory!(x).should().contain(3);
    }

    #[test]
    fn negative() {
        let x = vec![1, 2, 3];
        theory!(x).should().not().contain(3);
    }
}

#[cfg(not(test))]
mod be_empty {
    use prelude::*;

    #[test]
    fn positive() {
        let empty = vec![0]; //Oops
        theory!(empty).should().be_empty();
    }

    #[test]
    fn negative() {
        let my_vec = Vec::<i32>::new(); //Oops
        theory!(my_vec).should().not().be_empty();
    }
}
