1 #![recursion_limit="128"]
2 
3 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
4 #[test]
poll_and_pending()5 fn poll_and_pending() {
6     use futures::{pending, pin_mut, poll};
7     use futures::executor::block_on;
8     use futures::task::Poll;
9 
10     let pending_once = async { pending!() };
11     block_on(async {
12         pin_mut!(pending_once);
13         assert_eq!(Poll::Pending, poll!(&mut pending_once));
14         assert_eq!(Poll::Ready(()), poll!(&mut pending_once));
15     });
16 }
17 
18 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
19 #[test]
join()20 fn join() {
21     use futures::{pin_mut, poll, join};
22     use futures::channel::oneshot;
23     use futures::executor::block_on;
24     use futures::task::Poll;
25 
26     let (tx1, rx1) = oneshot::channel::<i32>();
27     let (tx2, rx2) = oneshot::channel::<i32>();
28 
29     let fut = async {
30         let res = join!(rx1, rx2);
31         assert_eq!((Ok(1), Ok(2)), res);
32     };
33 
34     block_on(async {
35         pin_mut!(fut);
36         assert_eq!(Poll::Pending, poll!(&mut fut));
37         tx1.send(1).unwrap();
38         assert_eq!(Poll::Pending, poll!(&mut fut));
39         tx2.send(2).unwrap();
40         assert_eq!(Poll::Ready(()), poll!(&mut fut));
41     });
42 }
43 
44 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
45 #[test]
select()46 fn select() {
47     use futures::select;
48     use futures::channel::oneshot;
49     use futures::executor::block_on;
50     use futures::future::FutureExt;
51 
52     let (tx1, rx1) = oneshot::channel::<i32>();
53     let (_tx2, rx2) = oneshot::channel::<i32>();
54     tx1.send(1).unwrap();
55     let mut ran = false;
56     block_on(async {
57         select! {
58             res = rx1.fuse() => {
59                 assert_eq!(Ok(1), res);
60                 ran = true;
61             },
62             _ = rx2.fuse() => unreachable!(),
63         }
64     });
65     assert!(ran);
66 }
67 
68 #[cfg(all(feature = "alloc", feature = "executor", feature = "async-await"))]
69 #[test]
select_biased()70 fn select_biased() {
71     use futures::channel::oneshot;
72     use futures::executor::block_on;
73     use futures::future::FutureExt;
74     use futures::select_biased;
75 
76     let (tx1, rx1) = oneshot::channel::<i32>();
77     let (_tx2, rx2) = oneshot::channel::<i32>();
78     tx1.send(1).unwrap();
79     let mut ran = false;
80     block_on(async {
81         select_biased! {
82             res = rx1.fuse() => {
83                 assert_eq!(Ok(1), res);
84                 ran = true;
85             },
86             _ = rx2.fuse() => unreachable!(),
87         }
88     });
89     assert!(ran);
90 }
91 
92 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
93 #[test]
select_streams()94 fn select_streams() {
95     use futures::select;
96     use futures::channel::mpsc;
97     use futures::executor::block_on;
98     use futures::sink::SinkExt;
99     use futures::stream::StreamExt;
100 
101     let (mut tx1, rx1) = mpsc::channel::<i32>(1);
102     let (mut tx2, rx2) = mpsc::channel::<i32>(1);
103     let mut rx1 = rx1.fuse();
104     let mut rx2 = rx2.fuse();
105     let mut ran = false;
106     let mut total = 0;
107     block_on(async {
108         let mut tx1_opt;
109         let mut tx2_opt;
110         select! {
111             _ = rx1.next() => panic!(),
112             _ = rx2.next() => panic!(),
113             default => {
114                 tx1.send(2).await.unwrap();
115                 tx2.send(3).await.unwrap();
116                 tx1_opt = Some(tx1);
117                 tx2_opt = Some(tx2);
118             }
119             complete => panic!(),
120         }
121         loop {
122             select! {
123                 // runs first and again after default
124                 x = rx1.next() => if let Some(x) = x { total += x; },
125                 // runs second and again after default
126                 x = rx2.next()  => if let Some(x) = x { total += x; },
127                 // runs third
128                 default => {
129                     assert_eq!(total, 5);
130                     ran = true;
131                     drop(tx1_opt.take().unwrap());
132                     drop(tx2_opt.take().unwrap());
133                 },
134                 // runs last
135                 complete => break,
136             };
137         }
138     });
139     assert!(ran);
140 }
141 
142 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
143 #[test]
select_can_move_uncompleted_futures()144 fn select_can_move_uncompleted_futures() {
145     use futures::select;
146     use futures::channel::oneshot;
147     use futures::executor::block_on;
148     use futures::future::FutureExt;
149 
150     let (tx1, rx1) = oneshot::channel::<i32>();
151     let (tx2, rx2) = oneshot::channel::<i32>();
152     tx1.send(1).unwrap();
153     tx2.send(2).unwrap();
154     let mut ran = false;
155     let mut rx1 = rx1.fuse();
156     let mut rx2 = rx2.fuse();
157     block_on(async {
158         select! {
159             res = rx1 => {
160                 assert_eq!(Ok(1), res);
161                 assert_eq!(Ok(2), rx2.await);
162                 ran = true;
163             },
164             res = rx2 => {
165                 assert_eq!(Ok(2), res);
166                 assert_eq!(Ok(1), rx1.await);
167                 ran = true;
168             },
169         }
170     });
171     assert!(ran);
172 }
173 
174 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
175 #[test]
select_nested()176 fn select_nested() {
177     use futures::select;
178     use futures::executor::block_on;
179     use futures::future;
180 
181     let mut outer_fut = future::ready(1);
182     let mut inner_fut = future::ready(2);
183     let res = block_on(async {
184         select! {
185             x = outer_fut => {
186                 select! {
187                     y = inner_fut => x + y,
188                 }
189             }
190         }
191     });
192     assert_eq!(res, 3);
193 }
194 
195 #[cfg(all(feature = "async-await", feature = "std"))]
196 #[test]
select_size()197 fn select_size() {
198     use futures::select;
199     use futures::future;
200 
201     let fut = async {
202         let mut ready = future::ready(0i32);
203         select! {
204             _ = ready => {},
205         }
206     };
207     assert_eq!(::std::mem::size_of_val(&fut), 24);
208 
209     let fut = async {
210         let mut ready1 = future::ready(0i32);
211         let mut ready2 = future::ready(0i32);
212         select! {
213             _ = ready1 => {},
214             _ = ready2 => {},
215         }
216     };
217     assert_eq!(::std::mem::size_of_val(&fut), 40);
218 }
219 
220 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
221 #[test]
select_on_non_unpin_expressions()222 fn select_on_non_unpin_expressions() {
223     use futures::select;
224     use futures::executor::block_on;
225     use futures::future::FutureExt;
226 
227     // The returned Future is !Unpin
228     let make_non_unpin_fut = || { async {
229         5
230     }};
231 
232     let res = block_on(async {
233         let select_res;
234         select! {
235             value_1 = make_non_unpin_fut().fuse() => { select_res = value_1 },
236             value_2 = make_non_unpin_fut().fuse() => { select_res = value_2 },
237         };
238         select_res
239     });
240     assert_eq!(res, 5);
241 }
242 
243 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
244 #[test]
select_on_non_unpin_expressions_with_default()245 fn select_on_non_unpin_expressions_with_default() {
246     use futures::select;
247     use futures::executor::block_on;
248     use futures::future::FutureExt;
249 
250     // The returned Future is !Unpin
251     let make_non_unpin_fut = || { async {
252         5
253     }};
254 
255     let res = block_on(async {
256         let select_res;
257         select! {
258             value_1 = make_non_unpin_fut().fuse() => { select_res = value_1 },
259             value_2 = make_non_unpin_fut().fuse() => { select_res = value_2 },
260             default => { select_res = 7 },
261         };
262         select_res
263     });
264     assert_eq!(res, 5);
265 }
266 
267 #[cfg(all(feature = "async-await", feature = "std"))]
268 #[test]
select_on_non_unpin_size()269 fn select_on_non_unpin_size() {
270     use futures::select;
271     use futures::future::FutureExt;
272 
273     // The returned Future is !Unpin
274     let make_non_unpin_fut = || { async {
275         5
276     }};
277 
278     let fut = async {
279         let select_res;
280         select! {
281             value_1 = make_non_unpin_fut().fuse() => { select_res = value_1 },
282             value_2 = make_non_unpin_fut().fuse() => { select_res = value_2 },
283         };
284         select_res
285     };
286 
287     assert_eq!(32, std::mem::size_of_val(&fut));
288 }
289 
290 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
291 #[test]
select_can_be_used_as_expression()292 fn select_can_be_used_as_expression() {
293     use futures::select;
294     use futures::executor::block_on;
295     use futures::future;
296 
297     block_on(async {
298         let res = select! {
299             x = future::ready(7) => { x },
300             y = future::ready(3) => { y + 1 },
301         };
302         assert!(res == 7 || res == 4);
303     });
304 }
305 
306 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
307 #[test]
select_with_default_can_be_used_as_expression()308 fn select_with_default_can_be_used_as_expression() {
309     use futures::select;
310     use futures::executor::block_on;
311     use futures::future::{FutureExt, poll_fn};
312     use futures::task::{Context, Poll};
313 
314     fn poll_always_pending<T>(_cx: &mut Context<'_>) -> Poll<T> {
315         Poll::Pending
316     }
317 
318     block_on(async {
319         let res = select! {
320             x = poll_fn(poll_always_pending::<i32>).fuse() => x,
321             y = poll_fn(poll_always_pending::<i32>).fuse() => { y + 1 },
322             default => 99,
323         };
324         assert_eq!(res, 99);
325     });
326 }
327 
328 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
329 #[test]
select_with_complete_can_be_used_as_expression()330 fn select_with_complete_can_be_used_as_expression() {
331     use futures::select;
332     use futures::executor::block_on;
333     use futures::future;
334 
335     block_on(async {
336         let res = select! {
337             x = future::pending::<i32>() => { x },
338             y = future::pending::<i32>() => { y + 1 },
339             default => 99,
340             complete => 237,
341         };
342         assert_eq!(res, 237);
343     });
344 }
345 
346 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
347 #[test]
select_on_mutable_borrowing_future_with_same_borrow_in_block()348 fn select_on_mutable_borrowing_future_with_same_borrow_in_block() {
349     use futures::select;
350     use futures::executor::block_on;
351     use futures::future::FutureExt;
352 
353     async fn require_mutable(_: &mut i32) {}
354     async fn async_noop() {}
355 
356     block_on(async {
357         let mut value = 234;
358         select! {
359             x = require_mutable(&mut value).fuse() => { },
360             y = async_noop().fuse() => {
361                 value += 5;
362             },
363         }
364     });
365 }
366 
367 #[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
368 #[test]
select_on_mutable_borrowing_future_with_same_borrow_in_block_and_default()369 fn select_on_mutable_borrowing_future_with_same_borrow_in_block_and_default() {
370     use futures::select;
371     use futures::executor::block_on;
372     use futures::future::FutureExt;
373 
374     async fn require_mutable(_: &mut i32) {}
375     async fn async_noop() {}
376 
377     block_on(async {
378         let mut value = 234;
379         select! {
380             x = require_mutable(&mut value).fuse() => { },
381             y = async_noop().fuse() => {
382                 value += 5;
383             },
384             default => {
385                 value += 27;
386             },
387         }
388     });
389 }
390 
391 #[cfg(feature = "async-await")]
392 #[test]
join_size()393 fn join_size() {
394     use futures::join;
395     use futures::future;
396 
397     let fut = async {
398         let ready = future::ready(0i32);
399         join!(ready)
400     };
401     assert_eq!(::std::mem::size_of_val(&fut), 16);
402 
403     let fut = async {
404         let ready1 = future::ready(0i32);
405         let ready2 = future::ready(0i32);
406         join!(ready1, ready2)
407     };
408     assert_eq!(::std::mem::size_of_val(&fut), 28);
409 }
410 
411 #[cfg(feature = "async-await")]
412 #[test]
try_join_size()413 fn try_join_size() {
414     use futures::try_join;
415     use futures::future;
416 
417     let fut = async {
418         let ready = future::ready(Ok::<i32, i32>(0));
419         try_join!(ready)
420     };
421     assert_eq!(::std::mem::size_of_val(&fut), 16);
422 
423     let fut = async {
424         let ready1 = future::ready(Ok::<i32, i32>(0));
425         let ready2 = future::ready(Ok::<i32, i32>(0));
426         try_join!(ready1, ready2)
427     };
428     assert_eq!(::std::mem::size_of_val(&fut), 28);
429 }
430 
431 #[cfg(feature = "async-await")]
432 #[test]
join_doesnt_require_unpin()433 fn join_doesnt_require_unpin() {
434     use futures::join;
435 
436     let _ = async {
437         join!(async {}, async {})
438     };
439 }
440 
441 #[cfg(feature = "async-await")]
442 #[test]
try_join_doesnt_require_unpin()443 fn try_join_doesnt_require_unpin() {
444     use futures::try_join;
445 
446     let _ = async {
447         try_join!(
448             async { Ok::<(), ()>(()) },
449             async { Ok::<(), ()>(()) },
450         )
451     };
452 }
453