packages feed

kazura-queue-0.1.0.3: 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)