{-# 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))