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]
map_ok()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]
map_err()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 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<F::Output>61     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<F::Output> {
62         self.project().future.poll(cx)
63     }
64 }
65 
66 #[test]
then_drops_eagerly()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]
and_then_drops_eagerly()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]
or_else_drops_eagerly()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