cqrs_es2/test_framework/test_handler/
handler_tester.rs

1use std::marker::PhantomData;
2
3use crate::{
4    commands::{
5        ICommand,
6        ICommandHandler,
7    },
8    events::{
9        IEvent,
10        IEventHandler,
11    },
12};
13
14use super::handler_test_executor::HandlerResultExecutor;
15
16/// `HandlerTester` provides a consistent way to test aggregate
17/// implementations
18///
19/// # Examples
20/// ```rust
21/// use cqrs_es2::{
22///     example_impl::{
23///         AddCustomerName,
24///         Customer,
25///         CustomerCommand,
26///         CustomerEvent,
27///         NameAdded,
28///     },
29///     HandlerTester,
30/// };
31///
32/// type CustomTester =
33///     HandlerTester<CustomerCommand, CustomerEvent, Customer>;
34///
35/// CustomTester::default()
36///     .given_no_previous_events()
37///     .when(CustomerCommand::AddCustomerName(
38///         AddCustomerName {
39///             changed_name: "John Doe".to_string(),
40///         },
41///     ))
42///     .then_expect(vec![CustomerEvent::NameAdded(
43///         NameAdded {
44///             changed_name: "John Doe".to_string(),
45///         },
46///     )]);
47///
48/// CustomTester::default()
49///     .given(vec![CustomerEvent::NameAdded(
50///         NameAdded {
51///             changed_name: "John Doe".to_string(),
52///         },
53///     )])
54///     .when(CustomerCommand::AddCustomerName(
55///         AddCustomerName {
56///             changed_name: "John Doe".to_string(),
57///         },
58///     ))
59///     .then_expect_error(
60///         "a name has already been added for this customer",
61///     )
62/// ```
63pub struct HandlerTester<
64    C: ICommand,
65    E: IEvent,
66    A: Default + ICommandHandler<C, E> + IEventHandler<E>,
67> {
68    _phantom: PhantomData<(C, E, A)>,
69}
70
71impl<
72        C: ICommand,
73        E: IEvent,
74        A: Default + ICommandHandler<C, E> + IEventHandler<E>,
75    > HandlerTester<C, E, A>
76{
77    /// Initiates a handler test with no previous events
78    #[must_use]
79    pub fn given_no_previous_events(
80        &self
81    ) -> HandlerResultExecutor<C, E, A> {
82        HandlerResultExecutor::new(Vec::new())
83    }
84
85    /// Initiates a handler test with a collection of previous events
86    #[must_use]
87    pub fn given(
88        &self,
89        events: Vec<E>,
90    ) -> HandlerResultExecutor<C, E, A> {
91        HandlerResultExecutor::new(events)
92    }
93}
94
95impl<
96        C: ICommand,
97        E: IEvent,
98        A: Default + ICommandHandler<C, E> + IEventHandler<E>,
99    > Default for HandlerTester<C, E, A>
100{
101    fn default() -> Self {
102        HandlerTester {
103            _phantom: PhantomData,
104        }
105    }
106}