grisette-0.5.0.0: test/Grisette/Lib/Control/ApplicativeTest.hs
{-# LANGUAGE OverloadedStrings #-}
module Grisette.Lib.Control.ApplicativeTest
( applicativeFunctionTests,
)
where
import Control.Applicative (Alternative (empty))
import Control.Monad.State
( MonadState (get, put),
MonadTrans (lift),
StateT (runStateT),
)
import Control.Monad.Trans.Maybe (MaybeT (MaybeT))
import Grisette
( UnionM,
UnionMergeable1 (mrgIfPropagatedStrategy),
mrgAsum,
mrgEmpty,
mrgPure,
mrgReturn,
mrgSingle,
)
import Grisette.Lib.Control.Applicative
( mrgLiftA,
mrgLiftA2,
mrgLiftA3,
mrgMany,
mrgOptional,
mrgSome,
(.*>),
(.<*),
(.<**>),
(.<*>),
(.<|>),
)
import Grisette.TestUtil.NoMerge
( NoMerge (NoMerge),
noMergeNotMerged,
oneNotMerged,
)
import Test.Framework
( Test,
TestOptions' (topt_timeout),
plusTestOptions,
testGroup,
)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit ((@?=))
applicativeFunctionTests :: Test
applicativeFunctionTests =
testGroup
"Applicative"
[ testCase "mrgPure" $ (mrgPure 1 :: UnionM Integer) @?= mrgSingle 1,
testGroup
".<*>"
[ testCase "merge result" $ do
let actual =
(return (\x -> x * x))
.<*> mrgIfPropagatedStrategy "a" (return $ -1) (return 1)
actual @?= (mrgSingle 1 :: UnionM Integer),
testCase "merge arguments" $ do
let actual = (return (const NoMerge)) .<*> oneNotMerged
actual @?= (mrgSingle NoMerge :: UnionM NoMerge)
],
testGroup
"mrgLiftA2"
[ testCase "merge result" $ do
let actual =
mrgLiftA2 (const $ const 1) noMergeNotMerged noMergeNotMerged
let expected = mrgPure 1 :: UnionM Int
actual @?= expected,
testCase "merge argument" $ do
let actual =
mrgLiftA2 (const $ const NoMerge) oneNotMerged oneNotMerged
let expected = mrgPure NoMerge
actual @?= expected
],
testGroup
".*>"
[ testCase "merge result" $
noMergeNotMerged .*> oneNotMerged @?= mrgSingle 1,
testCase "merge arguments" $
oneNotMerged .*> return NoMerge @?= mrgSingle NoMerge
],
testGroup
".<*"
[ testCase "merge result" $
oneNotMerged .<* noMergeNotMerged @?= mrgSingle 1,
testCase "merge arguments" $
return NoMerge .<* oneNotMerged @?= mrgSingle NoMerge
],
testCase "mrgEmpty" $
(mrgEmpty :: MaybeT UnionM Integer) @?= MaybeT (mrgReturn Nothing),
testGroup
".<|>"
[ testCase "merge result" $
return 1 .<|> return 2 @?= (mrgSingle 1 :: MaybeT UnionM Integer),
testCase "merge lhs" $ do
let lhs =
MaybeT $
mrgIfPropagatedStrategy "a" (return Nothing) (return Nothing)
let expected = mrgSingle NoMerge :: MaybeT UnionM NoMerge
lhs .<|> return NoMerge @?= expected
],
plusTestOptions (mempty {topt_timeout = Just (Just 1000000)}) $
testGroup
"mrgSome"
[ testCase "merge" $
runStateT (mrgSome f) 100 @?= (mrgSingle (replicate 100 (), 0)),
testCase "single" $
runStateT (mrgSome f) 1 @?= (mrgSingle ([()], 0)),
testCase "zero" $
runStateT (mrgSome f) 0 @?= MaybeT (mrgReturn Nothing)
],
plusTestOptions (mempty {topt_timeout = Just (Just 1000000)}) $
testGroup
"mrgMany"
[ testCase "merge" $
runStateT (mrgMany f) 100 @?= (mrgSingle (replicate 100 (), 0)),
testCase "single" $
runStateT (mrgMany f) 1 @?= (mrgSingle ([()], 0)),
testCase "zero" $
runStateT (mrgMany f) 0 @?= (mrgSingle ([], 0))
],
testGroup
".<**>"
[ testCase "merge result" $ do
let actual =
mrgIfPropagatedStrategy "a" (return $ -1) (return 1)
.<**> (return (\x -> x * x))
actual @?= (mrgSingle 1 :: UnionM Integer),
testCase "merge arguments" $ do
let actual = oneNotMerged .<**> (return (const NoMerge))
actual @?= (mrgSingle NoMerge :: UnionM NoMerge)
],
testGroup
"mrgLiftA"
[ testCase "merge result" $ do
let actual = mrgLiftA (const 1) noMergeNotMerged
let expected = mrgReturn 1 :: UnionM Int
actual @?= expected,
testCase "merge argument" $ do
let actual = mrgLiftA (const NoMerge) oneNotMerged
let expected = mrgReturn NoMerge
actual @?= expected
],
testGroup
"mrgLiftA3"
[ testCase "merge result" $ do
let actual =
mrgLiftA3
(const $ const $ const 1)
noMergeNotMerged
noMergeNotMerged
noMergeNotMerged
let expected = mrgReturn 1 :: UnionM Int
actual @?= expected,
testCase "merge argument" $ do
let actual =
mrgLiftA3
(const $ const $ const NoMerge)
oneNotMerged
oneNotMerged
oneNotMerged
let expected = mrgReturn NoMerge
actual @?= expected
],
testGroup
"mrgOptional"
[ testCase "one" $ do
let actual =
mrgOptional
( MaybeT $
mrgIfPropagatedStrategy
"a"
(return $ Just 1)
(return $ Just 1)
)
let expected = mrgSingle (Just 1) :: MaybeT UnionM (Maybe Int)
actual @?= expected,
testCase "none" $ do
let actual =
mrgOptional
( MaybeT $
mrgIfPropagatedStrategy "a" (return Nothing) (return Nothing)
)
let expected = mrgSingle Nothing :: MaybeT UnionM (Maybe Int)
actual @?= expected
],
plusTestOptions (mempty {topt_timeout = Just (Just 1000000)}) $
testGroup
"mrgAsum"
[ testCase "merge" $ do
let none =
MaybeT $
mrgIfPropagatedStrategy "a" (return Nothing) (return Nothing)
let expected =
MaybeT (mrgSingle Nothing) ::
MaybeT UnionM (Maybe Int)
mrgAsum (replicate 100 none) @?= expected,
testCase "semantics" $ do
(mrgAsum [mrgEmpty, mrgEmpty] :: MaybeT UnionM Integer)
@?= mrgEmpty
(mrgAsum [mrgPure 1, mrgEmpty] :: MaybeT UnionM Integer)
@?= mrgPure 1
(mrgAsum [mrgEmpty, mrgPure 1] :: MaybeT UnionM Integer)
@?= mrgPure 1
(mrgAsum [mrgPure 2, mrgPure 1] :: MaybeT UnionM Integer)
@?= mrgPure 2
]
]
f :: StateT Int (MaybeT UnionM) ()
f = do
i <- get
if (i == 0)
then empty
else do
put (i - 1)
lift . lift $
mrgIfPropagatedStrategy "a" (return ()) (return ())