beetry_node/decorator/
until_success.rs1use beetry_core::{Node, TickStatus};
2
3pub struct UntilSuccess<N> {
5 node: N,
6}
7
8impl<N> UntilSuccess<N> {
9 #[must_use]
10 pub fn new(node: N) -> Self {
11 Self { node }
12 }
13}
14
15impl<N> Node for UntilSuccess<N>
16where
17 N: Node,
18{
19 fn tick(&mut self) -> TickStatus {
20 match self.node.tick() {
21 TickStatus::Success => TickStatus::Success,
22 TickStatus::Failure | TickStatus::Running => TickStatus::Running,
23 }
24 }
25
26 fn abort(&mut self) {
27 self.node.abort();
28 }
29
30 fn reset(&mut self) {
31 self.node.reset();
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use beetry_core::{Node, TickStatus};
38
39 use super::*;
40 use crate::mock_test::mock_returns;
41
42 #[test]
43 fn success_stays_success() {
44 let mut node = UntilSuccess::new(mock_returns([TickStatus::Success]));
45 assert_eq!(node.tick(), TickStatus::Success);
46 }
47
48 #[test]
49 fn failure_becomes_running() {
50 let mut node = UntilSuccess::new(mock_returns([TickStatus::Failure]));
51 assert_eq!(node.tick(), TickStatus::Running);
52 }
53
54 #[test]
55 fn running_stays_running() {
56 let mut node = UntilSuccess::new(mock_returns([TickStatus::Running]));
57 assert_eq!(node.tick(), TickStatus::Running);
58 }
59
60 #[test]
61 fn abort_is_propagated() {
62 let mut child = mock_returns([]);
63 child.expect_abort().once().return_const(());
64 let mut node = UntilSuccess::new(child);
65 node.abort();
66 }
67
68 #[test]
69 fn reset_is_propagated() {
70 let mut child = mock_returns([]);
71 child.expect_reset().once().return_const(());
72 let mut node = UntilSuccess::new(child);
73 node.reset();
74 }
75}