polysemy-1.1.0.0: test/AsyncSpec.hs
{-# LANGUAGE NumDecimals #-}
module AsyncSpec where
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Monad
import Polysemy
import Polysemy.Async
import Polysemy.State
import Polysemy.Trace
import Test.Hspec
spec :: Spec
spec = describe "async" $ do
it "should thread state and not lock" $ do
(ts, (s, r)) <- runM
. runTraceList
. runState "hello"
. asyncToIO $ do
let message :: Member Trace r => Int -> String -> Sem r ()
message n msg = trace $ mconcat
[ show n, "> ", msg ]
~[lock1, lock2] <- embed $
replicateM 2 newEmptyMVar
a1 <- async $ do
v <- get @String
message 1 v
put $ reverse v
embed $ putMVar lock1 ()
embed $ takeMVar lock2
get >>= message 1
get @String
void $ async $ do
embed $ takeMVar lock1
get >>= message 2
put "pong"
embed $ putMVar lock2 ()
await a1 <* put "final"
ts `shouldContain` ["1> hello", "2> olleh", "1> pong"]
s `shouldBe` "final"
r `shouldBe` Just "pong"