1 //! Additional combinators for testing async writers. 2 3 use futures_io::AsyncWrite; 4 5 pub use super::limited::Limited; 6 pub use crate::assert_unmoved::AssertUnmoved; 7 pub use crate::interleave_pending::InterleavePending; 8 pub use crate::track_closed::TrackClosed; 9 10 /// Additional combinators for testing async writers. 11 pub 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. assert_unmoved_write(self) -> AssertUnmoved<Self> where Self: Sized,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 /// ``` interleave_pending_write(self) -> InterleavePending<Self> where Self: Sized,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 /// ``` limited_write(self, limit: usize) -> Limited<Self> where Self: Sized,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 /// ``` track_closed(self) -> TrackClosed<Self> where Self: Sized,133 fn track_closed(self) -> TrackClosed<Self> 134 where 135 Self: Sized, 136 { 137 TrackClosed::new(self) 138 } 139 } 140 141 impl<W> AsyncWriteTestExt for W where W: AsyncWrite {} 142