1 //! Additional combinators for testing async readers.
2 
3 use futures_io::AsyncRead;
4 
5 pub use super::limited::Limited;
6 pub use crate::assert_unmoved::AssertUnmoved;
7 pub use crate::interleave_pending::InterleavePending;
8 
9 /// Additional combinators for testing async readers.
10 pub trait AsyncReadTestExt: AsyncRead {
11     /// Asserts that the given is not moved after being polled.
12     ///
13     /// A check for movement is performed each time the reader is polled
14     /// and when `Drop` is called.
15     ///
16     /// Aside from keeping track of the location at which the reader was first
17     /// polled and providing assertions, this reader adds no runtime behavior
18     /// and simply delegates to the child reader.
assert_unmoved(self) -> AssertUnmoved<Self> where Self: Sized,19     fn assert_unmoved(self) -> AssertUnmoved<Self>
20     where
21         Self: Sized,
22     {
23         AssertUnmoved::new(self)
24     }
25 
26     /// Introduces an extra [`Poll::Pending`](futures_core::task::Poll::Pending)
27     /// in between each read of the reader.
28     ///
29     /// # Examples
30     ///
31     /// ```
32     /// use futures::task::Poll;
33     /// use futures::io::{AsyncRead, Cursor};
34     /// use futures_test::task::noop_context;
35     /// use futures_test::io::AsyncReadTestExt;
36     /// use futures::pin_mut;
37     ///
38     /// let reader = Cursor::new(&[1, 2, 3]).interleave_pending();
39     /// pin_mut!(reader);
40     ///
41     /// let mut cx = noop_context();
42     ///
43     /// let mut buf = [0, 0];
44     ///
45     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf[..])?, Poll::Pending);
46     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf[..])?, Poll::Ready(2));
47     /// assert_eq!(buf, [1, 2]);
48     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf[..])?, Poll::Pending);
49     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf[..])?, Poll::Ready(1));
50     /// assert_eq!(buf, [3, 2]);
51     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf[..])?, Poll::Pending);
52     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf[..])?, Poll::Ready(0));
53     ///
54     /// # Ok::<(), std::io::Error>(())
55     /// ```
56     ///
57     /// ## `AsyncBufRead`
58     ///
59     /// The returned reader will also implement `AsyncBufRead` if the underlying reader does.
60     ///
61     /// ```
62     /// use futures::task::Poll;
63     /// use futures::io::{AsyncBufRead, Cursor};
64     /// use futures_test::task::noop_context;
65     /// use futures_test::io::AsyncReadTestExt;
66     /// use futures::pin_mut;
67     ///
68     /// let reader = Cursor::new(&[1, 2, 3]).interleave_pending();
69     /// pin_mut!(reader);
70     ///
71     /// let mut cx = noop_context();
72     ///
73     /// assert_eq!(reader.as_mut().poll_fill_buf(&mut cx)?, Poll::Pending);
74     /// assert_eq!(reader.as_mut().poll_fill_buf(&mut cx)?, Poll::Ready(&[1, 2, 3][..]));
75     /// reader.as_mut().consume(2);
76     /// assert_eq!(reader.as_mut().poll_fill_buf(&mut cx)?, Poll::Pending);
77     /// assert_eq!(reader.as_mut().poll_fill_buf(&mut cx)?, Poll::Ready(&[3][..]));
78     /// reader.as_mut().consume(1);
79     /// assert_eq!(reader.as_mut().poll_fill_buf(&mut cx)?, Poll::Pending);
80     /// assert_eq!(reader.as_mut().poll_fill_buf(&mut cx)?, Poll::Ready(&[][..]));
81     ///
82     /// # Ok::<(), std::io::Error>(())
83     /// ```
interleave_pending(self) -> InterleavePending<Self> where Self: Sized,84     fn interleave_pending(self) -> InterleavePending<Self>
85     where
86         Self: Sized,
87     {
88         InterleavePending::new(self)
89     }
90 
91     /// Limit the number of bytes allowed to be read on each call to `poll_read`.
92     ///
93     /// # Examples
94     ///
95     /// ```
96     /// use futures::task::Poll;
97     /// use futures::io::{AsyncRead, Cursor};
98     /// use futures_test::task::noop_context;
99     /// use futures_test::io::AsyncReadTestExt;
100     /// use futures::pin_mut;
101     ///
102     /// let reader = Cursor::new(&[1, 2, 3, 4, 5]).limited(2);
103     /// pin_mut!(reader);
104     ///
105     /// let mut cx = noop_context();
106     ///
107     /// let mut buf = [0; 10];
108     ///
109     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf)?, Poll::Ready(2));
110     /// assert_eq!(&buf[..2], &[1, 2]);
111     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf)?, Poll::Ready(2));
112     /// assert_eq!(&buf[..2], &[3, 4]);
113     /// assert_eq!(reader.as_mut().poll_read(&mut cx, &mut buf)?, Poll::Ready(1));
114     /// assert_eq!(&buf[..1], &[5]);
115     ///
116     /// # Ok::<(), std::io::Error>(())
117     /// ```
limited(self, limit: usize) -> Limited<Self> where Self: Sized,118     fn limited(self, limit: usize) -> Limited<Self>
119     where
120         Self: Sized,
121     {
122         Limited::new(self, limit)
123     }
124 }
125 
126 impl<R> AsyncReadTestExt for R where R: AsyncRead {}
127