1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::core::{Join, Matcher};
use std::fmt;

/// A matcher for types that conform to `PartialOrd` trait.
pub struct PartialOrder<E> {
    expected: E,
    order: Order,
}

impl<E> PartialOrder<E> {
    fn new(expected: E, order: Order) -> PartialOrder<E> {
        PartialOrder {
            expected: expected,
            order: order,
        }
    }
}

impl<A, E> Matcher<A, E> for PartialOrder<E>
where
    A: PartialOrd<E> + fmt::Debug,
    E: fmt::Debug,
{
    fn failure_message(&self, join: Join, actual: &A) -> String {
        format!(
            "expected {} be {} <{:?}>, got <{:?}>",
            join, self.order, self.expected, actual
        )
    }

    fn matches(&self, actual: &A) -> bool {
        match self.order {
            Order::LessThan => *actual < self.expected,
            Order::LessOrEqualTo => *actual <= self.expected,
            Order::GreaterThan => *actual > self.expected,
            Order::GreaterOrEqualTo => *actual >= self.expected,
        }
    }
}

/// Returns a new `PartialOrder` (less than) matcher.
pub fn be_less_than<E>(expected: E) -> PartialOrder<E> {
    PartialOrder::new(expected, Order::LessThan)
}

/// Returns a new `PartialOrder` (less or equal to) matcher.
pub fn be_less_or_equal_to<E>(expected: E) -> PartialOrder<E> {
    PartialOrder::new(expected, Order::LessOrEqualTo)
}

/// Returns a new `PartialOrder` (greater than) matcher.
pub fn be_greater_than<E>(expected: E) -> PartialOrder<E> {
    PartialOrder::new(expected, Order::GreaterThan)
}

/// Returns a new `PartialOrder` (greater or equal to) matcher.
pub fn be_greater_or_equal_to<E>(expected: E) -> PartialOrder<E> {
    PartialOrder::new(expected, Order::GreaterOrEqualTo)
}

enum Order {
    LessThan,
    LessOrEqualTo,
    GreaterThan,
    GreaterOrEqualTo,
}

impl fmt::Display for Order {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        let order = match *self {
            Order::LessThan => "less than",
            Order::LessOrEqualTo => "less or equal to",
            Order::GreaterThan => "greater than",
            Order::GreaterOrEqualTo => "greater or equal to",
        };
        fmt.write_str(order)
    }
}

#[cfg(test)]
mod tests {
    use super::{be_greater_or_equal_to, be_greater_than, be_less_or_equal_to, be_less_than};
    use crate::core::expect;

    #[test]
    fn be_less_than_one_failure_message() {
        expect(1)
            .to(be_less_than(1))
            .assert_eq_message("expected to be less than <1>, got <1>");
    }

    #[test]
    fn be_less_or_equal_to_one_failure_message() {
        expect(2)
            .to(be_less_or_equal_to(1))
            .assert_eq_message("expected to be less or equal to <1>, got <2>");
    }

    #[test]
    fn be_greater_than_zero_failure_message() {
        expect(0)
            .to(be_greater_than(0))
            .assert_eq_message("expected to be greater than <0>, got <0>");
    }

    #[test]
    fn be_greater_or_equal_to_zero_failure_message() {
        expect(-1)
            .to(be_greater_or_equal_to(0))
            .assert_eq_message("expected to be greater or equal to <0>, got <-1>");
    }
}