tmapmvar-0.0.3: test/Spec.hs
{-# LANGUAGE
ScopedTypeVariables
, RankNTypes
#-}
module Main where
import Data.Map.Strict as Map
import Control.Monad (forM_)
import Control.Concurrent (threadDelay)
import Control.Concurrent.Async (async)
import Control.Concurrent.STM.TMapMVar as TMapMVar
import Control.Concurrent.STM.TVar (readTVar, newTVarIO, writeTVar, modifyTVar')
import Control.Concurrent.STM.TMVar (tryReadTMVar)
import Control.Concurrent.STM (atomically, STM)
import Test.Tasty (defaultMain, testGroup)
import Test.Tasty.QuickCheck (testProperty)
import Test.QuickCheck (Arbitrary (..), Property, ioProperty)
import System.IO.Unsafe (unsafePerformIO)
main :: IO ()
main =
defaultMain $ testGroup "Control.Concurrent.STM.TMapMVar"
[ testProperty "Insert in Empty" insertInEmpty
, testProperty "Insert in Full" insertInFull
, testProperty "Insert Force doesn't Block" insertForceDoesntBlock
, testProperty "Empty after Lookup" emptyAfterLookup
, testProperty "Observe doesn't Mutate" nonMutativeObserve
, testProperty "Lookup before Insert" lookupThenInsert
]
insertInEmpty :: Int -> Int -> Property
insertInEmpty k v = ioProperty $ do
var <- atomically newTMapMVar
TMapMVar.insert var k v
v' <- TMapMVar.observe var k
pure (v == v')
insertInFull :: Int -> Int -> Property
insertInFull k v = ioProperty $ do
var <- do
m <- atomically newTMapMVar
TMapMVar.insert m k (v-1)
pure m
async $ do
threadDelay 10
TMapMVar.delete var k
TMapMVar.insert var k v
v' <- TMapMVar.lookup var k
pure (v == v')
insertForceDoesntBlock :: Int -> Int -> Int -> Property
insertForceDoesntBlock k v1 v2 = ioProperty $ do
var <- atomically newTMapMVar
TMapMVar.insert var k v1
TMapMVar.insertForce var k v2
v' <- TMapMVar.lookup var k
pure (v' == v2)
emptyAfterLookup :: Int -> Int -> Property
emptyAfterLookup k v = ioProperty $ do
var <- atomically newTMapMVar
TMapMVar.insert var k v
_ <- TMapMVar.lookup var k
mV' <- TMapMVar.tryObserve var k
pure (mV' == Nothing)
nonMutativeObserve :: Int -> Int -> Property
nonMutativeObserve k v = ioProperty $ do
var <- atomically newTMapMVar
TMapMVar.insert var k v
v1 <- TMapMVar.observe var k
v2 <- TMapMVar.observe var k
pure (v1 == v2 && v2 == v)
lookupThenInsert :: Int -> Int -> Property
lookupThenInsert k v = ioProperty $ do
var <- atomically newTMapMVar
async $ do
threadDelay 10
TMapMVar.insert var k v
v' <- TMapMVar.lookup var k
pure (v' == v)