timemap-0.0.1: test/Data/TimeMapSpec.hs
{-# LANGUAGE
GeneralizedNewtypeDeriving
#-}
module Data.TimeMapSpec (spec) where
import Data.TimeMap (TimeMap)
import qualified Data.TimeMap as TM
import Data.Maybe (isJust, isNothing)
import Test.Tasty
import Test.Tasty.QuickCheck as QC
import Test.QuickCheck
import Test.QuickCheck.Instances
import Control.Concurrent.STM
import Control.Concurrent (threadDelay)
spec :: TestTree
spec = testGroup "Data.TimeMap"
[ QC.testProperty "lookups should always succeed after insertion"
lookupInsertExists
, QC.testProperty "lookups should always fail after deletion"
lookupDeleteNotExists
, QC.testProperty "lookups should always fail after waiting past the time"
lookupAgoNotExists
, QC.testProperty "lookups should always succeed after waiting before the time"
lookupAgoExists
]
type Key = Integer
type Content = Integer
newtype BuiltTimeMap = BuiltTimeMap
{ getBuiltTimeMap :: [(Key, Content)]
} deriving (Show, Arbitrary)
buildTimeMap :: BuiltTimeMap -> IO (TimeMap Key Content)
buildTimeMap xs = do
x <- atomically $ TM.newTimeMap
mapM_ (\(k,v) -> TM.insert k v x) $ getBuiltTimeMap xs
return x
lookupInsertExists :: Key -> Content -> BuiltTimeMap -> Property
lookupInsertExists k v xs = ioProperty $ do
x <- buildTimeMap xs
TM.insert k v x
isJust <$> atomically (TM.lookup k x)
lookupDeleteNotExists :: Key -> BuiltTimeMap -> Property
lookupDeleteNotExists k xs = ioProperty $ do
x <- buildTimeMap xs
atomically (TM.delete k x)
isNothing <$> atomically (TM.lookup k x)
lookupAgoNotExists :: Key -> Content -> BuiltTimeMap -> Property
lookupAgoNotExists k v xs = ioProperty $ do
x <- buildTimeMap xs
TM.insert k v x
threadDelay 1000000
TM.filterFromNow 1 x
isNothing <$> atomically (TM.lookup k x)
lookupAgoExists :: Key -> Content -> BuiltTimeMap -> Property
lookupAgoExists k v xs = ioProperty $ do
x <- buildTimeMap xs
TM.insert k v x
threadDelay 500000
TM.filterFromNow 1 x
isJust <$> atomically (TM.lookup k x)