Skip to content

Commit e4a2672

Browse files
remove the monad from the postcondition and get rid of extra callbacks
1 parent 43ac971 commit e4a2672

File tree

4 files changed

+12
-37
lines changed

4 files changed

+12
-37
lines changed

quickcheck-dynamic/src/Test/QuickCheck/ParallelActions.hs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,13 @@ import Test.QuickCheck.Monadic
1212
import Test.QuickCheck.StateModel.Variables
1313
import Test.QuickCheck.StateModel
1414
import Control.Concurrent
15-
import Control.Monad.Identity
1615
import Control.Arrow (first)
1716
import Data.Tree
1817

19-
2018
class RunModel state m => RunModelPar state m where
2119
performPar :: Typeable a => Action state a -> LookUp -> m (PerformResult state m a)
2220
performPar = perform (error "Trying to evaluate state in default implementation of performPar")
2321

24-
postconditionPar :: (state, state) -> Action state a -> LookUp -> a -> PostconditionM Identity Bool
25-
26-
postconditionOnFailurePar :: (state, state) -> Action state a -> LookUp -> Either (Error state m) a -> PostconditionM Identity Bool
27-
postconditionOnFailurePar _ _ _ _ = pure True
28-
2922
monitoringPar :: Action state a -> LookUp -> Either (Error state m) a -> Property -> Property
3023
monitoringPar _ _ _ = id
3124

