fail_follows_laws
Some checks failed
buildbot/cargo fmt (1.72) Build done.
buildbot/cargo doc (1.72) Build done.
buildbot/cargo clippy (1.65) Build done.
buildbot/cargo clippy (1.72) Build done.
buildbot/cargo test (1.65) Build done.

This commit is contained in:
AF 2023-10-15 18:05:36 +00:00
parent 787efb3662
commit 7f37bcbd49
3 changed files with 51 additions and 9 deletions

View File

@ -12,6 +12,8 @@
//! [`result`]: super::result
//! [`solo`]: super::solo
use std::convert::Infallible;
use crate::func::class_prelude::*;
#[derive(SharedFunctorAny)]
@ -126,14 +128,18 @@ impl<'a> LocalFunctor<'a> for OptionInstance {
}
}
impl<'a> Fail<'a, ()> for OptionInstance {
fn fail<A: 'a + Send>(_e: ()) -> Self::F<A> {
None
impl<'a> Fail<'a, Option<Infallible>> for OptionInstance {
fn fail<A: 'a + Send>(e: Option<Infallible>) -> Self::F<A> {
match e {
Some(some) => match some {},
None => None,
}
}
}
#[cfg(test)]
mod option_tests {
use std::convert::Infallible;
use std::sync::Arc;
use super::{test_suite, tests, Functor};
@ -159,6 +165,12 @@ mod option_tests {
}
}
impl<'a> test_suite::FailTestSuite<'a, Option<Infallible>> for T {
fn sample_fail<F: FnMut(Arc<dyn 'a + Send + Sync + Fn() -> Option<Infallible>>)>(mut f: F) {
f(Arc::new(|| None))
}
}
#[test]
fn fmap_f_none_is_none() {
assert_eq!(T::fmap(None, |_: ()| ()), None);
@ -190,4 +202,9 @@ mod option_tests {
fn shared_follows_laws() {
test_suite::shared_follows_laws::<T>().unwrap();
}
#[test]
fn fail_follows_laws() {
test_suite::fail_functor_follows_laws::<T, _>().unwrap();
}
}

View File

@ -1,7 +1,7 @@
use std::sync::Arc;
use shared::SharedFunctor;
use super::fail::*;
use super::shared::*;
use super::tests::*;
use super::*;
@ -13,6 +13,10 @@ pub trait FunctorTestSuite<'a>: WeakFunctor<'a> + Eqr<'a> {
fn sample<A: 'a + Send, F: FnMut(Arc<dyn WrapFunction<'a, A, Self::F<A>>>)>(f: F);
}
pub trait FailTestSuite<'a, E: 'a + Send>: FunctorTestSuite<'a> + Fail<'a, E> {
fn sample_fail<F: FnMut(Arc<dyn 'a + Send + Sync + Fn() -> E>)>(f: F);
}
pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite<'a>>() -> R {
let mut res = R::default();
T::sample(|pa| {
@ -132,3 +136,11 @@ pub fn shared_follows_laws<'a, T: SharedFunctor<'a> + FunctorTestSuite<'a>>() ->
});
res
}
pub fn fail_functor_follows_laws<'a, T: Functor<'a> + FailTestSuite<'a, E>, E: 'a + Send>() -> R {
let mut res = R::default();
T::sample_fail(|pe| {
res += fmap_keeps_fail::<T, _, _, _>(move || pe(), |x: i32| x + 2);
});
res
}

View File

@ -3,10 +3,10 @@ use std::{
ops::{Add, AddAssign},
};
use applicative_select::Selected;
use controlflow::IterativeWrapped;
use shared::SharedFunctor;
use super::applicative_select::*;
use super::controlflow::*;
use super::fail::*;
use super::shared::*;
use super::*;
pub struct TestResults {
@ -478,3 +478,16 @@ pub fn shared_is_same_after_clone<
T::unshare(sa),
)
}
pub fn fmap_keeps_fail<
'a,
T: Functor<'a> + Fail<'a, E> + Eqr<'a>,
A: 'a + Send,
B: 'a + Send + Debug + PartialEq,
E: 'a + Send,
>(
e0: impl 'a + Send + Fn() -> E,
f: impl 'a + Send + Fn(A) -> B,
) -> R {
T::eqr("fmap fail", T::fmap(T::fail(e0()), f), T::fail(e0()))
}