{-# OPTIONS_GHC -fno-warn-orphans #-} module CyclicList (tests) where import Control.Applicative import qualified Data.Foldable as F import Test.Tasty import Test.Tasty.QuickCheck import Numeric.QuadraticIrrational.CyclicList instance Arbitrary a => Arbitrary (CycList a) where arbitrary = oneof [ NonCyc <$> arbitrary , Cyc <$> arbitrary <*> arbitrary <*> arbitrary ] shrink (NonCyc as) = [ NonCyc as' | as' <- shrink as ] shrink (Cyc as b bs) = [ Cyc as' b bs | as' <- shrink as ] ++ [ Cyc as b' bs | b' <- shrink b ] ++ [ Cyc as b bs' | bs' <- shrink bs ] tests :: TestTree tests = testGroup "CyclicList" [ testProperty "fmap" . withListEquiv $ \asC asL -> initEq' (fmap (*10) asC) (fmap (*10) asL) , testProperty "toList" . withListEquiv $ \asC asL -> take 1000 (F.toList asC) === take 1000 asL ] withListEquiv :: (CycList Integer -> [Integer] -> b) -> CycList Integer -> b withListEquiv f cl@(NonCyc as) = f cl as withListEquiv f cl@(Cyc as b bs) = f cl (as ++ cycle (b:bs)) initEq :: Eq a => CycList a -> [a] -> Bool initEq (NonCyc as) cs = take 1000 cs == take 1000 as initEq (Cyc as b bs) cs = take 1000 cs == take 1000 (as ++ cycle (b:bs)) initEq' :: (Eq a, Show a) => CycList a -> [a] -> Property initEq' (NonCyc as) cs = take 1000 cs === take 1000 as initEq' (Cyc as b bs) cs = take 1000 cs === take 1000 (as ++ cycle (b:bs))