futures_test/future/mod.rs
1//! Additional combinators for testing futures.
2
3mod assert_unmoved;
4pub use self::assert_unmoved::AssertUnmoved;
5
6mod pending_once;
7pub use self::pending_once::PendingOnce;
8
9use futures_core::future::Future;
10use futures_executor;
11use std::thread;
12
13pub use crate::interleave_pending::InterleavePending;
14
15/// Additional combinators for testing futures.
16pub trait FutureTestExt: Future {
17 /// Asserts that the given is not moved after being polled.
18 ///
19 /// A check for movement is performed each time the future is polled
20 /// and when `Drop` is called.
21 ///
22 /// Aside from keeping track of the location at which the future was first
23 /// polled and providing assertions, this future adds no runtime behavior
24 /// and simply delegates to the child future.
25 fn assert_unmoved(self) -> AssertUnmoved<Self>
26 where
27 Self: Sized,
28 {
29 AssertUnmoved::new(self)
30 }
31
32 /// Introduces one [`Poll::Pending`](futures_core::task::Poll::Pending)
33 /// before polling the given future.
34 ///
35 /// # Examples
36 ///
37 /// ```
38 /// use futures::task::Poll;
39 /// use futures::future::FutureExt;
40 /// use futures_test::task::noop_context;
41 /// use futures_test::future::FutureTestExt;
42 /// use futures::pin_mut;
43 ///
44 /// let future = (async { 5 }).pending_once();
45 /// pin_mut!(future);
46 ///
47 /// let mut cx = noop_context();
48 ///
49 /// assert_eq!(future.poll_unpin(&mut cx), Poll::Pending);
50 /// assert_eq!(future.poll_unpin(&mut cx), Poll::Ready(5));
51 /// ```
52 fn pending_once(self) -> PendingOnce<Self>
53 where
54 Self: Sized,
55 {
56 PendingOnce::new(self)
57 }
58
59 /// Runs this future on a dedicated executor running in a background thread.
60 ///
61 /// # Examples
62 ///
63 /// ```
64 /// # futures::executor::block_on(async {
65 /// use futures::channel::oneshot;
66 /// use futures_test::future::FutureTestExt;
67 ///
68 /// let (tx, rx) = oneshot::channel::<i32>();
69 ///
70 /// (async { tx.send(5).unwrap() }).run_in_background();
71 ///
72 /// assert_eq!(rx.await, Ok(5));
73 /// # });
74 /// ```
75 fn run_in_background(self)
76 where
77 Self: Sized + Send + 'static,
78 Self::Output: Send,
79 {
80 thread::spawn(|| futures_executor::block_on(self));
81 }
82
83 /// Introduces an extra [`Poll::Pending`](futures_core::task::Poll::Pending)
84 /// in between each call to poll.
85 ///
86 /// # Examples
87 ///
88 /// ```
89 /// use futures::task::Poll;
90 /// use futures::future::{self, Future};
91 /// use futures_test::task::noop_context;
92 /// use futures_test::future::FutureTestExt;
93 /// use futures::pin_mut;
94 ///
95 /// let future = future::ready(1).interleave_pending();
96 /// pin_mut!(future);
97 ///
98 /// let mut cx = noop_context();
99 ///
100 /// assert_eq!(future.as_mut().poll(&mut cx), Poll::Pending);
101 /// assert_eq!(future.as_mut().poll(&mut cx), Poll::Ready(1));
102 /// ```
103 fn interleave_pending(self) -> InterleavePending<Self>
104 where
105 Self: Sized,
106 {
107 InterleavePending::new(self)
108 }
109}
110
111impl<Fut> FutureTestExt for Fut where Fut: Future {}