ranvier_runtime/
testkit.rs1use crate::Axon;
2use ranvier_core::{Bus, Outcome, transition::ResourceRequirement};
3use std::any::Any;
4
5pub struct AxonTestKit<R> {
10 resources: R,
11 bus: Bus,
12}
13
14impl<R> AxonTestKit<R> {
15 pub fn new(resources: R) -> Self {
16 Self {
17 resources,
18 bus: Bus::new(),
19 }
20 }
21
22 pub fn with_bus(resources: R, bus: Bus) -> Self {
23 Self { resources, bus }
24 }
25
26 pub fn insert<T: Any + Send + Sync + 'static>(&mut self, value: T) -> &mut Self {
27 self.bus.insert(value);
28 self
29 }
30
31 pub fn bus(&self) -> &Bus {
32 &self.bus
33 }
34
35 pub fn bus_mut(&mut self) -> &mut Bus {
36 &mut self.bus
37 }
38
39 pub fn resources(&self) -> &R {
40 &self.resources
41 }
42
43 pub fn resources_mut(&mut self) -> &mut R {
44 &mut self.resources
45 }
46
47 pub fn into_parts(self) -> (R, Bus) {
48 (self.resources, self.bus)
49 }
50}
51
52impl<R> AxonTestKit<R>
53where
54 R: ResourceRequirement,
55{
56 pub async fn run<In, Out, E>(
57 &mut self,
58 axon: &Axon<In, Out, E, R>,
59 input: In,
60 ) -> Outcome<Out, E>
61 where
62 In: Send + Sync + 'static,
63 Out: Send + Sync + 'static,
64 E: Send + 'static,
65 {
66 axon.execute(input, &self.resources, &mut self.bus).await
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use ranvier_core::{Outcome, Transition};
74 use std::convert::Infallible;
75
76 #[derive(Clone)]
77 struct MockResources {
78 offset: usize,
79 }
80
81 impl ranvier_core::transition::ResourceRequirement for MockResources {}
82
83 #[derive(Clone)]
84 struct SumWithBus;
85
86 #[async_trait::async_trait]
87 impl Transition<usize, usize> for SumWithBus {
88 type Error = Infallible;
89 type Resources = MockResources;
90
91 async fn run(
92 &self,
93 state: usize,
94 resources: &Self::Resources,
95 bus: &mut Bus,
96 ) -> Outcome<usize, Self::Error> {
97 let bus_value = bus.read::<usize>().copied().unwrap_or_default();
98 Outcome::next(state + resources.offset + bus_value)
99 }
100 }
101
102 #[tokio::test]
103 async fn testkit_executes_with_mocked_resources_and_bus_values() {
104 let axon = Axon::<usize, usize, Infallible, MockResources>::new("Sum").then(SumWithBus);
105 let mut kit = AxonTestKit::new(MockResources { offset: 7 });
106 kit.insert(5usize);
107
108 let result = kit.run(&axon, 10).await;
109 match result {
110 Outcome::Next(value) => assert_eq!(value, 22),
111 _ => panic!("expected Outcome::Next"),
112 }
113 }
114}