packages feed

festung-0.9.1.1: tests/Festung/Concurrency/UtilsSpec.hs

module Festung.Concurrency.UtilsSpec (spec) where

import Test.Hspec

import Control.Concurrent
import Control.Applicative
import Festung.Concurrency.Utils


oneSecond :: Int
oneSecond = 1 * 1000 * 1000


spec :: Spec
spec = do
    describe "copyMVar" $ do
        it "Copies content without taking it" $ do
            src <- newMVar ()
            dst <- newEmptyMVar
            copyMVar id src dst
            tryReadMVar src `shouldReturn` Just ()
            tryReadMVar dst `shouldReturn` Just ()

    describe "readAnyMVar" $ do
        let getMVars = pure (,) <*> newMVar 1 <*> (newEmptyMVar :: IO (MVar ()))

        it "Reads non-empty mvar" $ do
            (value, empty) <- getMVars
            readAnyMVar value empty `shouldReturn` Left 1
            readAnyMVar empty value `shouldReturn` Right 1

        it "Doesn't take the non-empty mvar" $ do
            (value, empty) <- getMVars
            readAnyMVar value empty `shouldReturn` Left 1
            tryReadMVar value       `shouldReturn` Just 1

    describe "readMVarTimeout" $ do
        it "Reads a filled mvar" $ do
            filled <- newMVar ()
            readMVarTimeout oneSecond filled `shouldReturn` Just ()

        it "Times out" $ do
            empty <- newEmptyMVar :: IO (MVar ())
            readMVarTimeout 0 empty `shouldReturn` Nothing

    describe "readChanTimeout" $ do
        it "Reads a Chan with data" $ do
            chan <- newChan
            writeChan chan ()
            readChanTimeout oneSecond chan `shouldReturn` Just ()

        it "Times out" $ do
            chan <- newChan :: IO (Chan ())
            readChanTimeout 0 chan `shouldReturn` Nothing