This crate provide a handy mock sink implementations that can be used test own Sink.
MockSink
allow to create a handy testsThis 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::
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(()))); ```
Licensed under either of
at your option.
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