1 #[test]
map_ok()2 fn map_ok() {
3     use futures::future::{self, FutureExt, TryFutureExt};
4     use futures_test::future::FutureTestExt;
5     use std::sync::mpsc;
6 
7     // The closure given to `map_ok` should have been dropped by the time `map`
8     // runs.
9     let (tx1, rx1) = mpsc::channel::<()>();
10     let (tx2, rx2) = mpsc::channel::<()>();
11 
12     future::ready::<Result<i32, i32>>(Err(1))
13         .map_ok(move |_| { let _tx1 = tx1; panic!("should not run"); })
14         .map(move |_| {
15             assert!(rx1.recv().is_err());
16             tx2.send(()).unwrap()
17         })
18         .run_in_background();
19 
20     rx2.recv().unwrap();
21 }
22 
23 #[test]
map_err()24 fn map_err() {
25     use futures::future::{self, FutureExt, TryFutureExt};
26     use futures_test::future::FutureTestExt;
27     use std::sync::mpsc;
28 
29     // The closure given to `map_err` should have been dropped by the time `map`
30     // runs.
31     let (tx1, rx1) = mpsc::channel::<()>();
32     let (tx2, rx2) = mpsc::channel::<()>();
33 
34     future::ready::<Result<i32, i32>>(Ok(1))
35         .map_err(move |_| { let _tx1 = tx1; panic!("should not run"); })
36         .map(move |_| {
37             assert!(rx1.recv().is_err());
38             tx2.send(()).unwrap()
39         })
40         .run_in_background();
41 
42     rx2.recv().unwrap();
43 }
44 
45 mod channelled {
46     use futures::future::Future;
47     use futures::task::{Context,Poll};
48     use pin_project::pin_project;
49     use std::pin::Pin;
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         use futures::channel::oneshot;
69         use futures::future::{self, FutureExt, TryFutureExt};
70         use futures_test::future::FutureTestExt;
71         use std::sync::mpsc;
72 
73         let (tx0, rx0) = oneshot::channel::<()>();
74         let (tx1, rx1) = mpsc::channel::<()>();
75         let (tx2, rx2) = mpsc::channel::<()>();
76 
77         FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| { panic!() }) }
78             .then(move |_| {
79                 assert!(rx1.recv().is_err()); // tx1 should have been dropped
80                 tx2.send(()).unwrap();
81                 future::ready(())
82             })
83             .run_in_background();
84 
85         assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
86         tx0.send(()).unwrap();
87         rx2.recv().unwrap();
88     }
89 
90     #[test]
and_then_drops_eagerly()91     fn and_then_drops_eagerly() {
92         use futures::channel::oneshot;
93         use futures::future::{self, TryFutureExt};
94         use futures_test::future::FutureTestExt;
95         use std::sync::mpsc;
96 
97         let (tx0, rx0) = oneshot::channel::<Result<(), ()>>();
98         let (tx1, rx1) = mpsc::channel::<()>();
99         let (tx2, rx2) = mpsc::channel::<()>();
100 
101         FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| { panic!() }) }
102             .and_then(move |_| {
103                 assert!(rx1.recv().is_err()); // tx1 should have been dropped
104                 tx2.send(()).unwrap();
105                 future::ready(Ok(()))
106             })
107             .run_in_background();
108 
109         assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
110         tx0.send(Ok(())).unwrap();
111         rx2.recv().unwrap();
112     }
113 
114     #[test]
or_else_drops_eagerly()115     fn or_else_drops_eagerly() {
116         use futures::channel::oneshot;
117         use futures::future::{self, TryFutureExt};
118         use futures_test::future::FutureTestExt;
119         use std::sync::mpsc;
120 
121         let (tx0, rx0) = oneshot::channel::<Result<(), ()>>();
122         let (tx1, rx1) = mpsc::channel::<()>();
123         let (tx2, rx2) = mpsc::channel::<()>();
124 
125         FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| { panic!() }) }
126             .or_else(move |_| {
127                 assert!(rx1.recv().is_err()); // tx1 should have been dropped
128                 tx2.send(()).unwrap();
129                 future::ready::<Result<(), ()>>(Ok(()))
130             })
131             .run_in_background();
132 
133         assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
134         tx0.send(Err(())).unwrap();
135         rx2.recv().unwrap();
136     }
137 }
138