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