io-classes-1.10.1.0: test/Test/Control/Concurrent/Class/MonadMVar/Strict/WHNF.hs
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
-- | Test whether functions on 'StrictMVar's correctly force values to WHNF
-- before they are put inside the 'StrictMVar'.
module Test.Control.Concurrent.Class.MonadMVar.Strict.WHNF
( prop_newMVar
, prop_putMVar
, prop_swapMVar
, prop_tryPutMVar
, prop_modifyMVar_
, prop_modifyMVar
, prop_modifyMVarMasked_
, prop_modifyMVarMasked
, (.:)
) where
import Control.Concurrent.Class.MonadMVar.Strict
import Control.Monad (void)
import Data.Typeable (Typeable)
import NoThunks.Class (OnlyCheckWhnf (OnlyCheckWhnf), unsafeNoThunks)
import Test.QuickCheck
import Test.QuickCheck.Monadic (PropertyM, monitor, run)
{-------------------------------------------------------------------------------
Utilities
-------------------------------------------------------------------------------}
infixr 9 .:
(.:) :: (y -> z) -> (x0 -> x1 -> y) -> (x0 -> x1 -> z)
(.:) g f x0 x1 = g (f x0 x1)
isInWHNF :: (MonadMVar m, Typeable a) => StrictMVar m a -> PropertyM m Bool
isInWHNF v = do
x <- run $ readMVar v
case unsafeNoThunks (OnlyCheckWhnf x) of
Nothing -> pure True
Just tinfo -> monitor (counterexample $ "Not in WHNF: " ++ show tinfo)
>> pure False
{-------------------------------------------------------------------------------
Properties
-------------------------------------------------------------------------------}
prop_newMVar ::
MonadMVar m
=> Int
-> Fun Int Int
-> PropertyM m Bool
prop_newMVar x f = do
v <- run $ newMVar (applyFun f x)
isInWHNF v
prop_putMVar ::
MonadMVar m
=> Int
-> Fun Int Int
-> PropertyM m Bool
prop_putMVar x f = do
v <- run newEmptyMVar
run $ putMVar v (applyFun f x)
isInWHNF v
prop_swapMVar ::
MonadMVar m
=> Int
-> Fun Int Int
-> PropertyM m Bool
prop_swapMVar x f = do
v <- run $ newMVar x
void $ run $ swapMVar v (applyFun f x)
isInWHNF v
prop_tryPutMVar ::
MonadMVar m
=> Int
-> Fun Int Int
-> PropertyM m Bool
prop_tryPutMVar x f = do
v <- run newEmptyMVar
b <- run $ tryPutMVar v (applyFun f x)
b' <- isInWHNF v
pure (b && b')
prop_modifyMVar_ ::
MonadMVar m
=> Int
-> Fun Int Int
-> PropertyM m Bool
prop_modifyMVar_ x f =do
v <- run $ newMVar x
run $ modifyMVar_ v (pure . applyFun f)
isInWHNF v
prop_modifyMVar ::
MonadMVar m
=> Int
-> Fun Int (Int, Char)
-> PropertyM m Bool
prop_modifyMVar x f =do
v <- run $ newMVar x
void $ run $ modifyMVar v (pure . applyFun f)
isInWHNF v
prop_modifyMVarMasked_ ::
MonadMVar m
=> Int
-> Fun Int Int
-> PropertyM m Bool
prop_modifyMVarMasked_ x f =do
v <- run $ newMVar x
void $ run $ modifyMVarMasked_ v (pure . applyFun f)
isInWHNF v
prop_modifyMVarMasked ::
MonadMVar m
=> Int
-> Fun Int (Int, Char)
-> PropertyM m Bool
prop_modifyMVarMasked x f =do
v <- run $ newMVar x
void $ run $ modifyMVarMasked v (pure . applyFun f)
isInWHNF v