diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/multiple_generics.rs | 86 | ||||
| -rw-r--r-- | tests/multiple_generics_lifetime.rs | 70 | ||||
| -rw-r--r-- | tests/trivial.rs | 40 | ||||
| -rw-r--r-- | tests/trivial_lifetime.rs | 33 | ||||
| -rw-r--r-- | tests/vector.rs | 106 | ||||
| -rw-r--r-- | tests/with_lifetimes.rs | 49 |
6 files changed, 201 insertions, 183 deletions
diff --git a/tests/multiple_generics.rs b/tests/multiple_generics.rs index c8c76ba..6e744f4 100644 --- a/tests/multiple_generics.rs +++ b/tests/multiple_generics.rs @@ -3,79 +3,67 @@ //! Tests if multiple generic parameters work, for the case that lifetimes are independent of mapping functions. //! For simplicity, it just creates a `FreeResult` based on `Result`. +use higher::{Apply, Bind, Functor}; use higher_free_macro::free; -use higher::{Functor, Bind, Apply}; free!(FreeResult<O,E>, Result<FreeResult<O,E>,E>); - //just to appease clippy without disabling the lint.... macro_rules! assert_nearly_equal { ($a:expr, $b:expr, $c:expr) => { - assert!((($a)-($b)).abs() < $c) + assert!((($a) - ($b)).abs() < $c) }; } #[test] -fn test_multiple_generics(){ - let m : FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); - let m = m.fmap(|x| x*2); +fn test_multiple_generics() { + let m: FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); + let m = m.fmap(|x| x * 2); let m = m.bind(|x| FreeResult::Free(Box::new(Ok(FreeResult::Pure(x))))); - let f = FreeResult::Pure((|x| x*3).into()); + let f = FreeResult::Pure((|x| x * 3).into()); let m = m.apply(f); match m { - FreeResult::Free(b) => { - match *b { - Ok(FreeResult::Free(b)) => { - match *b { - Ok(FreeResult::Pure(x)) => assert_eq!(x, 37*6), - _ => unreachable!() - } - } - _ => unreachable!() - } - } - FreeResult::Pure(_) => unreachable!() + FreeResult::Free(b) => match *b { + Ok(FreeResult::Free(b)) => match *b { + Ok(FreeResult::Pure(x)) => assert_eq!(x, 37 * 6), + _ => unreachable!(), + }, + _ => unreachable!(), + }, + FreeResult::Pure(_) => unreachable!(), } } #[test] -fn test_multiple_generics2(){ - let m : FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); +fn test_multiple_generics2() { + let m: FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); let m = m.bind(|_| FreeResult::<u32, _>::lift_f(Err("An early out.".to_owned()))); - match m{ - FreeResult::Free(m) => { - match &*m { - Ok(FreeResult::Free(m)) => { - match &**m { - Err(e) => assert_eq!(e, "An early out."), - _ => unreachable!() - } - }, - _ => unreachable!() - } + match m { + FreeResult::Free(m) => match &*m { + Ok(FreeResult::Free(m)) => match &**m { + Err(e) => assert_eq!(e, "An early out."), + _ => unreachable!(), + }, + _ => unreachable!(), }, - FreeResult::Pure(_) => unreachable!() + FreeResult::Pure(_) => unreachable!(), } } #[test] -fn test_multiple_generics3(){ - let m : FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); - let f : FreeResult<_, String> = FreeResult::Pure(|x : u32| -> f64 {f64::from(x)*0.5f64}).fmap(Into::into); +fn test_multiple_generics3() { + let m: FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); + let f: FreeResult<_, String> = + FreeResult::Pure(|x: u32| -> f64 { f64::from(x) * 0.5f64 }).fmap(Into::into); let m = m.apply(f); - match m{ - FreeResult::Free(m) => { - match &*m{ - Ok(k) => { - match k { - FreeResult::Pure(k) => assert_nearly_equal!(18.5f64, *k, f64::EPSILON), - FreeResult::Free(_) => unreachable!(), - } - } - Err(_) => unreachable!(), - } + match m { + FreeResult::Free(m) => match &*m { + Ok(k) => match k { + FreeResult::Pure(k) => assert_nearly_equal!(18.5f64, *k, f64::EPSILON), + FreeResult::Free(_) => unreachable!(), + }, + Err(_) => unreachable!(), }, - FreeResult::Pure(_) => unreachable!() + FreeResult::Pure(_) => unreachable!(), } -}
\ No newline at end of file +} diff --git a/tests/multiple_generics_lifetime.rs b/tests/multiple_generics_lifetime.rs index 48a9bd1..8d24f0e 100644 --- a/tests/multiple_generics_lifetime.rs +++ b/tests/multiple_generics_lifetime.rs @@ -2,32 +2,39 @@ #![deny(clippy::all)] //! Tests if multiple generic parameters work, if the return value's lifetime depends on the mapping function lifetime. -use std::rc::Rc; +use higher::{Apply, Bind, Functor}; use higher_free_macro::free; -use higher::{Functor, Bind, Apply}; +use std::rc::Rc; #[derive(Clone)] -struct TestFunctor<'a, 'b, A, B>{ - data : &'b B, - next : Rc<dyn Fn(i32)->A + 'a>, +struct TestFunctor<'a, 'b, A, B> { + data: &'b B, + next: Rc<dyn Fn(i32) -> A + 'a>, } -impl<'a,'b,A : 'a,B> Functor<'a,A> for TestFunctor<'a, 'b, A, B>{ +impl<'a, 'b, A: 'a, B> Functor<'a, A> for TestFunctor<'a, 'b, A, B> { type Target<T> = TestFunctor<'a, 'b, T, B>; fn fmap<C, F>(self, f: F) -> Self::Target<C> where - F: Fn(A) -> C + 'a { - TestFunctor{ data : self.data, next : Rc::new(move |x| f((self.next)(x)))} + F: Fn(A) -> C + 'a, + { + TestFunctor { + data: self.data, + next: Rc::new(move |x| f((self.next)(x))), + } } } free!(<'xx>, FreeTest<'xx,'yy,AA,BB>, TestFunctor<'xx, 'yy, FreeTest<'xx, 'yy, AA, BB>, BB>); #[test] -fn test_lifetime_multiple_generics(){ - let free_monad = FreeTest::lift_f(TestFunctor{ data : &"Listening to NSP while writing this.", next : Rc::new(|x| f64::from(x)*0.5f64)}); - let functions = FreeTest::Pure(|x : f64| -> bool {x > 0.7f64} ).fmap(Into::into); +fn test_lifetime_multiple_generics() { + let free_monad = FreeTest::lift_f(TestFunctor { + data: &"Listening to NSP while writing this.", + next: Rc::new(|x| f64::from(x) * 0.5f64), + }); + let functions = FreeTest::Pure(|x: f64| -> bool { x > 0.7f64 }).fmap(Into::into); let free_monad_after_apply = free_monad.apply(functions); match free_monad_after_apply { FreeTest::Free(m) => { @@ -35,44 +42,51 @@ fn test_lifetime_multiple_generics(){ let x = m.next.clone(); let y = m.next.clone(); let m1 = x(1); - match m1{ + match m1 { FreeTest::Pure(v) => assert!(!v), FreeTest::Free(_) => unreachable!(), } let m2 = y(3); - match m2{ + match m2 { FreeTest::Pure(v) => assert!(v), FreeTest::Free(_) => unreachable!(), } - }, - FreeTest::Pure(_) => unreachable!() + } + FreeTest::Pure(_) => unreachable!(), } } //just to appease clippy without disabling the lint.... macro_rules! assert_nearly_equal { ($a:expr, $b:expr, $c:expr) => { - assert!((($a)-($b)).abs() < $c) + assert!((($a) - ($b)).abs() < $c) }; } #[test] -fn test_lifetime_multiple_generics_bind(){ - let m = FreeTest::lift_f(TestFunctor{ data : &"Listening to Soilwork while writing this.", next : Rc::new(|x| f64::from(x)*0.5f64)}); - let m = m.bind(|x : f64| -> FreeTest<_,_> { +fn test_lifetime_multiple_generics_bind() { + let m = FreeTest::lift_f(TestFunctor { + data: &"Listening to Soilwork while writing this.", + next: Rc::new(|x| f64::from(x) * 0.5f64), + }); + let m = m.bind(|x: f64| -> FreeTest<_, _> { if x < 0.0 { FreeTest::Pure(x.abs().floor()) } else { - FreeTest::lift_f(TestFunctor{data : &"Now it's Little Big.", next : Rc::new(move |y| f64::from(y) + x.ceil())}) - }}); - match m{ + FreeTest::lift_f(TestFunctor { + data: &"Now it's Little Big.", + next: Rc::new(move |y| f64::from(y) + x.ceil()), + }) + } + }); + match m { FreeTest::Free(m) => { assert_eq!(m.data, &"Listening to Soilwork while writing this."); - match (m.next)(-3){ + match (m.next)(-3) { FreeTest::Pure(v) => assert_nearly_equal!(v, 1f64, f64::EPSILON), FreeTest::Free(_) => unreachable!(), } - match (m.next)(3){ + match (m.next)(3) { FreeTest::Pure(_) => unreachable!(), FreeTest::Free(v) => { assert_eq!(v.data, &"Now it's Little Big."); @@ -80,9 +94,9 @@ fn test_lifetime_multiple_generics_bind(){ FreeTest::Pure(v) => assert_nearly_equal!(v, 7f64, f64::EPSILON), FreeTest::Free(_) => unreachable!(), } - }, + } } - }, - FreeTest::Pure(_) => unreachable!() + } + FreeTest::Pure(_) => unreachable!(), } -}
\ No newline at end of file +} diff --git a/tests/trivial.rs b/tests/trivial.rs index 5bc1e91..d3a71f3 100644 --- a/tests/trivial.rs +++ b/tests/trivial.rs @@ -1,8 +1,8 @@ #![deny(clippy::pedantic)] #![deny(clippy::all)] //! A trivial test functor. Not holding any data, so this is basically just a linked list of free-nodes. +use higher::{Apply, Bind, Functor}; use higher_free_macro::free; -use higher::{Functor, Bind, Apply}; #[derive(Functor, Clone)] struct TrivialFunctor<A>(A); @@ -12,30 +12,22 @@ free!(TrivialFreeMonad<A>, TrivialFunctor<TrivialFreeMonad<A>>); #[test] fn test_trivial_functor() { let m = TrivialFreeMonad::lift_f(TrivialFunctor(37u32)); - let m = m.fmap(|x| x*2); + let m = m.fmap(|x| x * 2); let m = m.bind(|x| TrivialFreeMonad::Free(Box::new(TrivialFunctor(TrivialFreeMonad::Pure(x))))); - let f = TrivialFreeMonad::Pure((|x| x*3).into()); + let f = TrivialFreeMonad::Pure((|x| x * 3).into()); let m = m.apply(f); match m { - TrivialFreeMonad::Free(b) => { - match *b { - TrivialFunctor(f) => { - match f { - TrivialFreeMonad::Free(b) => { - match *b { - TrivialFunctor(f) => { - match f{ - TrivialFreeMonad::Pure(x) => assert_eq!(x, 37*6), - TrivialFreeMonad::Free(_) => unreachable!() - } - } - } - }, - TrivialFreeMonad::Pure(_) => unreachable!() - } - } - } - } - TrivialFreeMonad::Pure(_) => unreachable!() + TrivialFreeMonad::Free(b) => match *b { + TrivialFunctor(f) => match f { + TrivialFreeMonad::Free(b) => match *b { + TrivialFunctor(f) => match f { + TrivialFreeMonad::Pure(x) => assert_eq!(x, 37 * 6), + TrivialFreeMonad::Free(_) => unreachable!(), + }, + }, + TrivialFreeMonad::Pure(_) => unreachable!(), + }, + }, + TrivialFreeMonad::Pure(_) => unreachable!(), } -}
\ No newline at end of file +} diff --git a/tests/trivial_lifetime.rs b/tests/trivial_lifetime.rs index 4f7d094..04d2d4a 100644 --- a/tests/trivial_lifetime.rs +++ b/tests/trivial_lifetime.rs @@ -1,39 +1,44 @@ #![deny(clippy::pedantic)] #![deny(clippy::all)] //! Tests if a trivial functor, which's lifetime depends on the mapping function, works. -use std::rc::Rc; -use higher::{Functor, Bind}; +use higher::{Bind, Functor}; use higher_free_macro::free; +use std::rc::Rc; #[derive(Clone)] -struct TrivWithLifetime<'a,A,B>{ - next : Rc<dyn Fn(B)->A + 'a>, +struct TrivWithLifetime<'a, A, B> { + next: Rc<dyn Fn(B) -> A + 'a>, } -impl<'a,A : 'a,B : 'a> Functor<'a,A> for TrivWithLifetime<'a,A,B> { - type Target<T> = TrivWithLifetime<'a,T,B>; +impl<'a, A: 'a, B: 'a> Functor<'a, A> for TrivWithLifetime<'a, A, B> { + type Target<T> = TrivWithLifetime<'a, T, B>; fn fmap<C, F>(self, f: F) -> Self::Target<C> where - F: Fn(A) -> C + 'a { - TrivWithLifetime{ next : Rc::new(move |x| f((self.next)(x)))} + F: Fn(A) -> C + 'a, + { + TrivWithLifetime { + next: Rc::new(move |x| f((self.next)(x))), + } } } free!(<'a>, FreeTriv<'a,A,B>, TrivWithLifetime<'a,FreeTriv<'a,A,B>,B>); #[test] -fn test_trivial_with_lifetime(){ - let f = FreeTriv::lift_f(TrivWithLifetime{next : Rc::new(i32::unsigned_abs)}); +fn test_trivial_with_lifetime() { + let f = FreeTriv::lift_f(TrivWithLifetime { + next: Rc::new(i32::unsigned_abs), + }); let f = f.bind(FreeTriv::Pure); match f { FreeTriv::Free(f) => { let n = (f.next)(-4); match n { - FreeTriv::Pure(v) => assert_eq!(v,4u32), + FreeTriv::Pure(v) => assert_eq!(v, 4u32), FreeTriv::Free(_) => unreachable!(), } - }, - FreeTriv::Pure(_) => unreachable!() + } + FreeTriv::Pure(_) => unreachable!(), } -}
\ No newline at end of file +} diff --git a/tests/vector.rs b/tests/vector.rs index 2b2f4b2..f22a243 100644 --- a/tests/vector.rs +++ b/tests/vector.rs @@ -3,74 +3,80 @@ //! Tests if creating a Free Monad for a Vec works. Not sure if this is useful in any way. //! It is a nice illustration that Free Monads are tree-like though. +use higher::{Apply, Bind, Functor}; use higher_free_macro::free; -use higher::{Functor, Bind, Apply}; free!(FreeVec<A>, Vec<FreeVec<A>>); - //just to appease clippy without disabling the lint.... macro_rules! assert_nearly_equal { ($a:expr, $b:expr, $c:expr) => { - assert!((($a)-($b)).abs() < $c) + assert!((($a) - ($b)).abs() < $c) }; } #[test] -fn test_vector(){ - let free_monad = FreeVec::lift_f(vec![2,3,4]); - let free_monad_after_fmap = free_monad.fmap(|x| x*2); - let free_monad_after_bind = free_monad_after_fmap.bind(|x| if x%3 == 0 {FreeVec::Pure(x)} else {FreeVec::lift_f(vec![x,x+1])}); - let functions = FreeVec::lift_f(vec![(|x| f64::from(x) / 3.0) as fn(u32)->f64, (|x| f64::from(x+2)) as fn(u32)->f64]); +fn test_vector() { + let free_monad = FreeVec::lift_f(vec![2, 3, 4]); + let free_monad_after_fmap = free_monad.fmap(|x| x * 2); + let free_monad_after_bind = free_monad_after_fmap.bind(|x| { + if x % 3 == 0 { + FreeVec::Pure(x) + } else { + FreeVec::lift_f(vec![x, x + 1]) + } + }); + let functions = FreeVec::lift_f(vec![ + (|x| f64::from(x) / 3.0) as fn(u32) -> f64, + (|x| f64::from(x + 2)) as fn(u32) -> f64, + ]); let free_monad_after_apply = free_monad_after_bind.apply(functions.fmap(Into::into)); match free_monad_after_apply { - FreeVec::Free(v) => { - match &**v{ - [FreeVec::Free(left), FreeVec::Free(right)] => { - match &***left { - [FreeVec::Free(left), FreeVec::Pure(middle), FreeVec::Free(right)] => { - match &***left { - [FreeVec::Pure(left), FreeVec::Pure(right)] => { - assert_nearly_equal!(4.0f64/3.0f64, *left, f64::EPSILON); - assert_nearly_equal!(5.0f64/3.0f64, *right, f64::EPSILON); - }, - _ => unreachable!() + FreeVec::Free(v) => match &**v { + [FreeVec::Free(left), FreeVec::Free(right)] => { + match &***left { + [FreeVec::Free(left), FreeVec::Pure(middle), FreeVec::Free(right)] => { + match &***left { + [FreeVec::Pure(left), FreeVec::Pure(right)] => { + assert_nearly_equal!(4.0f64 / 3.0f64, *left, f64::EPSILON); + assert_nearly_equal!(5.0f64 / 3.0f64, *right, f64::EPSILON); } - assert_nearly_equal!(2.0f64, *middle, f64::EPSILON); - match &***right { - [FreeVec::Pure(left),FreeVec::Pure(right)] => { - assert_nearly_equal!(8.0f64/3.0f64, *left, f64::EPSILON); - assert_nearly_equal!(3.0f64, *right, f64::EPSILON); - }, - _ => unreachable!() + _ => unreachable!(), + } + assert_nearly_equal!(2.0f64, *middle, f64::EPSILON); + match &***right { + [FreeVec::Pure(left), FreeVec::Pure(right)] => { + assert_nearly_equal!(8.0f64 / 3.0f64, *left, f64::EPSILON); + assert_nearly_equal!(3.0f64, *right, f64::EPSILON); } - }, - _ => unreachable!() + _ => unreachable!(), + } } - match &***right { - [FreeVec::Free(left),FreeVec::Pure(middle),FreeVec::Free(right)] => { - match &***left { - [FreeVec::Pure(left),FreeVec::Pure(right)] => { - assert_nearly_equal!(6.0f64, *left, f64::EPSILON); - assert_nearly_equal!(7.0f64, *right, f64::EPSILON); - }, - _ => unreachable!() + _ => unreachable!(), + } + match &***right { + [FreeVec::Free(left), FreeVec::Pure(middle), FreeVec::Free(right)] => { + match &***left { + [FreeVec::Pure(left), FreeVec::Pure(right)] => { + assert_nearly_equal!(6.0f64, *left, f64::EPSILON); + assert_nearly_equal!(7.0f64, *right, f64::EPSILON); } - assert_nearly_equal!(8.0f64, *middle, f64::EPSILON); - match &***right { - [FreeVec::Pure(left),FreeVec::Pure(right)] => { - assert_nearly_equal!(10.0f64, *left, f64::EPSILON); - assert_nearly_equal!(11.0f64, *right, f64::EPSILON); - }, - _ => unreachable!() + _ => unreachable!(), + } + assert_nearly_equal!(8.0f64, *middle, f64::EPSILON); + match &***right { + [FreeVec::Pure(left), FreeVec::Pure(right)] => { + assert_nearly_equal!(10.0f64, *left, f64::EPSILON); + assert_nearly_equal!(11.0f64, *right, f64::EPSILON); } - }, - _ => unreachable!() + _ => unreachable!(), + } } - }, - _ => unreachable!() + _ => unreachable!(), + } } - } - FreeVec::Pure(_) => unreachable!() + _ => unreachable!(), + }, + FreeVec::Pure(_) => unreachable!(), } -}
\ No newline at end of file +} diff --git a/tests/with_lifetimes.rs b/tests/with_lifetimes.rs index 697fc74..ee35274 100644 --- a/tests/with_lifetimes.rs +++ b/tests/with_lifetimes.rs @@ -3,34 +3,47 @@ //! Test for the case that the Functor the Free Monad is based on has lifetime parameters that do not depend on the //! lifetime of the mapping function in the Functor implementation. +use higher::{Apply, Bind, Functor}; use higher_free_macro::free; -use higher::{Functor, Bind, Apply}; #[derive(Functor, Clone)] -struct WithLifetimes<'a,'b, A>{ - s1 : &'a str, - s2 : &'b str, - next : A +struct WithLifetimes<'a, 'b, A> { + s1: &'a str, + s2: &'b str, + next: A, } -free!(FreeWithLifetimes<'a,'b,A>, WithLifetimes<'a,'b,FreeWithLifetimes<'a,'b,A>>); +free!( + FreeWithLifetimes<'a, 'b, A>, + WithLifetimes<'a, 'b, FreeWithLifetimes<'a, 'b, A>> +); -fn lifetime_helper<'a,'b>(s1 : &'a str, s2 : &'b str) -> FreeWithLifetimes<'a, 'b, u32>{ - let fv = FreeWithLifetimes::lift_f(WithLifetimes{ s1, s2, next: 15}); - fv.fmap(|x| x+1) +fn lifetime_helper<'a, 'b>(s1: &'a str, s2: &'b str) -> FreeWithLifetimes<'a, 'b, u32> { + let fv = FreeWithLifetimes::lift_f(WithLifetimes { s1, s2, next: 15 }); + fv.fmap(|x| x + 1) } #[test] -fn test_with_lifetimes(){ +fn test_with_lifetimes() { let s1 = "First"; let s2 = "Second"; let fv = lifetime_helper(s1, s2); let s3 = "Third"; let s4 = "Fourth"; - let fv = fv.bind(|x| FreeWithLifetimes::lift_f(WithLifetimes{ s1: s3, s2: s4, next : x+2})); + let fv = fv.bind(|x| { + FreeWithLifetimes::lift_f(WithLifetimes { + s1: s3, + s2: s4, + next: x + 2, + }) + }); let s5 = "Fifth"; let s6 = "Sixth"; - let fa = FreeWithLifetimes::lift_f(WithLifetimes{s1: s5, s2: s6, next : (|x| x+3).into()}); + let fa = FreeWithLifetimes::lift_f(WithLifetimes { + s1: s5, + s2: s6, + next: (|x| x + 3).into(), + }); let fv = fv.apply(fa); match fv { FreeWithLifetimes::Free(v) => { @@ -48,15 +61,15 @@ fn test_with_lifetimes(){ FreeWithLifetimes::Free(_) => unreachable!(), FreeWithLifetimes::Pure(a) => { assert_eq!(a, 21); - }, + } } - }, + } FreeWithLifetimes::Pure(_) => unreachable!(), } - }, + } FreeWithLifetimes::Pure(_) => unreachable!(), } - }, - FreeWithLifetimes::Pure(_) => unreachable!() + } + FreeWithLifetimes::Pure(_) => unreachable!(), } -}
\ No newline at end of file +} |
