1 | use futures::executor::block_on; |
2 | use futures::future::{self, FusedFuture, FutureExt}; |
3 | use futures::select; |
4 | use futures::stream::{FuturesUnordered, StreamExt}; |
5 | use futures::task::{Context, Poll}; |
6 | use futures_test::future::FutureTestExt; |
7 | use futures_test::task::new_count_waker; |
8 | |
9 | #[test] |
10 | fn is_terminated() { |
11 | let (waker, counter) = new_count_waker(); |
12 | let mut cx = Context::from_waker(&waker); |
13 | |
14 | let mut tasks = FuturesUnordered::new(); |
15 | |
16 | let mut select_next_some = tasks.select_next_some(); |
17 | assert_eq!(select_next_some.is_terminated(), false); |
18 | assert_eq!(select_next_some.poll_unpin(&mut cx), Poll::Pending); |
19 | assert_eq!(counter, 1); |
20 | assert_eq!(select_next_some.is_terminated(), true); |
21 | drop(select_next_some); |
22 | |
23 | tasks.push(future::ready(1)); |
24 | |
25 | let mut select_next_some = tasks.select_next_some(); |
26 | assert_eq!(select_next_some.is_terminated(), false); |
27 | assert_eq!(select_next_some.poll_unpin(&mut cx), Poll::Ready(1)); |
28 | assert_eq!(select_next_some.is_terminated(), false); |
29 | assert_eq!(select_next_some.poll_unpin(&mut cx), Poll::Pending); |
30 | assert_eq!(select_next_some.is_terminated(), true); |
31 | } |
32 | |
33 | #[test] |
34 | fn select() { |
35 | // Checks that even though `async_tasks` will yield a `None` and return |
36 | // `is_terminated() == true` during the first poll, it manages to toggle |
37 | // back to having items after a future is pushed into it during the second |
38 | // poll (after pending_once completes). |
39 | block_on(async { |
40 | let mut fut = future::ready(1).pending_once(); |
41 | let mut async_tasks = FuturesUnordered::new(); |
42 | let mut total = 0; |
43 | loop { |
44 | select! { |
45 | num = fut => { |
46 | total += num; |
47 | async_tasks.push(async { 5 }); |
48 | }, |
49 | num = async_tasks.select_next_some() => { |
50 | total += num; |
51 | } |
52 | complete => break, |
53 | } |
54 | } |
55 | assert_eq!(total, 6); |
56 | }); |
57 | } |
58 | |
59 | // Check that `select!` macro does not fail when importing from `futures_util`. |
60 | #[test] |
61 | fn futures_util_select() { |
62 | use futures_util::select; |
63 | |
64 | // Checks that even though `async_tasks` will yield a `None` and return |
65 | // `is_terminated() == true` during the first poll, it manages to toggle |
66 | // back to having items after a future is pushed into it during the second |
67 | // poll (after pending_once completes). |
68 | block_on(async { |
69 | let mut fut = future::ready(1).pending_once(); |
70 | let mut async_tasks = FuturesUnordered::new(); |
71 | let mut total = 0; |
72 | loop { |
73 | select! { |
74 | num = fut => { |
75 | total += num; |
76 | async_tasks.push(async { 5 }); |
77 | }, |
78 | num = async_tasks.select_next_some() => { |
79 | total += num; |
80 | } |
81 | complete => break, |
82 | } |
83 | } |
84 | assert_eq!(total, 6); |
85 | }); |
86 | } |
87 | |