pub fn lt<ExpectedT>(expected: ExpectedT) -> __internal::LtMatcher<ExpectedT> {
__internal::LtMatcher { expected }
}
pub mod __internal {
use crate::{
description::Description,
matcher::{Describable, Matcher, MatcherResult},
};
use core::fmt::Debug;
#[doc(hidden)]
pub struct LtMatcher<ExpectedT> {
pub(super) expected: ExpectedT,
}
impl<ActualT: Debug + PartialOrd<ExpectedT>, ExpectedT: Debug> Matcher<ActualT>
for LtMatcher<ExpectedT>
{
fn matches(&self, actual: &ActualT) -> MatcherResult {
(*actual < self.expected).into()
}
}
impl<ExpectedT: Debug> Describable for LtMatcher<ExpectedT> {
fn describe(&self, matcher_result: MatcherResult) -> Description {
match matcher_result {
MatcherResult::Match => format!("is less than {:?}", self.expected).into(),
MatcherResult::NoMatch => {
format!("is greater than or equal to {:?}", self.expected).into()
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::lt;
use crate::matcher::{Matcher, MatcherResult};
use crate::prelude::*;
use alloc::string::ToString;
use indoc::indoc;
#[test]
fn lt_matches_i32_with_i32() -> TestResult<()> {
let actual: i32 = 10000;
let expected: i32 = 20000;
verify_that!(actual, lt(expected))
}
#[test]
fn lt_does_not_match_equal_i32() -> TestResult<()> {
let matcher = lt(10);
let result = matcher.matches(&10);
verify_that!(result, eq(MatcherResult::NoMatch))
}
#[test]
fn lt_does_not_match_lower_i32() -> TestResult<()> {
let matcher = lt(-50);
let result = matcher.matches(&50);
verify_that!(result, eq(MatcherResult::NoMatch))
}
#[test]
fn lt_matches_lesser_str() -> TestResult<()> {
verify_that!("A", lt("B"))
}
#[test]
fn lt_does_not_match_bigger_str() -> TestResult<()> {
let matcher = lt("ab");
let result = matcher.matches(&"az");
verify_that!(result, eq(MatcherResult::NoMatch))
}
#[test]
fn lt_mismatch_contains_actual_and_expected() -> TestResult<()> {
let result = verify_that!(481, lt(45));
let formatted_message = format!("{}", result.unwrap_err());
verify_that!(
formatted_message.as_str(),
contains_substring(indoc!(
"
Value of: 481
Expected: is less than 45
Actual: 481,
which is greater than or equal to 45
"
))
)
}
#[cfg(feature = "std")]
#[test]
fn lt_matches_owned_osstring_reference_with_string_reference() -> TestResult<()> {
use std::ffi::OsString;
let expected = "C";
let actual: OsString = "B".to_string().into();
verify_that!(&actual, lt(expected))
}
#[cfg(feature = "std")]
#[test]
fn lt_matches_ipv6addr_with_ipaddr() -> TestResult<()> {
use std::net::IpAddr;
use std::net::Ipv6Addr;
let actual: IpAddr = "127.0.0.1".parse().unwrap();
let expected: Ipv6Addr = "2001:4860:4860::8844".parse().unwrap();
verify_that!(actual, lt(expected))
}
#[test]
fn lt_matches_with_custom_partial_ord() -> TestResult<()> {
#[derive(Debug)]
struct VeryLowNumber {}
impl core::cmp::PartialEq<u32> for VeryLowNumber {
fn eq(&self, _other: &u32) -> bool {
false
}
}
impl core::cmp::PartialOrd<u32> for VeryLowNumber {
fn partial_cmp(&self, _other: &u32) -> Option<core::cmp::Ordering> {
Some(core::cmp::Ordering::Less)
}
}
impl core::cmp::PartialEq<VeryLowNumber> for u32 {
fn eq(&self, _other: &VeryLowNumber) -> bool {
false
}
}
impl core::cmp::PartialOrd<VeryLowNumber> for u32 {
fn partial_cmp(&self, _other: &VeryLowNumber) -> Option<core::cmp::Ordering> {
Some(core::cmp::Ordering::Greater)
}
}
let actual = VeryLowNumber {};
let expected: u32 = 42;
verify_that!(actual, lt(expected))
}
}