{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Prelude hiding
( all
, any
, break
, drop
, dropWhile
, filter
, foldMap
, foldl
, foldl1
, foldr
, foldr1
, head
, init
, last
, length
, repeat
, null
, replicate
, reverse
, seq
, span
, splitAt
, tail
, take
, takeWhile
)
import Data.Bifunctor (Bifunctor(..))
import Data.MonoTraversable
( MonoFoldable(..)
, MonoFunctor(..)
, MonoPointed(..)
, MonoTraversable(..)
)
import Data.Sequences (IsSequence(..), SemiSequence(..))
import Data.Transaction
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck
import Test.QuickCheck.Exception
main :: IO ()
main = hspec spec
exceptionableEq :: Eq a => Either AnException a -> Either AnException a -> Bool
exceptionableEq (Left _) (Left _) = True
exceptionableEq (Right a) (Right b) = a == b
exceptionableEq _ _ = False
spec :: Spec
spec = do
describe "MonoFunctor" $ do
describe "omap" $ do
prop "is equivalent to list" $
\(Fun _ f) (a :: [Int]) ->
omap f a == (toList . omap f . listToTrans) a
describe "MonoFoldable" $ do
describe "ofoldMap" $ do
prop "is equivalent to list" $
\(Fun _ f) (a :: [Int]) ->
(ofoldMap f a :: String) ==
(ofoldMap f $ listToTrans a)
describe "ofoldr" $ do
modifyMaxSize (const 20) $ prop "is equivalent to list" $
\f (a :: String) (mono :: [Int]) ->
(ofoldr (applyFun2 f) a mono) ==
(ofoldr (applyFun2 f) a $ listToTrans mono)
describe "ofoldl'" $ do
modifyMaxSize (const 20) $ prop "is equivalent to list" $
\f (a :: String) (mono :: [Int]) ->
(ofoldl' (applyFun2 f) a mono) ==
(ofoldl' (applyFun2 f) a $ listToTrans mono)
describe "otoList" $ do
prop "is equivalent to list" $
\(mono :: [Int]) ->
otoList (listToTrans mono) == mono
describe "oall" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(oall f mono) ==
(oall f $ listToTrans mono)
describe "oany" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(oany f mono) ==
(oany f $ listToTrans mono)
describe "onull" $ do
prop "is equivalent to list" $
\(mono :: [Int]) ->
(onull mono) ==
(onull $ listToTrans mono)
describe "olength" $ do
prop "is equivalent to list" $
\(mono :: [Int]) ->
(olength mono) ==
(olength $ listToTrans mono)
describe "olength64" $ do
prop "is equivalent to list" $
\(mono :: [Int]) ->
(olength64 mono) ==
(olength64 $ listToTrans mono)
describe "ocompareLength" $ do
prop "is equivalent to list" $
\(i :: Integer) (mono :: [String]) ->
(ocompareLength mono i) ==
(ocompareLength (listToTrans mono) i)
describe "otraverse_" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(otraverse_ (f :: Int -> Maybe String) mono) ==
(otraverse_ f $ listToTrans mono)
describe "ofor_" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(ofor_ mono (f :: Int -> Maybe String)) ==
(ofor_ (listToTrans mono) f)
describe "omapM_" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(omapM_ (f :: Int -> Maybe ()) mono) ==
(omapM_ f (listToTrans mono))
describe "oforM_" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(ofor_ mono (f :: Int -> Maybe ())) ==
(ofor_ (listToTrans mono) f)
describe "ofoldlM" $ do
modifyMaxSize (const 40) $ prop "is equivalent to list" $
\f (a :: String) (mono :: [Int]) ->
(ofoldlM (applyFun2 f) a mono :: Maybe String) ==
(ofoldlM (applyFun2 f) a (listToTrans mono))
describe "ofoldMap1Ex" $ do
it "is equivalent to list" $ again $ \(Fun _ f) (mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (ofoldMap1Ex f mono :: String)
<*> tryEvaluate (ofoldMap1Ex f (listToTrans mono))
describe "ofoldr1Ex" $ do
it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (ofoldr1Ex (applyFun2 f) mono)
<*> tryEvaluate (ofoldr1Ex (applyFun2 f) (listToTrans mono))
describe "ofoldl1Ex'" $ do
it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (ofoldl1Ex' (applyFun2 f) mono)
<*> tryEvaluate (ofoldl1Ex' (applyFun2 f) (listToTrans mono))
describe "headEx" $ do
it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (headEx mono)
<*> tryEvaluate (headEx (listToTrans mono))
describe "lastEx" $ do
it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (lastEx mono)
<*> tryEvaluate (lastEx (listToTrans mono))
describe "unsafeHead" $ do
it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (unsafeHead mono)
<*> tryEvaluate (unsafeHead (listToTrans mono))
describe "unsafeLast" $ do
it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (unsafeLast mono)
<*> tryEvaluate (unsafeLast (listToTrans mono))
describe "maximumByEx" $ do
it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (maximumByEx (applyFun2 f) mono)
<*> tryEvaluate (maximumByEx (applyFun2 f) (listToTrans mono))
describe "minimumByEx" $ do
it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (minimumByEx (applyFun2 f) mono)
<*> tryEvaluate (minimumByEx (applyFun2 f) (listToTrans mono))
#if MIN_VERSION_mono_traversable(1,0,5)
describe "oelem" $ do
prop "is equivalent to list" $
\(a :: Int) (mono :: [Int]) ->
(oelem a mono) ==
(oelem a (listToTrans mono))
describe "onotElem" $ do
prop "is equivalent to list" $
\(a :: Int) (mono :: [Int]) ->
(onotElem a mono) ==
(onotElem a (listToTrans mono))
#endif
describe "MonoPointed" $ do
describe "opoint" $ do
prop "is equivalent to list" $
\(a :: Int) ->
(opoint a) ==
(toList $ opoint a)
describe "SemiSequence" $ do
describe "intersperse" $ do
prop "is equivalent to list" $
\(seq :: [Int]) a ->
(intersperse a seq) ==
(toList $ intersperse a $ listToTrans seq)
describe "reverse" $ do
prop "is equivalent to list" $
\(seq :: [Int]) ->
(reverse seq) ==
(toList $ reverse $ listToTrans seq)
describe "sortBy" $ do
prop "is equivalent to list" $
\f (seq :: [Int]) ->
(sortBy (applyFun2 f) seq) ==
(toList $ sortBy (applyFun2 f) $ listToTrans seq)
describe "cons" $ do
prop "is equivalent to list" $
\a (seq :: [Int]) ->
(cons a seq) ==
(toList $ cons a $ listToTrans seq)
describe "snoc" $ do
prop "is equivalent to list" $
\a (seq :: [Int]) ->
(snoc seq a) ==
(toList $ snoc (listToTrans seq) a)
describe "MonoTraversable" $ do
describe "otraverse" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(otraverse (f :: Int -> Maybe Int) mono) ==
(toList <$> otraverse f (listToTrans mono))
describe "omapM" $ do
prop "is equivalent to list" $
\(Fun _ f) (mono :: [Int]) ->
(otraverse (f :: Int -> Maybe Int) mono) ==
(toList <$> otraverse f (listToTrans mono))
describe "IsSequence" $ do
describe "fromList" $ do
prop "is equivalent to list" $
\(seq :: [Int]) ->
(toList $ fromList seq) == seq
#if MIN_VERSION_mono_traversable(1,0,2)
describe "lengthIndex" $ do
prop "is equivalent to list" $
\(seq :: [Int]) ->
(lengthIndex seq) ==
(lengthIndex (listToTrans seq))
#endif
describe "break" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(break f seq) ==
(let (a,b) = break f (listToTrans seq) in (toList a, toList b))
describe "span" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(span f seq) ==
(let (a,b) = span f (listToTrans seq) in (toList a, toList b))
describe "dropWhile" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(dropWhile f seq) ==
(toList $ dropWhile f $ listToTrans seq)
describe "takeWhile" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(takeWhile f seq) ==
(toList $ takeWhile f $ listToTrans seq)
describe "splitAt" $ do
prop "is equivalent to list" $
\n (seq :: [Int]) ->
(splitAt n seq) ==
(let (a,b) = splitAt n (listToTrans seq) in (toList a, toList b))
describe "unsafeSplitAt" $ do
prop "is equivalent to list" $
\n (seq :: [Int]) ->
(unsafeSplitAt n seq) ==
(let (a,b) = unsafeSplitAt n (listToTrans seq) in (toList a, toList b))
describe "take" $ do
prop "is equivalent to list" $
\n (seq :: [Int]) ->
(take n seq) ==
(toList $ take n $ fromList seq)
describe "unsafeTake" $ do
prop "is equivalent to list" $
\n (seq :: [Int]) ->
(unsafeTake n seq) ==
(toList $ unsafeTake n $ fromList seq)
describe "drop" $ do
prop "is equivalent to list" $
\n (seq :: [Int]) ->
(drop n seq) ==
(toList $ drop n $ fromList seq)
describe "unsafeDrop" $ do
prop "is equivalent to list" $
\n (seq :: [Int]) ->
(unsafeDrop n seq) ==
(toList $ unsafeDrop n $ fromList seq)
#if MIN_VERSION_mono_traversable(1,0,4)
describe "dropEnd" $ do
prop "is equivalent to list" $
\n (seq :: [Int]) ->
(dropEnd n seq) ==
(toList $ dropEnd n $ fromList seq)
#endif
describe "partition" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(partition f seq) ==
(let (a, b) = partition f (listToTrans seq) in (toList a, toList b))
describe "uncons" $ do
prop "is equivalent to list" $
\(seq :: [Int]) ->
(uncons seq) ==
(second toList <$> uncons (listToTrans seq))
describe "unsnoc" $ do
prop "is equivalent to list" $
\(seq :: [Int]) ->
(unsnoc seq) ==
(first toList <$> unsnoc (listToTrans seq))
describe "filter" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(filter f seq) ==
(toList $ filter f $ listToTrans seq)
describe "filterM" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(filterM (f :: Int -> Maybe Bool) seq) ==
(toList <$> filterM f (listToTrans seq))
describe "replicate" $ do
prop "is equivalent to list" $
\n (a :: Int) ->
(replicate n a) ==
(toList $ replicate n a)
describe "replicateM" $ do
prop "is equivalent to list" $
\n (ma :: Maybe Int) ->
(replicateM n ma) ==
(toList <$> replicateM n ma)
describe "groupBy" $ do
prop "is equivalent to list" $
\f (seq :: [Int]) ->
(groupBy (applyFun2 f) seq) ==
(map toList $ groupBy (applyFun2 f) $ listToTrans seq)
describe "groupAllOn" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(groupAllOn (f :: Int -> String) seq) ==
(map toList $ groupAllOn f $ listToTrans seq)
describe "subsequences" $ do
modifyMaxSize (const 10) $ prop "is equivalent to list" $
\(seq :: [Int]) ->
(subsequences seq) ==
(map toList $ subsequences $ listToTrans seq)
describe "permutations" $ do
modifyMaxSize (const 10) $ prop "is equivalent to list" $
\(seq :: [Int]) ->
(permutations seq) ==
(map toList $ permutations $ listToTrans seq)
describe "tailEx" $ do
it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (tailEx seq)
<*> tryEvaluate (toList $ tailEx $ listToTrans seq)
describe "tailMay" $ do
prop "is equivalent to list" $
\(seq :: [Int]) ->
(tailMay seq) ==
(fmap toList $ tailMay $ listToTrans seq)
describe "initEx" $ do
it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (initEx seq)
<*> tryEvaluate (toList $ initEx $ listToTrans seq)
describe "initMay" $ do
prop "is equivalent to list" $
\(seq :: [Int]) ->
(initMay seq) ==
(fmap toList $ initMay $ listToTrans seq)
describe "unsafeTail" $ do
it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (unsafeTail seq)
<*> tryEvaluate (toList $ unsafeTail $ listToTrans seq)
describe "unsafeInit" $ do
it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
exceptionableEq
<$> tryEvaluate (unsafeInit seq)
<*> tryEvaluate (toList $ unsafeInit $ listToTrans seq)
describe "index" $ do
prop "is equivalent to list" $
\(seq :: [Int]) n ->
(index seq n) ==
(index (listToTrans seq) n)
describe "indexEx" $ do
it "is equivalent to list" $ again $ \(seq :: [Int]) n -> ioProperty $
exceptionableEq <$> tryEvaluate (indexEx seq n) <*> tryEvaluate (indexEx (listToTrans seq) n)
describe "unsafeIndex" $ do
it "is equivalent to list" $ again $ \(seq :: [Int]) n -> ioProperty $
exceptionableEq <$> tryEvaluate (unsafeIndex seq n) <*> tryEvaluate (unsafeIndex (listToTrans seq) n)
describe "splitWhen" $ do
prop "is equivalent to list" $
\(Fun _ f) (seq :: [Int]) ->
(splitWhen f seq) ==
(fmap toList $ splitWhen f $ listToTrans seq)
listToTrans :: [a] -> Transaction a
listToTrans = fromList