Skip to main content

rxpect/
lib.rs

1#![doc=include_str!("../README.md")]
2mod borrow;
3#[cfg(feature = "diff")]
4pub mod diff;
5mod expectation_list;
6pub mod expectations;
7mod projection;
8mod root;
9
10pub use borrow::BorrowedOrOwned;
11pub use expectation_list::ExpectationList;
12pub use projection::ExpectProjection;
13pub use projection::ProjectedExpectationsBuilder;
14pub use root::OwnedExpectations;
15pub use root::RefExpectations;
16
17use std::fmt::Debug;
18
19/// Result of an expectation check
20#[derive(Clone, Debug)]
21pub enum CheckResult {
22    /// The expectation passed
23    Pass,
24    /// The expectation failed, contains a message describing the failure
25    Fail(String),
26}
27
28/// An expectation on a value
29pub trait Expectation<T: Debug> {
30    /// Check this expectation
31    /// Returns CheckResult::Pass if the expectation passes
32    /// and CheckResult::Fail with a descriptive message if it didn't
33    fn check(&self, value: &T) -> CheckResult;
34}
35
36/// Trait to enable fluent building of expectations
37pub trait ExpectationBuilder<'e> {
38    /// Target value type for this builder
39    type Value: Debug + 'e;
40
41    /// Expect the value to pass an expectation
42    /// This is intended to be used in extension methods to add expectations to the builder
43    fn to_pass(self, expectation: impl Expectation<Self::Value> + 'e) -> Self;
44}
45
46/// Create expectations for a value.
47/// Used as an entrypoint for fluently building expectations
48///
49/// ```
50/// use rxpect::expect;
51/// use rxpect::expectations::EqualityExpectations;
52///
53/// expect(1).to_equal(1);
54/// ```
55///
56/// You can get the value back out if you check all expectations early:
57///
58/// ```
59/// use rxpect::expect;
60/// use rxpect::expectations::EqualityExpectations;
61///
62/// let value: String = expect("Hello World!".to_string())
63///     .to_equal("Hello World!")
64///     .check();
65/// println!("{value}"); // Hello World!
66/// ```
67pub fn expect<'e, T: Debug>(value: T) -> OwnedExpectations<'e, T> {
68    OwnedExpectations::new(value)
69}
70
71/// Create expectations for a reference to a value.
72/// Used as an entrypoint for fluently building expectations
73/// ```
74/// use rxpect::expect_ref;
75/// use rxpect::expectations::EqualityExpectations;
76///
77/// let value: String = "Hello World!".to_string();
78/// expect_ref(&value)
79///     .to_equal("Hello World!");
80/// ```
81pub fn expect_ref<T: Debug>(value: &'_ T) -> RefExpectations<'_, T> {
82    RefExpectations::new(value)
83}
84
85#[cfg(test)]
86pub(crate) mod tests {
87    use crate::{CheckResult, Expectation};
88    use std::fmt::Debug;
89    use std::rc::Rc;
90    use std::sync::Mutex;
91
92    pub(crate) struct TestExpectation {
93        pub asserted: Rc<Mutex<bool>>,
94        result: CheckResult,
95    }
96
97    impl TestExpectation {
98        pub fn new(result: CheckResult) -> (TestExpectation, Rc<Mutex<bool>>) {
99            let asserted = Rc::new(Mutex::new(false));
100            (
101                TestExpectation {
102                    asserted: asserted.clone(),
103                    result,
104                },
105                asserted,
106            )
107        }
108    }
109
110    impl<T: Debug> Expectation<T> for TestExpectation {
111        fn check(&self, _: &T) -> CheckResult {
112            let mut asserted = self.asserted.lock().unwrap();
113            *asserted = true;
114            self.result.clone()
115        }
116    }
117}