fluent_test/backend/matchers/
equality.rs

1use crate::backend::Assertion;
2use crate::backend::assertions::sentence::AssertionSentence;
3use std::fmt::Debug;
4
5pub trait EqualityMatchers<T> {
6    /// Check if the value is equal to the expected value
7    fn to_equal(self, expected: T) -> Self;
8
9    /// Type-specific version of to_equal to avoid trait conflicts
10    fn to_equal_value(self, expected: T) -> Self;
11}
12
13/// Helper trait for equality comparison
14trait AsEqualityComparable<T> {
15    fn equals<U: PartialEq<T>>(&self, expected: &U) -> bool;
16}
17
18// Implementation for T comparing with anything that can be compared with T
19impl<T: PartialEq> AsEqualityComparable<T> for T {
20    fn equals<U: PartialEq<T>>(&self, expected: &U) -> bool {
21        expected == self
22    }
23}
24
25// Implementation for &T comparing with anything that can be compared with T
26impl<T: PartialEq> AsEqualityComparable<T> for &T {
27    fn equals<U: PartialEq<T>>(&self, expected: &U) -> bool {
28        expected == *self
29    }
30}
31
32// Generic implementation for both T and &T expected values
33impl<V, T> EqualityMatchers<T> for Assertion<V>
34where
35    T: Debug + PartialEq + Clone,
36    V: AsEqualityComparable<T> + Debug + Clone,
37{
38    fn to_equal(self, expected: T) -> Self {
39        return self.to_equal_value(expected);
40    }
41
42    fn to_equal_value(self, expected: T) -> Self {
43        let result = self.value.equals(&expected);
44        let sentence = AssertionSentence::new("be", format!("equal to {:?}", expected));
45
46        return self.add_step(sentence, result);
47    }
48}
49
50// We no longer need a separate implementation for &T, since the generic implementation handles it
51
52#[cfg(test)]
53mod tests {
54    use crate::prelude::*;
55
56    #[test]
57    fn test_equality() {
58        // Disable deduplication for tests
59        crate::Reporter::disable_deduplication();
60
61        // Test with integers
62        expect!(42).to_equal(42);
63        expect!(42).not().to_equal(100);
64
65        // Test with strings
66        expect!("hello").to_equal("hello");
67        expect!("hello").not().to_equal("world");
68
69        // Test with floating point
70        expect!(3.14).to_equal(3.14);
71        expect!(3.14).not().to_equal(2.71);
72
73        // Test with boolean
74        expect!(true).to_equal(true);
75        expect!(true).not().to_equal(false);
76    }
77
78    #[test]
79    #[should_panic(expected = "be equal to")]
80    fn test_equality_fails() {
81        // This should fail because 42 != 43
82        let _assertion = expect!(42).to_equal(43);
83        std::hint::black_box(_assertion);
84    }
85
86    #[test]
87    #[should_panic(expected = "not be equal to")]
88    fn test_equality_not_fails() {
89        // This should fail because !(42 != 42)
90        let _assertion = expect!(42).not().to_equal(42);
91        std::hint::black_box(_assertion);
92    }
93}