futures_test/io/write/
mod.rs

1//! Additional combinators for testing async writers.
2
3use futures_io::AsyncWrite;
4
5pub use super::limited::Limited;
6pub use crate::assert_unmoved::AssertUnmoved;
7pub use crate::interleave_pending::InterleavePending;
8pub use crate::track_closed::TrackClosed;
9
10/// Additional combinators for testing async writers.
11pub trait AsyncWriteTestExt: AsyncWrite {
12    /// Asserts that the given is not moved after being polled.
13    ///
14    /// A check for movement is performed each time the writer is polled
15    /// and when `Drop` is called.
16    ///
17    /// Aside from keeping track of the location at which the writer was first
18    /// polled and providing assertions, this writer adds no runtime behavior
19    /// and simply delegates to the child writer.
20    fn assert_unmoved_write(self) -> AssertUnmoved<Self>
21    where
22        Self: Sized,
23    {
24        AssertUnmoved::new(self)
25    }
26
27    /// Introduces an extra [`Poll::Pending`](futures_core::task::Poll::Pending)
28    /// in between each operation on the writer.
29    ///
30    /// # Examples
31    ///
32    /// ```
33    /// use futures::task::Poll;
34    /// use futures::io::{AsyncWrite, Cursor};
35    /// use futures_test::task::noop_context;
36    /// use futures_test::io::AsyncWriteTestExt;
37    /// use futures::pin_mut;
38    ///
39    /// let writer = Cursor::new(vec![0u8; 4].into_boxed_slice()).interleave_pending_write();
40    /// pin_mut!(writer);
41    ///
42    /// let mut cx = noop_context();
43    ///
44    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[1, 2])?, Poll::Pending);
45    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[1, 2])?, Poll::Ready(2));
46    /// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 0, 0]);
47    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[3, 4])?, Poll::Pending);
48    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[3, 4])?, Poll::Ready(2));
49    /// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 3, 4]);
50    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[5, 6])?, Poll::Pending);
51    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[5, 6])?, Poll::Ready(0));
52    ///
53    /// assert_eq!(writer.as_mut().poll_flush(&mut cx)?, Poll::Pending);
54    /// assert_eq!(writer.as_mut().poll_flush(&mut cx)?, Poll::Ready(()));
55    ///
56    /// assert_eq!(writer.as_mut().poll_close(&mut cx)?, Poll::Pending);
57    /// assert_eq!(writer.as_mut().poll_close(&mut cx)?, Poll::Ready(()));
58    ///
59    /// # Ok::<(), std::io::Error>(())
60    /// ```
61    fn interleave_pending_write(self) -> InterleavePending<Self>
62    where
63        Self: Sized,
64    {
65        InterleavePending::new(self)
66    }
67
68    /// Limit the number of bytes allowed to be written on each call to `poll_write`.
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// use futures::task::Poll;
74    /// use futures::io::{AsyncWrite, Cursor};
75    /// use futures_test::task::noop_context;
76    /// use futures_test::io::AsyncWriteTestExt;
77    /// use futures::pin_mut;
78    ///
79    /// let writer = Cursor::new(vec![0u8; 4].into_boxed_slice()).limited_write(2);
80    /// pin_mut!(writer);
81    ///
82    /// let mut cx = noop_context();
83    ///
84    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[1, 2])?, Poll::Ready(2));
85    /// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 0, 0]);
86    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[3])?, Poll::Ready(1));
87    /// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 3, 0]);
88    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[4, 5])?, Poll::Ready(1));
89    /// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 3, 4]);
90    /// assert_eq!(writer.as_mut().poll_write(&mut cx, &[5])?, Poll::Ready(0));
91    ///
92    /// # Ok::<(), std::io::Error>(())
93    /// ```
94    fn limited_write(self, limit: usize) -> Limited<Self>
95    where
96        Self: Sized,
97    {
98        Limited::new(self, limit)
99    }
100
101    /// Track whether this stream has been closed and errors if it is used after closing.
102    ///
103    /// # Examples
104    ///
105    /// ```
106    /// # futures::executor::block_on(async {
107    /// use futures::io::{AsyncWriteExt, Cursor};
108    /// use futures_test::io::AsyncWriteTestExt;
109    ///
110    /// let mut writer = Cursor::new(vec![0u8; 4]).track_closed();
111    ///
112    /// writer.write_all(&[1, 2]).await?;
113    /// assert!(!writer.is_closed());
114    /// writer.close().await?;
115    /// assert!(writer.is_closed());
116    ///
117    /// # Ok::<(), std::io::Error>(()) })?;
118    /// # Ok::<(), std::io::Error>(())
119    /// ```
120    ///
121    /// ```
122    /// # futures::executor::block_on(async {
123    /// use futures::io::{AsyncWriteExt, Cursor};
124    /// use futures_test::io::AsyncWriteTestExt;
125    ///
126    /// let mut writer = Cursor::new(vec![0u8; 4]).track_closed();
127    ///
128    /// writer.close().await?;
129    /// assert!(writer.write_all(&[1, 2]).await.is_err());
130    /// # Ok::<(), std::io::Error>(()) })?;
131    /// # Ok::<(), std::io::Error>(())
132    /// ```
133    fn track_closed(self) -> TrackClosed<Self>
134    where
135        Self: Sized,
136    {
137        TrackClosed::new(self)
138    }
139}
140
141impl<W> AsyncWriteTestExt for W where W: AsyncWrite {}