@@ -188,13 +181,13 @@ checkTrace s env (Node (TraceStep r v (ActionWithPolarity a _)) trs) =
188181
s' = computeNextState s act v
189182
env' | Right val <- r = (v :== val) : env
190183
| otherwise = env
191-
checkPost | Right val <- r, polarity act == PosPolarity = fst . runWriter . runPost $ postconditionPar @state @m
184+
checkPost | Right val <- r, polarity act == PosPolarity = fst . runWriter . runPost $ postcondition @state @m
192185
(underlyingState s, underlyingState s')
193186
(polarAction act)
194187
(lookUpVar env')
195188
val
196189
| Left{} <- r, polarity act == PosPolarity = False
197-
| otherwise = fst . runWriter . runPost $ postconditionOnFailurePar @state @m
190+
| otherwise = fst . runWriter . runPost $ postconditionOnFailure @state @m
198191
(underlyingState s, underlyingState s')
199192
(polarAction act)
200193
(lookUpVar env')

quickcheck-dynamic/src/Test/QuickCheck/StateModel.hs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ module Test.QuickCheck.StateModel (
5353
) where
5454

5555
import Control.Monad
56-
import Control.Monad.Reader
5756
import Control.Monad.Writer
5857
import Data.Data
5958
import Data.Kind
@@ -165,27 +164,24 @@ class
165164

166165
deriving instance (forall a. Show (Action state a)) => Show (Any (Action state))
167166

168-
newtype PostconditionM m a = PostconditionM {runPost :: WriterT (Endo Property, Endo Property) m a}
167+
newtype PostconditionM a = PostconditionM {runPost :: Writer (Endo Property, Endo Property) a}
169168
deriving (Functor, Applicative, Monad)
170169

171-
instance MonadTrans PostconditionM where
172-
lift = PostconditionM . lift
173-
174-
evaluatePostCondition :: Monad m => PostconditionM m Bool -> PropertyM m ()
170+
evaluatePostCondition :: Monad m => PostconditionM Bool -> PropertyM m ()
175171
evaluatePostCondition post = do
176-
(b, (Endo mon, Endo onFail)) <- run . runWriterT . runPost $ post
172+
let (b, (Endo mon, Endo onFail)) = runWriter . runPost $ post
177173
monitor mon
178174
unless b $ monitor onFail
179175
assert b
180176

181177
-- | Apply the property transformation to the property after evaluating
182178
-- the postcondition. Useful for collecting statistics while avoiding
183179
-- duplication between `monitoring` and `postcondition`.
184-
monitorPost :: Monad m => (Property -> Property) -> PostconditionM m ()
180+
monitorPost :: (Property -> Property) -> PostconditionM ()
185181
monitorPost m = PostconditionM $ tell (Endo m, mempty)
186182

187183
-- | Acts as `Test.QuickCheck.counterexample` if the postcondition fails.
188-
counterexamplePost :: Monad m => String -> PostconditionM m ()
184+
counterexamplePost :: String -> PostconditionM ()
189185
counterexamplePost c = PostconditionM $ tell (mempty, Endo $ counterexample c)
190186

191187
-- | The result required of `perform` depending on the `Error` type.
@@ -230,14 +226,14 @@ class (forall a. Show (Action state a), Show (Error state m), Monad m) => RunMod
230226
-- | Postcondition on the `a` value produced at some step.
231227
-- The result is `assert`ed and will make the property fail should it be `False`. This is useful
232228
-- to check the implementation produces expected values.
233-
postcondition :: (state, state) -> Action state a -> LookUp -> a -> PostconditionM m Bool
229+
postcondition :: (state, state) -> Action state a -> LookUp -> a -> PostconditionM Bool
234230
postcondition _ _ _ _ = pure True
235231

236232
-- | Postcondition on the result of running a _negative_ `Action`.
237233
-- The result is `assert`ed and will make the property fail should it be `False`. This is useful
238234
-- to check the implementation produces e.g. the expected errors or to check that the SUT hasn't
239235
-- been updated during the execution of the negative action.
240-
postconditionOnFailure :: (state, state) -> Action state a -> LookUp -> Either (Error state m) a -> PostconditionM m Bool
236+
postconditionOnFailure :: (state, state) -> Action state a -> LookUp -> Either (Error state m) a -> PostconditionM Bool
241237
postconditionOnFailure _ _ _ _ = pure True
242238

243239
-- | Allows the user to attach additional information to the `Property` at each step of the process.
@@ -624,7 +620,7 @@ runSteps s env ((v := act) : as) = do
624620
positiveActionSucceeded ret val = do
625621
(s', env', stateTransition) <- computeNewState ret
626622
evaluatePostCondition $
627-
postcondition
623+
postcondition @state @m
628624
stateTransition
629625
action
630626
(lookUpVar env)
@@ -634,7 +630,7 @@ runSteps s env ((v := act) : as) = do
634630
negativeActionResult ret = do
635631
(s', env', stateTransition) <- computeNewState ret
636632
evaluatePostCondition $
637-
postconditionOnFailure
633+
postconditionOnFailure @state @m
638634
stateTransition
639635
action
640636
(lookUpVar env)

quickcheck-dynamic/test/Spec/DynamicLogic/Counters.hs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ instance RunModelPar Counter (ReaderT (IORef Int) IO) where
116116
ref <- ask
117117
lift $ atomicModifyIORef ref (\ c -> (0, c))
118118

119-
postconditionPar (Counter n, _) Reset _ res = pure $ n == res
120-
postconditionPar _ _ _ _ = pure True
121-
122119
prop_counter_par :: ParallelActions Counter -> Property
123120
prop_counter_par as = always 10 $ monadicIO $ do
124121
ref <- lift $ newIORef (0 :: Int)

quickcheck-dynamic/test/Spec/DynamicLogic/RegistryModel.hs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -166,18 +166,7 @@ instance GoodMonad m => RunModel (RegState m) (RegM m) where
166166
counterexample (show res ++ " <- " ++ show act ++ "\n -- State: " ++ show s')
167167
. tabulate "Registry size" [show $ Map.size (regs s')]
168168

169-
instance GoodMonad m => RunModelPar (RegState m) (RegM m) where
170-
postconditionPar (s, _) (WhereIs name) env mtid =
171-
return $ (env <$> Map.lookup name (regs s)) == mtid
172-
postconditionPar _ _ _ _ = return True
173-
174-
postconditionOnFailurePar (s, _) act@Register{} _ res = do
175-
monitorPost $
176-
tabulate
177-
"Reason for -Register"
178-
[why s act]
179-
pure $ isLeft res
180-
postconditionOnFailurePar _ _ _ _ = pure True
169+
instance GoodMonad m => RunModelPar (RegState m) (RegM m)
181170

182171
data ShowDict a where
183172
ShowDict :: Show a => ShowDict a

0 commit comments

Comments
 (0)