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 {}