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