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