1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
//! Macros used with tests /// Creates TestProbe matcher function from the user specified block of code /// /// # Examples /// /// ``` /// matcher!(v => { /// if let Some(m) = v.downcast_ref::<some_actor::SomeMsg>() { /// if m.data > 100 { /// true /// } else { /// false /// } /// } else { /// false /// } /// }); /// ``` #[macro_export] macro_rules! matcher { ($value:ident => $body:expr) => { Box::new(|$value: &Box<Any + Send>| { $body }) }; } /// Creates TestProbe matcher function which match specified message type. /// /// # Examples /// /// ``` /// type_matcher!(some_actor::SomeMsg); /// ``` /// #[macro_export] macro_rules! type_matcher { ($t:path) => { Box::new(|v: &Box<Any + Send>| { if let Some(m) = v.downcast_ref::<$t>() { true } else { false } }) }; } /// Creates TestProbe matcher function which match specified message by match arm. Match arm must be /// specified without guards. /// /// # Examples /// /// ``` /// type_matcher!(some_actor::SomeMsg => some_actor::SomeMsg { data: 100 }); /// /// // Message type => Match arm /// /// ``` /// #[macro_export] macro_rules! pat_matcher { ($t:path => $pat:pat) => { Box::new(|v: &Box<Any + Send>| { if let Some(m) = v.downcast_ref::<$t>() { match m { $pat => true, _ => false } } else { false } }) }; } /// Creates TestProbe matcher function which match specified message type and if is was success, /// apply specified user function to the result. /// /// # Examples /// /// ``` /// extended_type_matcher!(some_actor::SomeMsg, v => { /// if v.data > 100 { /// true /// } else { /// false /// } /// }); /// /// // Inner function must return bool value /// /// ``` /// #[macro_export] macro_rules! extended_type_matcher { ($t:path , $v:ident => $body:expr) => { Box::new(|v: &Box<Any + Send>| { if let Some($v) = v.downcast_ref::<$t>() { $body } else { false } }) }; } /// Extract actor object from TestActorRef. This object is immutable and may be used for reversion /// of the internal actor's state. For use this macros, target actor must implement the as_any /// method from the Actor trait. Without satisfying this condition, macros will cause panic. /// /// # Examples /// /// ``` /// in_state! (target, Foo, actor => { /// assert_eq!(actor.data, 599); /// }); /// /// // target - TestActorRef /// // Foo - actor type under actor reference /// ``` /// #[macro_export] macro_rules! in_state { ($r:ident , $t:path, $a:ident => $e:expr) => { { let mut target_any = $r.as_any(); let mut sd = target_any.downcast_ref::<Box<TestLocalActorRef>>().unwrap(); let mut actor = sd.actor.lock().unwrap(); let mut actor = actor.as_any(); let mut $a = actor.downcast_ref::<$t>().unwrap(); $e; } }; }