1 //! Additional combinators for testing sinks. 2 3 use futures_sink::Sink; 4 5 pub use crate::assert_unmoved::AssertUnmoved; 6 pub use crate::interleave_pending::InterleavePending; 7 pub use crate::track_closed::TrackClosed; 8 9 /// Additional combinators for testing sinks. 10 pub trait SinkTestExt<Item>: Sink<Item> { 11 /// Asserts that the given is not moved after being polled. 12 /// 13 /// A check for movement is performed each time the sink is polled 14 /// and when `Drop` is called. 15 /// 16 /// Aside from keeping track of the location at which the sink was first 17 /// polled and providing assertions, this sink adds no runtime behavior 18 /// and simply delegates to the child sink. assert_unmoved_sink(self) -> AssertUnmoved<Self> where Self: Sized,19 fn assert_unmoved_sink(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 operation on the sink. interleave_pending_sink(self) -> InterleavePending<Self> where Self: Sized,28 fn interleave_pending_sink(self) -> InterleavePending<Self> 29 where 30 Self: Sized, 31 { 32 InterleavePending::new(self) 33 } 34 35 /// Track whether this sink has been closed and panics if it is used after closing. 36 /// 37 /// # Examples 38 /// 39 /// ``` 40 /// # futures::executor::block_on(async { 41 /// use futures::sink::{SinkExt, drain}; 42 /// use futures_test::sink::SinkTestExt; 43 /// 44 /// let mut sink = drain::<i32>().track_closed(); 45 /// 46 /// sink.send(1).await?; 47 /// assert!(!sink.is_closed()); 48 /// sink.close().await?; 49 /// assert!(sink.is_closed()); 50 /// 51 /// # Ok::<(), std::convert::Infallible>(()) })?; 52 /// # Ok::<(), std::convert::Infallible>(()) 53 /// ``` 54 /// 55 /// Note: Unlike [`AsyncWriteTestExt::track_closed`] when 56 /// used as a sink the adaptor will panic if closed too early as there's no easy way to 57 /// integrate as an error. 58 /// 59 /// [`AsyncWriteTestExt::track_closed`]: crate::io::AsyncWriteTestExt::track_closed 60 /// 61 /// ``` 62 /// # futures::executor::block_on(async { 63 /// use std::panic::AssertUnwindSafe; 64 /// use futures::{sink::{SinkExt, drain}, future::FutureExt}; 65 /// use futures_test::sink::SinkTestExt; 66 /// 67 /// let mut sink = drain::<i32>().track_closed(); 68 /// 69 /// sink.close().await?; 70 /// assert!(AssertUnwindSafe(sink.send(1)).catch_unwind().await.is_err()); 71 /// # Ok::<(), std::convert::Infallible>(()) })?; 72 /// # Ok::<(), std::convert::Infallible>(()) 73 /// ``` track_closed(self) -> TrackClosed<Self> where Self: Sized,74 fn track_closed(self) -> TrackClosed<Self> 75 where 76 Self: Sized, 77 { 78 TrackClosed::new(self) 79 } 80 } 81 82 impl<Item, W> SinkTestExt<Item> for W where W: Sink<Item> {} 83