1 //! A collection of useful macros for testing futures and tokio based code 2 3 /// Asserts a `Poll` is ready, returning the value. 4 /// 5 /// This will invoke `panic!` if the provided `Poll` does not evaluate to `Poll::Ready` at 6 /// runtime. 7 /// 8 /// # Custom Messages 9 /// 10 /// This macro has a second form, where a custom panic message can be provided with or without 11 /// arguments for formatting. 12 /// 13 /// # Examples 14 /// 15 /// ``` 16 /// use futures_util::future; 17 /// use tokio_test::{assert_ready, task}; 18 /// 19 /// let mut fut = task::spawn(future::ready(())); 20 /// assert_ready!(fut.poll()); 21 /// ``` 22 #[macro_export] 23 macro_rules! assert_ready { 24 ($e:expr) => {{ 25 use core::task::Poll::*; 26 match $e { 27 Ready(v) => v, 28 Pending => panic!("pending"), 29 } 30 }}; 31 ($e:expr, $($msg:tt)+) => {{ 32 use core::task::Poll::*; 33 match $e { 34 Ready(v) => v, 35 Pending => { 36 panic!("pending; {}", format_args!($($msg)+)) 37 } 38 } 39 }}; 40 } 41 42 /// Asserts a `Poll<Result<...>>` is ready and `Ok`, returning the value. 43 /// 44 /// This will invoke `panic!` if the provided `Poll` does not evaluate to `Poll::Ready(Ok(..))` at 45 /// runtime. 46 /// 47 /// # Custom Messages 48 /// 49 /// This macro has a second form, where a custom panic message can be provided with or without 50 /// arguments for formatting. 51 /// 52 /// # Examples 53 /// 54 /// ``` 55 /// use futures_util::future; 56 /// use tokio_test::{assert_ready_ok, task}; 57 /// 58 /// let mut fut = task::spawn(future::ok::<_, ()>(())); 59 /// assert_ready_ok!(fut.poll()); 60 /// ``` 61 #[macro_export] 62 macro_rules! assert_ready_ok { 63 ($e:expr) => {{ 64 use tokio_test::{assert_ready, assert_ok}; 65 let val = assert_ready!($e); 66 assert_ok!(val) 67 }}; 68 ($e:expr, $($msg:tt)+) => {{ 69 use tokio_test::{assert_ready, assert_ok}; 70 let val = assert_ready!($e, $($msg)*); 71 assert_ok!(val, $($msg)*) 72 }}; 73 } 74 75 /// Asserts a `Poll<Result<...>>` is ready and `Err`, returning the error. 76 /// 77 /// This will invoke `panic!` if the provided `Poll` does not evaluate to `Poll::Ready(Err(..))` at 78 /// runtime. 79 /// 80 /// # Custom Messages 81 /// 82 /// This macro has a second form, where a custom panic message can be provided with or without 83 /// arguments for formatting. 84 /// 85 /// # Examples 86 /// 87 /// ``` 88 /// use futures_util::future; 89 /// use tokio_test::{assert_ready_err, task}; 90 /// 91 /// let mut fut = task::spawn(future::err::<(), _>(())); 92 /// assert_ready_err!(fut.poll()); 93 /// ``` 94 #[macro_export] 95 macro_rules! assert_ready_err { 96 ($e:expr) => {{ 97 use tokio_test::{assert_ready, assert_err}; 98 let val = assert_ready!($e); 99 assert_err!(val) 100 }}; 101 ($e:expr, $($msg:tt)+) => {{ 102 use tokio_test::{assert_ready, assert_err}; 103 let val = assert_ready!($e, $($msg)*); 104 assert_err!(val, $($msg)*) 105 }}; 106 } 107 108 /// Asserts a `Poll` is pending. 109 /// 110 /// This will invoke `panic!` if the provided `Poll` does not evaluate to `Poll::Pending` at 111 /// runtime. 112 /// 113 /// # Custom Messages 114 /// 115 /// This macro has a second form, where a custom panic message can be provided with or without 116 /// arguments for formatting. 117 /// 118 /// # Examples 119 /// 120 /// ``` 121 /// use futures_util::future; 122 /// use tokio_test::{assert_pending, task}; 123 /// 124 /// let mut fut = task::spawn(future::pending::<()>()); 125 /// assert_pending!(fut.poll()); 126 /// ``` 127 #[macro_export] 128 macro_rules! assert_pending { 129 ($e:expr) => {{ 130 use core::task::Poll::*; 131 match $e { 132 Pending => {} 133 Ready(v) => panic!("ready; value = {:?}", v), 134 } 135 }}; 136 ($e:expr, $($msg:tt)+) => {{ 137 use core::task::Poll::*; 138 match $e { 139 Pending => {} 140 Ready(v) => { 141 panic!("ready; value = {:?}; {}", v, format_args!($($msg)+)) 142 } 143 } 144 }}; 145 } 146 147 /// Asserts if a poll is ready and check for equality on the value 148 /// 149 /// This will invoke `panic!` if the provided `Poll` does not evaluate to `Poll::Ready` at 150 /// runtime and the value produced does not partially equal the expected value. 151 /// 152 /// # Custom Messages 153 /// 154 /// This macro has a second form, where a custom panic message can be provided with or without 155 /// arguments for formatting. 156 /// 157 /// # Examples 158 /// 159 /// ``` 160 /// use futures_util::future; 161 /// use tokio_test::{assert_ready_eq, task}; 162 /// 163 /// let mut fut = task::spawn(future::ready(42)); 164 /// assert_ready_eq!(fut.poll(), 42); 165 /// ``` 166 #[macro_export] 167 macro_rules! assert_ready_eq { 168 ($e:expr, $expect:expr) => { 169 let val = $crate::assert_ready!($e); 170 assert_eq!(val, $expect) 171 }; 172 173 ($e:expr, $expect:expr, $($msg:tt)+) => { 174 let val = $crate::assert_ready!($e, $($msg)*); 175 assert_eq!(val, $expect, $($msg)*) 176 }; 177 } 178 179 /// Asserts that the expression evaluates to `Ok` and returns the value. 180 /// 181 /// This will invoke the `panic!` macro if the provided expression does not evaluate to `Ok` at 182 /// runtime. 183 /// 184 /// # Custom Messages 185 /// 186 /// This macro has a second form, where a custom panic message can be provided with or without 187 /// arguments for formatting. 188 /// 189 /// # Examples 190 /// 191 /// ``` 192 /// use tokio_test::assert_ok; 193 /// 194 /// let n: u32 = assert_ok!("123".parse()); 195 /// 196 /// let s = "123"; 197 /// let n: u32 = assert_ok!(s.parse(), "testing parsing {:?} as a u32", s); 198 /// ``` 199 #[macro_export] 200 macro_rules! assert_ok { 201 ($e:expr) => { 202 assert_ok!($e,) 203 }; 204 ($e:expr,) => {{ 205 use std::result::Result::*; 206 match $e { 207 Ok(v) => v, 208 Err(e) => panic!("assertion failed: Err({:?})", e), 209 } 210 }}; 211 ($e:expr, $($arg:tt)+) => {{ 212 use std::result::Result::*; 213 match $e { 214 Ok(v) => v, 215 Err(e) => panic!("assertion failed: Err({:?}): {}", e, format_args!($($arg)+)), 216 } 217 }}; 218 } 219 220 /// Asserts that the expression evaluates to `Err` and returns the error. 221 /// 222 /// This will invoke the `panic!` macro if the provided expression does not evaluate to `Err` at 223 /// runtime. 224 /// 225 /// # Custom Messages 226 /// 227 /// This macro has a second form, where a custom panic message can be provided with or without 228 /// arguments for formatting. 229 /// 230 /// # Examples 231 /// 232 /// ``` 233 /// use tokio_test::assert_err; 234 /// use std::str::FromStr; 235 /// 236 /// 237 /// let err = assert_err!(u32::from_str("fail")); 238 /// 239 /// let msg = "fail"; 240 /// let err = assert_err!(u32::from_str(msg), "testing parsing {:?} as u32", msg); 241 /// ``` 242 #[macro_export] 243 macro_rules! assert_err { 244 ($e:expr) => { 245 assert_err!($e,); 246 }; 247 ($e:expr,) => {{ 248 use std::result::Result::*; 249 match $e { 250 Ok(v) => panic!("assertion failed: Ok({:?})", v), 251 Err(e) => e, 252 } 253 }}; 254 ($e:expr, $($arg:tt)+) => {{ 255 use std::result::Result::*; 256 match $e { 257 Ok(v) => panic!("assertion failed: Ok({:?}): {}", v, format_args!($($arg)+)), 258 Err(e) => e, 259 } 260 }}; 261 } 262