packages feed

kazura-queue-0.1.0.0: test/Test/WVar.hs

module Test.WVar where

import qualified Test.Hspec      as HS
import qualified Test.QuickCheck as Q

import qualified Control.Concurrent.WVar as WV

import qualified Control.Monad as M

withLatestCache ::
    (IO (v, v, WV.WVar v, WV.WCached v) -> r) -> IO (v, WV.WVar v) -> r
withLatestCache f prepare = f prepare'
    where
        prepare' = do
            (val, wv) <- prepare
            wc        <- WV.cacheWVar wv
            return (val, val, wv, wc)

whenWVarIsFresh ::
    (IO (Int, WV.WVar Int) -> HS.Spec) -> HS.Spec
whenWVarIsFresh f = HS.describe "when WVar is fresh" $ f prepare
    where
        prepare = do
            val <- Q.generate Q.arbitrary
            wv  <- WV.newWVar val
            return (val, wv)

whenWVarIsUpdating :: Q.Arbitrary v =>
    (IO (v, WV.WVar v) -> HS.Spec) -> HS.Spec
whenWVarIsUpdating f = HS.describe "when WVar is updating" $ f prepare
    where
        prepare = do
            val <- Q.generate Q.arbitrary
            wv  <- WV.newWVar val
            M.void $ WV.takeWVar wv
            return (val, wv)

whenWVarIsFreshButCacheStaled :: (Eq v, Q.Arbitrary v) =>
    (IO (v, v, WV.WVar v, WV.WCached v) -> HS.Spec) -> HS.Spec
whenWVarIsFreshButCacheStaled f =
    HS.describe "when WVar is fresh but cache staled" $ f prepare
    where
        prepare = do
            val1 <- Q.generate Q.arbitrary
            val2 <- Q.generate $ Q.arbitrary `Q.suchThat` (/= val1)
            wv   <- WV.newWVar val1
            wc   <- WV.cacheWVar wv
            WV.putWVar wv val2
            return (val1, val2, wv, wc)

whenWVarIsUpdatingAndCacheStaled :: (Eq v, Q.Arbitrary v) =>
    (IO (v, v, WV.WVar v, WV.WCached v) -> HS.Spec) -> HS.Spec
whenWVarIsUpdatingAndCacheStaled f =
    HS.describe "when WVar is updating and cache staled" $ f prepare
    where
        prepare = do
            val <- Q.generate Q.arbitrary
            wv  <- WV.newWVar val
            wc  <- WV.cacheWVar wv
            M.void $ WV.takeWVar wv
            return (val, val, wv, wc)