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