[−][src]Crate futures_test_sink
This crate provide a handy mock sink implementations that can be used test own Sink.
Examples
:MockSink
allow to create a handy tests
This example contains a 3 tests. See documentation of MockSink
for details.
use futures::{ self, never::Never, stream::{self, StreamExt}, }; use futures_test_sink::SinkMock; use std::iter; use std::task::{Context, Poll}; fn drain_test() { let e = iter::repeat::<Poll<Result<(), Never>>>(Poll::Ready(Ok(()))); let sink = SinkMock::with_flush_feedback(e); let stream = stream::iter(vec![Ok::<u8, Never>(5u8), Ok(7), Ok(9), Ok(77), Ok(79)].into_iter()); let send_all = stream.forward(sink); assert_eq!(Ok(()), futures::executor::block_on(send_all)); } fn interleave_pending() { let e = vec![Poll::Ready(Ok::<_, Never>(())), Poll::Pending] .into_iter() .cycle(); let sink = SinkMock::with_flush_feedback(e); let stream = stream::iter(vec![Ok::<u8, Never>(5u8), Ok(7), Ok(9), Ok(77), Ok(79)].into_iter()); let send_all = stream.forward(sink); assert_eq!(Ok(()), futures::executor::block_on(send_all)); } fn error() { let e = vec![Poll::Ready(Ok(())), Poll::Pending, Poll::Ready(Err(()))] .into_iter() .cycle(); let sink = SinkMock::with_flush_feedback(e); let stream = stream::iter(vec![Ok(5u8), Ok(7), Ok(9), Ok(77), Ok(79)].into_iter()); let send_all = stream.forward(sink); assert_eq!(Err(()), futures::executor::block_on(send_all)); } drain_test(); interleave_pending(); error();
SinkFeedback
mock provide a full control of returned items.
You should first use MockSink
if this doesn't this one may be useful.
use async_task::waker_fn; use futures::sink::Sink; use futures_test_sink::from_iter; use std::{ pin::Pin, sync::{atomic, Arc}, task::{Context, Poll}, }; // create a Context let wake_cnt = Arc::new(atomic::AtomicUsize::new(0)); let cnt = wake_cnt.clone(); let waker = waker_fn(move || { wake_cnt.fetch_add(1, atomic::Ordering::SeqCst); }); let mut cx = Context::from_waker(&waker); // actual test let poll_fallback = vec![ Poll::Ready(Ok(())), Poll::Ready(Ok(())), Poll::Pending, Poll::Ready(Err(12)), ] .into_iter(); let start_send_fallback = vec![Ok::<_, u32>(())].into_iter().cycle(); // ours sink implementation let mut s = from_iter(poll_fallback, start_send_fallback); let r1 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r1, Poll::Ready(Ok(()))); let s1 = Pin::new(&mut s).start_send(1); assert_eq!(s1, Ok(())); let r2 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r2, Poll::Ready(Ok(()))); // start send don't panic because start_send_fallback is cycle let s2 = Pin::new(&mut s).start_send(2); assert_eq!(s2, Ok(())); // ctx.wake() wasn't called. assert_eq!(0, cnt.load(atomic::Ordering::SeqCst)); let r3 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r3, Poll::Pending); assert_eq!(1, cnt.load(atomic::Ordering::SeqCst)); let r4 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r4, Poll::Ready(Err(12))); assert_eq!(1, cnt.load(atomic::Ordering::SeqCst));
You can be interested in FuseLast container for Iterator.
use async_task::waker_fn; use futures::sink::Sink; use futures_test_sink::{from_iter, fuse_last::IteratorExt}; use std::{ pin::Pin, sync::{atomic, Arc}, task::{Context, Poll}, }; // create a Context let wake_cnt = Arc::new(atomic::AtomicUsize::new(0)); let cnt = wake_cnt.clone(); let waker = waker_fn(move || { wake_cnt.fetch_add(1, atomic::Ordering::SeqCst); }); let mut cx = Context::from_waker(&waker); // actual test let poll_fallback = vec![ Poll::Ready(Ok(())), Poll::Ready(Err(12)), Poll::Ready(Ok(())), ] .into_iter() .fuse_last(); let start_send_fallback = vec![Ok::<_, u32>(())].into_iter().cycle(); // ours sink implementation let mut s = from_iter(poll_fallback, start_send_fallback); let r1 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r1, Poll::Ready(Ok(()))); let s1 = Pin::new(&mut s).start_send(1); assert_eq!(s1, Ok(())); let r2 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r2, Poll::Ready(Err(12))); let r3 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r3, Poll::Ready(Ok(()))); // if not `fuse_last` this would panic! let r4 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r3, Poll::Ready(Ok(()))); let r5 = Pin::new(&mut s).poll_ready(&mut cx); assert_eq!(r3, Poll::Ready(Ok(())));
Modules
fuse_last | This is like cycle but after an iterator end the last element is returned infinitely. |
Structs
SinkFeedback | This |
SinkMock | This struct represent correct implementation of sink according to sink doc. |
Functions
from_iter | This method allows to create Sink from iterators. |
interleave_pending | This method will additionally return |
ok | This method is similar to |