{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Math.Programming.Tests.Api where
import Control.Monad.IO.Class
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck
import Math.Programming
makeApiTests
:: (Num (Numeric m), MonadIO m, LPMonad m)
=> (m () -> IO ())
-> TestTree
makeApiTests runner = testGroup "API tests"
[ testCase "Set/get variable names" (runner setGetVariableName)
, testCase "Set/get constraint names" (runner setGetConstraintName)
]
setGetVariableName :: (MonadIO m, LPMonad m) => m ()
setGetVariableName = do
let name = "foo"
x <- free
setVariableName x name
vName <- getVariableName x
liftIO $ vName @?= name
setGetConstraintName :: (Num (Numeric m), MonadIO m, LPMonad m) => m ()
setGetConstraintName = do
let name = "foo"
x <- free
c <- (x @>=# 0) `named` name
cName <- getConstraintName c
liftIO $ cName @?= name
data Action
= AddVariable
| AddConstraint
| AddThenDeleteVariable
| AddThenDeleteConstraint
deriving
( Enum
, Show
)
instance Arbitrary Action where
arbitrary = elements actions
where
actions = [AddVariable .. AddThenDeleteConstraint]
newtype LPActions m = LPActions (m ())
instance LPMonad m => Arbitrary (LPActions m) where
arbitrary = LPActions <$> sized lpActions
lpActions :: LPMonad m => Int -> Gen (m ())
lpActions remaining
| remaining <= 0 = return (return ())
| otherwise = do
action <- arbitrary
case action of
AddVariable
-> return (addVariable >> return ())
AddThenDeleteVariable
-> bindOver addVariable removeVariable <$> lpActions (remaining - 1)
_ -> return (return ())
bindOver
:: (Monad m)
=> m a
-> (a -> m b)
-> m ()
-> m b
bindOver action fn intermediate = action >>= (\x -> intermediate >> fn x)
arbitraryLPActionsProp :: LPActions m -> m ()
arbitraryLPActionsProp (LPActions actions) = actions