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