grisette-0.5.0.0: test/Grisette/Core/Data/Class/ExtractSymbolicsTests.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Grisette.Core.Data.Class.ExtractSymbolicsTests
( extractSymbolicsTests,
)
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 as B
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Generics (Generic)
import GHC.Stack (HasCallStack)
import Generics.Deriving (Default (Default))
import Grisette
( ExtractSymbolics (extractSymbolics),
ITEOp (symIte),
LogicalOp (symNot, (.&&), (.||)),
SEq ((.==)),
SymBool,
SymbolSetOps (emptySet),
SymbolSetRep (buildSymbolSet),
)
import Grisette.Core.Data.Class.TestValues
( isymBool,
isymbolBool,
ssymBool,
ssymbolBool,
symTrue,
)
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)
data A = A1 | A2 SymBool | A3 SymBool SymBool
deriving (Generic, Show, Eq)
deriving (ExtractSymbolics) via (Default A)
concreteExtractSymbolicsOkProp ::
(HasCallStack, ExtractSymbolics a) => (a, a) -> Assertion
concreteExtractSymbolicsOkProp x = extractSymbolics x @?= emptySet
extractSymbolicsTests :: Test
extractSymbolicsTests =
testGroup
"ExtractSymbolics"
[ testGroup
"Common types"
[ testGroup
"SymBool"
[ testCase "con" $
extractSymbolics symTrue @?= emptySet,
testCase "ssym" $
extractSymbolics (ssymBool "a")
@?= buildSymbolSet (ssymbolBool "a"),
testCase "isym" $
extractSymbolics (isymBool "a" 1)
@?= buildSymbolSet (isymbolBool "a" 1),
testCase "And" $
extractSymbolics (ssymBool "a" .&& isymBool "b" 1)
@?= buildSymbolSet (ssymbolBool "a", isymbolBool "b" 1),
testCase "Or" $
extractSymbolics (ssymBool "a" .|| isymBool "b" 1)
@?= buildSymbolSet (ssymbolBool "a", isymbolBool "b" 1),
testCase "Equal" $
extractSymbolics (ssymBool "a" .== isymBool "b" 1)
@?= buildSymbolSet (ssymbolBool "a", isymbolBool "b" 1),
testCase "ITE" $
extractSymbolics
(symIte (ssymBool "a") (isymBool "b" 1) (ssymBool "c"))
@?= buildSymbolSet
( ssymbolBool "a",
isymbolBool "b" 1,
ssymbolBool "c"
),
testCase "Not" $
extractSymbolics (symNot $ isymBool "a" 1)
@?= buildSymbolSet (isymbolBool "a" 1)
],
testProperty "Bool" $
ioProperty . concreteExtractSymbolicsOkProp @Bool,
testProperty "Integer" $
ioProperty . concreteExtractSymbolicsOkProp @Integer,
testProperty "Char" $
ioProperty . concreteExtractSymbolicsOkProp @Char,
testProperty "Int" $ ioProperty . concreteExtractSymbolicsOkProp @Int,
testProperty "Int8" $
ioProperty . concreteExtractSymbolicsOkProp @Int8,
testProperty "Int16" $
ioProperty . concreteExtractSymbolicsOkProp @Int16,
testProperty "Int32" $
ioProperty . concreteExtractSymbolicsOkProp @Int32,
testProperty "Int64" $
ioProperty . concreteExtractSymbolicsOkProp @Int64,
testProperty "Word" $
ioProperty . concreteExtractSymbolicsOkProp @Word,
testProperty "Word8" $
ioProperty . concreteExtractSymbolicsOkProp @Word8,
testProperty "Word16" $
ioProperty . concreteExtractSymbolicsOkProp @Word16,
testProperty "Word32" $
ioProperty . concreteExtractSymbolicsOkProp @Word32,
testProperty "Word64" $
ioProperty . concreteExtractSymbolicsOkProp @Word64,
testGroup
"[SymBool]"
[ testCase "[]" $
extractSymbolics ([] :: [SymBool]) @?= emptySet,
testCase "[v]" $
extractSymbolics [ssymBool "a"]
@?= buildSymbolSet (ssymbolBool "a"),
testCase "[v1, v2]" $
extractSymbolics [ssymBool "a", ssymBool "b"]
@?= buildSymbolSet (ssymbolBool "a", ssymbolBool "b")
],
testGroup
"Maybe SymBool"
[ testCase "Nothing" $
extractSymbolics (Nothing :: Maybe SymBool) @?= emptySet,
testCase "Just v" $
extractSymbolics (Just (ssymBool "a"))
@?= buildSymbolSet (ssymbolBool "a")
],
testGroup
"Either SymBool SymBool"
[ testCase "Left v" $
extractSymbolics
(Left (ssymBool "a") :: Either SymBool SymBool)
@?= buildSymbolSet (ssymbolBool "a"),
testCase "Right v" $
extractSymbolics
(Right (ssymBool "a") :: Either SymBool SymBool)
@?= buildSymbolSet (ssymbolBool "a")
],
testGroup
"MaybeT Maybe SymBool"
[ testCase "MaybeT Nothing" $
extractSymbolics (MaybeT Nothing :: MaybeT Maybe SymBool)
@?= emptySet,
testCase "MaybeT (Just Nothing)" $
extractSymbolics (MaybeT (Just Nothing) :: MaybeT Maybe SymBool)
@?= emptySet,
testCase "MaybeT (Just (Just v))" $
extractSymbolics (MaybeT (Just (Just (ssymBool "a"))))
@?= buildSymbolSet (ssymbolBool "a")
],
testGroup
"ExceptT SymBool Maybe SymBool"
[ testCase "ExceptT Nothing" $
extractSymbolics
(ExceptT Nothing :: ExceptT SymBool Maybe SymBool)
@?= emptySet,
testCase "ExceptT (Just (Left v))" $
extractSymbolics
( ExceptT (Just (Left (ssymBool "a"))) ::
ExceptT SymBool Maybe SymBool
)
@?= buildSymbolSet (ssymbolBool "a"),
testCase "ExceptT (Just (Right v))" $
extractSymbolics
( ExceptT (Just (Right (ssymBool "a"))) ::
ExceptT SymBool Maybe SymBool
)
@?= buildSymbolSet (ssymbolBool "a")
],
testGroup
"WriterT SymBool Maybe SymBool"
[ testGroup
"Lazy"
[ testCase "WriterT Nothing" $
extractSymbolics
( WriterLazy.WriterT Nothing ::
WriterLazy.WriterT SymBool Maybe SymBool
)
@?= emptySet,
testCase "WriterT (Just (v1, v2))" $
extractSymbolics
( WriterLazy.WriterT
(Just (ssymBool "a", ssymBool "b")) ::
WriterLazy.WriterT SymBool Maybe SymBool
)
@?= buildSymbolSet (ssymbolBool "a", ssymbolBool "b")
],
testGroup
"Strict"
[ testCase "WriterT Nothing" $
extractSymbolics
( WriterStrict.WriterT Nothing ::
WriterStrict.WriterT SymBool Maybe SymBool
)
@?= emptySet,
testCase "WriterT (Just (v1, v2))" $
extractSymbolics
( WriterStrict.WriterT
(Just (ssymBool "a", ssymBool "b")) ::
WriterStrict.WriterT SymBool Maybe SymBool
)
@?= buildSymbolSet (ssymbolBool "a", ssymbolBool "b")
]
],
testProperty "()" (ioProperty . concreteExtractSymbolicsOkProp @()),
testCase "(,)" $
extractSymbolics (ssymBool "a", ssymBool "b")
@?= buildSymbolSet (ssymbolBool "a", ssymbolBool "b"),
testCase "(,,)" $
extractSymbolics (ssymBool "a", ssymBool "b", ssymBool "c")
@?= buildSymbolSet
(ssymbolBool "a", ssymbolBool "b", ssymbolBool "c"),
testGroup
"ByteString"
[ testCase "\"\"" $
extractSymbolics ("" :: B.ByteString) @?= emptySet,
testCase "\"a\"" $
extractSymbolics ("a" :: B.ByteString) @?= emptySet
],
testCase "Identity SymBool" $
extractSymbolics (Identity (ssymBool "a"))
@?= buildSymbolSet (ssymbolBool "a"),
testGroup
"IdentityT (Either SymBool) SymBool"
[ testCase "Identity (Left v)" $
extractSymbolics
( IdentityT $ Left (ssymBool "a") ::
IdentityT (Either SymBool) SymBool
)
@?= buildSymbolSet (ssymbolBool "a"),
testCase "Identity (Right v)" $
extractSymbolics
( IdentityT $ Right (ssymBool "a") ::
IdentityT (Either SymBool) SymBool
)
@?= buildSymbolSet (ssymbolBool "a")
]
],
testGroup
"deriving ExtractSymbolics for ADT"
[ testGroup
"Simple ADT"
[ testCase "A1" $
extractSymbolics A1 @?= emptySet,
testCase "A2" $
extractSymbolics (A2 (ssymBool "a"))
@?= buildSymbolSet (ssymbolBool "a"),
testCase "A3" $
extractSymbolics (A3 (ssymBool "a") (ssymBool "b"))
@?= buildSymbolSet (ssymbolBool "a", ssymbolBool "b")
]
]
]