polysemy-managed-0.1.0.0: test/Polysemy/ManagedSpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Polysemy.ManagedSpec (spec) where
import Control.Concurrent.MVar (MVar)
import Control.Concurrent.MVar qualified as IO
import Control.Monad (forM_, void)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Resource qualified as MTR
import HaskellWorks.Hspec.Hedgehog qualified as H
import Hedgehog ((===), PropertyT)
import Polysemy (Final, Sem)
import Polysemy qualified as PY
import Polysemy.Embed (Embed)
import Polysemy.Managed qualified as PY
import Polysemy.Resource (Resource)
import Polysemy.Resource qualified as PY
import Test.Hspec (describe, it, Spec)
{- HLINT ignore "Redundant do" -}
runMainEffects :: forall a. ()
=> Sem '[Embed IO , Resource , Final IO] a
-> IO a
runMainEffects =
PY.runFinal
. PY.resourceToIOFinal
. PY.embedToFinal
run :: MVar [PropertyT IO ()] -> PropertyT IO () -> IO ()
run mv p = do
ps <- IO.takeMVar mv
IO.putMVar mv (p:ps)
spec :: Spec
spec = describe "Polysemy.ManagedSpec" $ do
it "De-allocated allocated resource (embed)" $ H.requireTest $ do
mva <- liftIO IO.newEmptyMVar
result1 <- liftIO $ runMainEffects $
PY.runManaged $ do
void $ MTR.allocate (return ()) $ const (IO.putMVar mva ())
liftIO $ IO.tryTakeMVar mva
result2 <- liftIO $ IO.tryTakeMVar mva
result1 === Nothing
result2 === Just ()
it "De-allocated allocated resource (final)" $ H.requireTest $ do
mva <- liftIO IO.newEmptyMVar
result1 <- liftIO $ runMainEffects $
PY.runManagedFinal $ do
void $ MTR.allocate (return ()) $ const (IO.putMVar mva ())
liftIO $ IO.tryTakeMVar mva
result2 <- liftIO $ IO.tryTakeMVar mva
result1 === Nothing
result2 === Just ()
it "Has local capability (embed)" $ H.requireTest $ do
mAssertions <- liftIO $ IO.newMVar []
mva <- liftIO IO.newEmptyMVar
mvb <- liftIO IO.newEmptyMVar
liftIO $ runMainEffects $ do
PY.runManaged $ do
void $ MTR.allocate (return ()) $ const (IO.putMVar mva ())
PY.managedLocal $ do
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Nothing
void $ MTR.allocate (return ()) $ const $ IO.putMVar mvb ()
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Just ()
assertions <- fmap reverse . liftIO $ IO.readMVar mAssertions
forM_ assertions id
it "Has local capability (final)" $ H.requireTest $ do
mAssertions <- liftIO $ IO.newMVar []
mva <- liftIO IO.newEmptyMVar
mvb <- liftIO IO.newEmptyMVar
liftIO $ runMainEffects $ do
PY.runManagedFinal $ do
void $ MTR.allocate (return ()) $ const (IO.putMVar mva ())
PY.managedLocal $ do
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Nothing
void $ MTR.allocate (return ()) $ const $ IO.putMVar mvb ()
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Nothing
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mva >>= \result -> run mAssertions $ result === Just ()
liftIO $ IO.tryReadMVar mvb >>= \result -> run mAssertions $ result === Just ()
assertions <- fmap reverse . liftIO $ IO.readMVar mAssertions
forM_ assertions id