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