1 | use futures::channel::oneshot; |
2 | use futures::future::{self, Future, FutureExt, TryFutureExt}; |
3 | use futures::task::{Context, Poll}; |
4 | use futures_test::future::FutureTestExt; |
5 | use pin_project::pin_project ; |
6 | use std::pin::Pin; |
7 | use std::sync::mpsc; |
8 | |
9 | #[test] |
10 | fn map_ok() { |
11 | // The closure given to `map_ok` should have been dropped by the time `map` |
12 | // runs. |
13 | let (tx1, rx1) = mpsc::channel::<()>(); |
14 | let (tx2, rx2) = mpsc::channel::<()>(); |
15 | |
16 | future::ready::<Result<i32, i32>>(Err(1)) |
17 | .map_ok(move |_| { |
18 | let _tx1 = tx1; |
19 | panic!("should not run" ); |
20 | }) |
21 | .map(move |_| { |
22 | assert!(rx1.recv().is_err()); |
23 | tx2.send(()).unwrap() |
24 | }) |
25 | .run_in_background(); |
26 | |
27 | rx2.recv().unwrap(); |
28 | } |
29 | |
30 | #[test] |
31 | fn map_err() { |
32 | // The closure given to `map_err` should have been dropped by the time `map` |
33 | // runs. |
34 | let (tx1, rx1) = mpsc::channel::<()>(); |
35 | let (tx2, rx2) = mpsc::channel::<()>(); |
36 | |
37 | future::ready::<Result<i32, i32>>(Ok(1)) |
38 | .map_err(move |_| { |
39 | let _tx1 = tx1; |
40 | panic!("should not run" ); |
41 | }) |
42 | .map(move |_| { |
43 | assert!(rx1.recv().is_err()); |
44 | tx2.send(()).unwrap() |
45 | }) |
46 | .run_in_background(); |
47 | |
48 | rx2.recv().unwrap(); |
49 | } |
50 | |
51 | #[pin_project ] |
52 | struct FutureData<F, T> { |
53 | _data: T, |
54 | #[pin] |
55 | future: F, |
56 | } |
57 | |
58 | impl<F: Future, T: Send + 'static> Future for FutureData<F, T> { |
59 | type Output = F::Output; |
60 | |
61 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<F::Output> { |
62 | self.project().future.poll(cx) |
63 | } |
64 | } |
65 | |
66 | #[test] |
67 | fn then_drops_eagerly() { |
68 | let (tx0, rx0) = oneshot::channel::<()>(); |
69 | let (tx1, rx1) = mpsc::channel::<()>(); |
70 | let (tx2, rx2) = mpsc::channel::<()>(); |
71 | |
72 | FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) } |
73 | .then(move |_| { |
74 | assert!(rx1.recv().is_err()); // tx1 should have been dropped |
75 | tx2.send(()).unwrap(); |
76 | future::ready(()) |
77 | }) |
78 | .run_in_background(); |
79 | |
80 | assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv()); |
81 | tx0.send(()).unwrap(); |
82 | rx2.recv().unwrap(); |
83 | } |
84 | |
85 | #[test] |
86 | fn and_then_drops_eagerly() { |
87 | let (tx0, rx0) = oneshot::channel::<Result<(), ()>>(); |
88 | let (tx1, rx1) = mpsc::channel::<()>(); |
89 | let (tx2, rx2) = mpsc::channel::<()>(); |
90 | |
91 | FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) } |
92 | .and_then(move |_| { |
93 | assert!(rx1.recv().is_err()); // tx1 should have been dropped |
94 | tx2.send(()).unwrap(); |
95 | future::ready(Ok(())) |
96 | }) |
97 | .run_in_background(); |
98 | |
99 | assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv()); |
100 | tx0.send(Ok(())).unwrap(); |
101 | rx2.recv().unwrap(); |
102 | } |
103 | |
104 | #[test] |
105 | fn or_else_drops_eagerly() { |
106 | let (tx0, rx0) = oneshot::channel::<Result<(), ()>>(); |
107 | let (tx1, rx1) = mpsc::channel::<()>(); |
108 | let (tx2, rx2) = mpsc::channel::<()>(); |
109 | |
110 | FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) } |
111 | .or_else(move |_| { |
112 | assert!(rx1.recv().is_err()); // tx1 should have been dropped |
113 | tx2.send(()).unwrap(); |
114 | future::ready::<Result<(), ()>>(Ok(())) |
115 | }) |
116 | .run_in_background(); |
117 | |
118 | assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv()); |
119 | tx0.send(Err(())).unwrap(); |
120 | rx2.recv().unwrap(); |
121 | } |
122 | |