crates.io Documentation CI master

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. ```rust use asynctask::wakerfn; use std::iter; use std::{ task::{Poll, Context}, } use futures::{self, stream};

fn draintest() { let e = iter::repeat::>>(Poll::Ready(Ok(()))); let sink = SinkMock::withflush_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 interleavepending() { let e = vec![Poll::Ready(Ok::<_, Never>(())), Poll::Pending] .intoiter() .cycle(); let sink = SinkMock::withflushfeedback(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(()))] .intoiter() .cycle(); let sink = SinkMock::withflush_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));

}

fn main() { draintest(); interleavepending(); error(); } ```

SinkFeedback mock provide a full control of returned items.

You should first use MockSink if this doesn't this one may be useful.

```rust use asynctask::wakerfn; use futures::sink::Sink; use futurestestsink::from_iter; use std::{ pin::Pin, sync::{atomic, Arc}, task::{Context, Poll}, };

// create a Context let wakecnt = Arc::new(atomic::AtomicUsize::new(0)); let cnt = wakecnt.clone(); let waker = wakerfn(move || { wakecnt.fetchadd(1, atomic::Ordering::SeqCst); }); let mut cx = Context::fromwaker(&waker); // actual test let pollfallback = vec![ Poll::Ready(Ok(())), Poll::Ready(Ok(())), Poll::Pending, Poll::Ready(Err(12)), ] .intoiter(); let startsendfallback = vec![Ok::<_, u32>(())].intoiter().cycle(); // ours sink implementation let mut s = fromiter(pollfallback, startsend_fallback);

let r1 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r1, Poll::Ready(Ok(()))); let s1 = Pin::new(&mut s).startsend(1); asserteq!(s1, Ok(()));

let r2 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r2, Poll::Ready(Ok(()))); // start send don't panic because startsendfallback is cycle let s2 = Pin::new(&mut s).startsend(2); asserteq!(s2, Ok(()));

// ctx.wake() wasn't called. assert_eq!(0, cnt.load(atomic::Ordering::SeqCst));

let r3 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r3, Poll::Pending); assert_eq!(1, cnt.load(atomic::Ordering::SeqCst));

let r4 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r4, Poll::Ready(Err(12))); assert_eq!(1, cnt.load(atomic::Ordering::SeqCst)); ```

You can be interested in FuseLast container for Iterator.

```rust use asynctask::wakerfn; use futures::sink::Sink; use futurestestsink::{fromiter, fuselast::IteratorExt}; use std::{ pin::Pin, sync::{atomic, Arc}, task::{Context, Poll}, };

// create a Context let wakecnt = Arc::new(atomic::AtomicUsize::new(0)); let cnt = wakecnt.clone(); let waker = wakerfn(move || { wakecnt.fetchadd(1, atomic::Ordering::SeqCst); }); let mut cx = Context::fromwaker(&waker); // actual test let pollfallback = vec![ Poll::Ready(Ok(())), Poll::Ready(Err(12)), Poll::Ready(Ok(())), ] .intoiter() .fuselast(); let startsendfallback = vec![Ok::<_, u32>(())].intoiter().cycle(); // ours sink implementation let mut s = fromiter(pollfallback, startsendfallback);

let r1 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r1, Poll::Ready(Ok(()))); let s1 = Pin::new(&mut s).startsend(1); asserteq!(s1, Ok(()));

let r2 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r2, Poll::Ready(Err(12)));

let r3 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r3, Poll::Ready(Ok(())));

// if not fuse_last this would panic! let r4 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r3, Poll::Ready(Ok(())));

let r5 = Pin::new(&mut s).pollready(&mut cx); asserteq!(r3, Poll::Ready(Ok(()))); ```

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

This project try follow rules: * Keep a Changelog, * Semantic Versioning.

This README was generated with cargo-readme from template