grisette-0.4.0.0: test/Grisette/Core/Data/Class/ToConTests.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Grisette.Core.Data.Class.ToConTests (toConTests) where
import Control.Monad.Except (ExceptT (ExceptT))
import Control.Monad.Identity
( Identity (Identity),
IdentityT (IdentityT),
)
import Control.Monad.Trans.Maybe (MaybeT (MaybeT))
import qualified Control.Monad.Writer.Lazy as WriterLazy
import qualified Control.Monad.Writer.Strict as WriterStrict
import qualified Data.ByteString.Char8 as C
import Data.Foldable (traverse_)
import Data.Functor.Sum (Sum (InL, InR))
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Stack (HasCallStack)
import Grisette.Core.Data.Class.ITEOp (ITEOp (symIte))
import Grisette.Core.Data.Class.LogicalOp (LogicalOp (symNot, (.&&), (.||)))
import Grisette.Core.Data.Class.SEq (SEq ((.==)))
import Grisette.Core.Data.Class.TestValues
( conBool,
isymBool,
ssymBool,
symFalse,
symTrue,
)
import Grisette.Core.Data.Class.ToCon (ToCon (toCon))
import Grisette.IR.SymPrim.Data.SymPrim (SymBool)
import Test.Framework (Test, testGroup)
import Test.Framework.Providers.HUnit (testCase)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Test.HUnit (Assertion, (@?=))
import Test.QuickCheck (ioProperty)
toConForConcreteOkProp ::
(HasCallStack, ToCon v v, Show v, Eq v) => v -> Assertion
toConForConcreteOkProp v = toCon v @?= Just v
toConTests :: Test
toConTests =
testGroup
"ToCon"
[ testGroup
"ToCon for common types"
[ testGroup
"SymBool"
[ testGroup
"To Bool"
[ testCase "con" $ do
let bools :: [Bool] = [True, False]
traverse_ (\v -> toCon (conBool v) @?= Just v) bools,
testCase "Symbolic SymBools" $ do
let sbools :: [SymBool] =
[ ssymBool "a",
isymBool "a" 1,
ssymBool "a" .&& ssymBool "b",
ssymBool "a" .|| ssymBool "b",
symNot $ ssymBool "a",
ssymBool "a" .== ssymBool "b",
symIte (ssymBool "a") (ssymBool "b") (ssymBool "c")
]
traverse_ (\v -> toCon v @?= (Nothing :: Maybe Bool)) sbools
],
testCase "To SymBool" $ do
let sbools :: [SymBool] =
[ symTrue,
ssymBool "a",
isymBool "a" 1,
ssymBool "a" .&& ssymBool "b",
ssymBool "a" .|| ssymBool "b",
symNot $ ssymBool "a",
ssymBool "a" .== ssymBool "b",
symIte (ssymBool "a") (ssymBool "b") (ssymBool "c")
]
traverse_ (\v -> toCon v @?= Just v) sbools
],
testProperty "Bool" $ ioProperty . toConForConcreteOkProp @Bool,
testProperty "Integer" $ ioProperty . toConForConcreteOkProp @Integer,
testProperty "Char" $ ioProperty . toConForConcreteOkProp @Char,
testProperty "Int" $ ioProperty . toConForConcreteOkProp @Int,
testProperty "Int8" $ ioProperty . toConForConcreteOkProp @Int8,
testProperty "Int16" $ ioProperty . toConForConcreteOkProp @Int16,
testProperty "Int32" $ ioProperty . toConForConcreteOkProp @Int32,
testProperty "Int64" $ ioProperty . toConForConcreteOkProp @Int64,
testProperty "Word" $ ioProperty . toConForConcreteOkProp @Word,
testProperty "Word8" $ ioProperty . toConForConcreteOkProp @Word8,
testProperty "Word16" $ ioProperty . toConForConcreteOkProp @Word16,
testProperty "Word32" $ ioProperty . toConForConcreteOkProp @Word32,
testProperty "Word64" $ ioProperty . toConForConcreteOkProp @Word64,
testProperty "()" $ ioProperty . toConForConcreteOkProp @(),
testProperty "ByteString" $
ioProperty
. \(v :: String) -> toConForConcreteOkProp (C.pack v),
testGroup
"List"
[ testProperty "[Integer]" $
ioProperty . toConForConcreteOkProp @[Integer],
testCase "[SymBool]" $ do
toCon ([] :: [SymBool]) @?= (Just [] :: Maybe [Bool])
toCon ([symTrue] :: [SymBool]) @?= (Just [True] :: Maybe [Bool])
toCon ([ssymBool "a"] :: [SymBool])
@?= (Nothing :: Maybe [Bool])
toCon ([symTrue, symFalse] :: [SymBool])
@?= (Just [True, False] :: Maybe [Bool])
toCon ([symTrue, ssymBool "a"] :: [SymBool])
@?= (Nothing :: Maybe [Bool])
],
testGroup
"Maybe"
[ testProperty "Maybe Integer" $
ioProperty . toConForConcreteOkProp @(Maybe Integer),
testCase "Maybe SymBool" $ do
let toConMaybe :: Maybe SymBool -> Maybe (Maybe Bool)
toConMaybe = toCon
toConMaybe Nothing @?= (Just Nothing)
toConMaybe (Just symTrue) @?= (Just (Just True))
toConMaybe (Just $ ssymBool "a") @?= Nothing
],
testGroup
"Either"
[ testProperty "Either Integer Integer" $
ioProperty . toConForConcreteOkProp @(Either Integer Integer),
testCase "Either SymBool SymBool" $ do
let toConEither ::
Either SymBool SymBool ->
Maybe (Either Bool Bool)
toConEither = toCon
toConEither (Left symTrue) @?= (Just (Left True))
toConEither (Right symTrue) @?= (Just (Right True))
toConEither (Left $ ssymBool "a") @?= Nothing
toConEither (Right $ ssymBool "a") @?= Nothing
],
testGroup
"MaybeT"
[ testProperty "MaybeT Maybe Integer" $
ioProperty . \(v :: Maybe (Maybe Integer)) ->
toConForConcreteOkProp (MaybeT v),
testCase "MaybeT Maybe SymBool" $ do
toCon (MaybeT Nothing :: MaybeT Maybe SymBool)
@?= (Just $ MaybeT Nothing :: Maybe (MaybeT Maybe Bool))
toCon (MaybeT $ Just Nothing :: MaybeT Maybe SymBool)
@?= ( Just $ MaybeT $ Just Nothing ::
Maybe (MaybeT Maybe Bool)
)
toCon
( MaybeT $ Just $ Just symTrue ::
MaybeT Maybe SymBool
)
@?= ( Just $ MaybeT $ Just $ Just True ::
Maybe (MaybeT Maybe Bool)
)
toCon
( MaybeT $ Just $ Just $ ssymBool "a" ::
MaybeT Maybe SymBool
)
@?= (Nothing :: Maybe (MaybeT Maybe Bool))
],
testGroup
"ExceptT"
[ testProperty "ExceptT Integer Maybe Integer" $
ioProperty . \(v :: Maybe (Either Integer Integer)) ->
toConForConcreteOkProp (ExceptT v),
testCase "ExceptT SymBool Maybe SymBool" $ do
let toConExceptT ::
ExceptT SymBool Maybe SymBool ->
Maybe (ExceptT Bool Maybe Bool)
toConExceptT = toCon
toConExceptT (ExceptT Nothing) @?= Just (ExceptT Nothing)
toConExceptT (ExceptT $ Just $ Left symTrue)
@?= Just (ExceptT $ Just $ Left True)
toConExceptT (ExceptT $ Just $ Left $ ssymBool "a") @?= Nothing
toConExceptT (ExceptT $ Just $ Right symTrue)
@?= Just (ExceptT $ Just $ Right True)
toConExceptT (ExceptT $ Just $ Right $ ssymBool "a") @?= Nothing
],
testGroup
"(,)"
[ testProperty "(Integer, Integer)" $
ioProperty . toConForConcreteOkProp @(Integer, Integer),
testCase "(SymBool, SymBool)" $ do
let toConTuple2 :: (SymBool, SymBool) -> Maybe (Bool, Bool)
toConTuple2 = toCon
toConTuple2 (symTrue, symFalse) @?= Just (True, False)
toConTuple2 (symTrue, ssymBool "a") @?= Nothing
],
testGroup
"(,,)"
[ testProperty "(Integer, Integer, Integer)" $
ioProperty
. toConForConcreteOkProp @(Integer, Integer, Integer),
testCase "(SymBool, SymBool, SymBool)" $ do
let toConTuple3 ::
(SymBool, SymBool, SymBool) ->
Maybe (Bool, Bool, Bool)
toConTuple3 = toCon
toConTuple3 (symFalse, symTrue, symFalse)
@?= Just (False, True, False)
toConTuple3 (symFalse, symTrue, ssymBool "a")
@?= Nothing
],
testGroup
"(,,,)"
[ testProperty "(Integer, Integer, Integer, Integer)" $
ioProperty
. toConForConcreteOkProp
@(Integer, Integer, Integer, Integer),
testCase "(SymBool, SymBool, SymBool, SymBool)" $ do
let toConTuple4 ::
(SymBool, SymBool, SymBool, SymBool) ->
Maybe (Bool, Bool, Bool, Bool)
toConTuple4 = toCon
toConTuple4 (symTrue, symFalse, symTrue, symFalse)
@?= Just (True, False, True, False)
toConTuple4 (symTrue, symFalse, symTrue, ssymBool "a")
@?= Nothing
],
testGroup
"(,,,,)"
[ testProperty "(Integer, Integer, Integer, Integer, Integer)" $
ioProperty
. toConForConcreteOkProp
@(Integer, Integer, Integer, Integer, Integer),
testCase "(SymBool, SymBool, SymBool, SymBool, SymBool)" $ do
let toConTuple5 ::
(SymBool, SymBool, SymBool, SymBool, SymBool) ->
Maybe (Bool, Bool, Bool, Bool, Bool)
toConTuple5 = toCon
toConTuple5 (symFalse, symTrue, symFalse, symTrue, symFalse)
@?= Just (False, True, False, True, False)
toConTuple5 (symFalse, symTrue, symFalse, symTrue, ssymBool "a")
@?= Nothing
],
testGroup
"(,,,,,)"
[ testProperty
"(Integer, Integer, Integer, Integer, Integer, Integer)"
$ ioProperty
. toConForConcreteOkProp
@(Integer, Integer, Integer, Integer, Integer, Integer),
testCase
"(SymBool, SymBool, SymBool, SymBool, SymBool, SymBool)"
$ do
let toConTuple6 ::
( SymBool,
SymBool,
SymBool,
SymBool,
SymBool,
SymBool
) ->
Maybe (Bool, Bool, Bool, Bool, Bool, Bool)
toConTuple6 = toCon
toConTuple6
(symTrue, symFalse, symTrue, symFalse, symTrue, symFalse)
@?= Just (True, False, True, False, True, False)
toConTuple6
(symTrue, symFalse, symTrue, symFalse, symTrue, ssymBool "a")
@?= Nothing
],
testGroup
"(,,,,,,)"
[ testProperty
"(Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
$ ioProperty
. toConForConcreteOkProp
@( Integer,
Integer,
Integer,
Integer,
Integer,
Integer,
Integer
),
testCase
"(SymBool, SymBool, SymBool, SymBool, SymBool, SymBool, SymBool)"
$ do
let toConTuple7 ::
( SymBool,
SymBool,
SymBool,
SymBool,
SymBool,
SymBool,
SymBool
) ->
Maybe (Bool, Bool, Bool, Bool, Bool, Bool, Bool)
toConTuple7 = toCon
toConTuple7
( symFalse,
symTrue,
symFalse,
symTrue,
symFalse,
symTrue,
symFalse
)
@?= Just (False, True, False, True, False, True, False)
toConTuple7
( symFalse,
symTrue,
symFalse,
symTrue,
symFalse,
symTrue,
ssymBool "a"
)
@?= Nothing
],
testGroup
"(,,,,,,,)"
[ testProperty
"(Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
$ ioProperty
. toConForConcreteOkProp
@( Integer,
Integer,
Integer,
Integer,
Integer,
Integer,
Integer,
Integer
),
testCase
"(SymBool, SymBool, SymBool, SymBool, SymBool, SymBool, SymBool, SymBool)"
$ do
let toConTuple8 ::
( SymBool,
SymBool,
SymBool,
SymBool,
SymBool,
SymBool,
SymBool,
SymBool
) ->
Maybe (Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool)
toConTuple8 = toCon
toConTuple8
( symTrue,
symFalse,
symTrue,
symFalse,
symTrue,
symFalse,
symTrue,
symFalse
)
@?= Just
( True,
False,
True,
False,
True,
False,
True,
False
)
toConTuple8
( symTrue,
symFalse,
symTrue,
symFalse,
symTrue,
symFalse,
symTrue,
ssymBool "a"
)
@?= Nothing
],
testGroup
"Sum"
[ testProperty "Sum Maybe Maybe Integer" $
ioProperty . \(v :: Either (Maybe Integer) (Maybe Integer)) ->
toConForConcreteOkProp $ case v of
Left x -> InL x
Right x -> InR x,
testCase "Sum Maybe (Either SymBool) SymBool" $ do
let toConSum ::
Sum Maybe (Either SymBool) SymBool ->
Maybe (Sum Maybe (Either Bool) Bool)
toConSum = toCon
toConSum (InL (Just symTrue)) @?= Just (InL (Just True))
toConSum (InL (Just $ ssymBool "a")) @?= Nothing
toConSum (InR (Left symTrue)) @?= Just (InR (Left True))
toConSum (InR (Right symTrue)) @?= Just (InR (Right True))
toConSum (InR (Left $ ssymBool "a")) @?= Nothing
toConSum (InR (Right $ ssymBool "a")) @?= Nothing
],
testGroup
"WriterT"
[ testGroup
"Lazy"
[ testProperty "WriterT Integer (Either Integer) Integer" $
ioProperty . \(v :: Either Integer (Integer, Integer)) ->
toConForConcreteOkProp $ WriterLazy.WriterT v,
testCase "WriterT SymBool (Either SymBool) SymBool" $ do
let toConWriterT ::
WriterLazy.WriterT SymBool (Either SymBool) SymBool ->
Maybe (WriterLazy.WriterT Bool (Either Bool) Bool)
toConWriterT = toCon
toConWriterT (WriterLazy.WriterT $ Left symTrue)
@?= Just (WriterLazy.WriterT $ Left True)
toConWriterT (WriterLazy.WriterT $ Left $ ssymBool "a")
@?= Nothing
toConWriterT (WriterLazy.WriterT $ Right (symTrue, symTrue))
@?= Just (WriterLazy.WriterT $ Right (True, True))
toConWriterT
(WriterLazy.WriterT $ Right (ssymBool "a", symTrue))
@?= Nothing
toConWriterT
(WriterLazy.WriterT $ Right (symTrue, ssymBool "a"))
@?= Nothing
toConWriterT
(WriterLazy.WriterT $ Right (ssymBool "a", ssymBool "b"))
@?= Nothing
],
testGroup
"Strict"
[ testProperty "WriterT Integer (Either Integer) Integer" $
ioProperty . \(v :: Either Integer (Integer, Integer)) ->
toConForConcreteOkProp $ WriterStrict.WriterT v,
testCase "WriterT SymBool (Either SymBool) SymBool" $ do
let toConWriterT ::
WriterStrict.WriterT
SymBool
(Either SymBool)
SymBool ->
Maybe (WriterStrict.WriterT Bool (Either Bool) Bool)
toConWriterT = toCon
toConWriterT (WriterStrict.WriterT $ Left symTrue)
@?= Just (WriterStrict.WriterT $ Left True)
toConWriterT (WriterStrict.WriterT $ Left $ ssymBool "a")
@?= Nothing
toConWriterT
(WriterStrict.WriterT $ Right (symTrue, symTrue))
@?= Just (WriterStrict.WriterT $ Right (True, True))
toConWriterT
(WriterStrict.WriterT $ Right (ssymBool "a", symTrue))
@?= Nothing
toConWriterT
(WriterStrict.WriterT $ Right (symTrue, ssymBool "a"))
@?= Nothing
toConWriterT
(WriterStrict.WriterT $ Right (ssymBool "a", ssymBool "b"))
@?= Nothing
]
],
testGroup
"Identity"
[ testProperty "Identity Integer" $
ioProperty . \(v :: Integer) ->
toConForConcreteOkProp $ Identity v,
testCase "Identity SymBool" $ do
toCon (Identity symTrue) @?= Just (Identity True)
toCon (Identity $ ssymBool "a") @?= (Nothing :: Maybe (Identity Bool))
],
testGroup
"IdentityT"
[ testProperty "IdentityT (Either Integer) Integer" $
ioProperty . \(v :: Either Integer Integer) ->
toConForConcreteOkProp $ IdentityT v,
testCase "IdentityT (Either SymBool) SymBool" $ do
let toConIdentityT ::
IdentityT (Either SymBool) SymBool ->
Maybe (IdentityT (Either Bool) Bool)
toConIdentityT = toCon
toConIdentityT (IdentityT $ Left symTrue)
@?= Just (IdentityT $ Left True)
toConIdentityT (IdentityT $ Left $ ssymBool "a")
@?= Nothing
toConIdentityT (IdentityT $ Right symTrue)
@?= Just (IdentityT $ Right True)
toConIdentityT (IdentityT $ Right $ ssymBool "a")
@?= Nothing
]
]
]