quickcheck-dynamic-3.4.0: test/Spec/DynamicLogic/CounterModel.hs
module Spec.DynamicLogic.CounterModel where
import Control.Monad.Reader
import Data.IORef
import Test.QuickCheck
import Test.QuickCheck.Extras
import Test.QuickCheck.Monadic
import Test.QuickCheck.StateModel
import Test.Tasty hiding (after)
import Test.Tasty.QuickCheck
data Counter = Counter Int
deriving (Show, Generic)
deriving instance Show (Action Counter a)
deriving instance Eq (Action Counter a)
instance HasVariables (Action Counter a) where
getAllVariables _ = mempty
instance StateModel Counter where
data Action Counter a where
Inc :: Action Counter ()
Reset :: Action Counter Int
initialState = Counter 0
arbitraryAction _ _ = frequency [(5, pure $ Some Inc), (1, pure $ Some Reset)]
nextState (Counter n) Inc _ = Counter (n + 1)
nextState _ Reset _ = Counter 0
instance RunModel Counter (ReaderT (IORef Int) IO) where
perform _ Inc _ = do
ref <- ask
lift $ modifyIORef ref succ
perform _ Reset _ = do
ref <- ask
lift $ do
n <- readIORef ref
writeIORef ref 0
pure n
postcondition (Counter n, _) Reset _ res = pure $ n == res
postcondition _ _ _ _ = pure True
prop_counter :: Actions Counter -> Property
prop_counter as = monadicIO $ do
ref <- lift $ newIORef (0 :: Int)
runPropertyReaderT (runActions as) ref
assert True
tests :: TestTree
tests =
testGroup
"counter tests"
[ testProperty "prop_conter" $ prop_counter
]