packages feed

sydtest-0.0.0.0: test/Test/Syd/AroundSpec.hs

module Test.Syd.AroundSpec (spec) where

import Control.Concurrent.STM
import Control.Monad.IO.Class
import Test.Syd

spec :: Spec
spec = sequential $
  doNotRandomiseExecutionOrder $ do
    describe "before" $ do
      var <- liftIO $ newTVarIO (1 :: Int)
      let readAndIncrement = atomically $ stateTVar var $ \i -> (i + 1, i + 1)
      before readAndIncrement $ do
        it "reads 2" $ \i ->
          i `shouldBe` 2
        it "reads 4" $ \i ->
          i `shouldBe` 3
        it "reads 6" $ \i ->
          i `shouldBe` 4

    describe "before_" $ do
      var <- liftIO $ newTVarIO (1 :: Int)
      let increment = atomically $ modifyTVar var succ
      before_ increment $ do
        it "reads 2" $ do
          i <- readTVarIO var
          i `shouldBe` 2
        it "reads 4" $ do
          i <- readTVarIO var
          i `shouldBe` 3
        it "reads 6" $ do
          i <- readTVarIO var
          i `shouldBe` 4

    describe "after" $ do
      var <- liftIO $ newTVarIO (0 :: Int)
      let increment = atomically $ modifyTVar var succ
      after (\() -> increment) $ do
        it "reads 0" $ do
          i <- readTVarIO var
          i `shouldBe` 0
        it "reads 2" $ do
          i <- readTVarIO var
          i `shouldBe` 1
        it "reads 4" $ do
          i <- readTVarIO var
          i `shouldBe` 2

    describe "after_" $ do
      var <- liftIO $ newTVarIO (0 :: Int)
      let increment = atomically $ modifyTVar var succ
      after_ increment $ do
        it "reads 0" $ do
          i <- readTVarIO var
          i `shouldBe` 0
        it "reads 2" $ do
          i <- readTVarIO var
          i `shouldBe` 1
        it "reads 4" $ do
          i <- readTVarIO var
          i `shouldBe` 2

    describe "around" $ do
      var <- liftIO $ newTVarIO (1 :: Int)
      let increment = atomically $ modifyTVar var succ
          readAndIncrement = atomically $ stateTVar var $ \i -> (i + 1, i + 1)
          aroundFunc :: (Int -> IO ()) -> IO ()
          aroundFunc intFunc = do
            i <- readAndIncrement
            intFunc i
            increment
      around aroundFunc $ do
        it "reads 2" $ \i ->
          i `shouldBe` 2
        it "reads 4" $ \i ->
          i `shouldBe` 4
        it "reads 6" $ \i ->
          i `shouldBe` 6

    describe "around_" $ do
      var <- liftIO $ newTVarIO (1 :: Int)
      let increment = atomically $ modifyTVar var succ
          aroundFunc_ :: IO () -> IO ()
          aroundFunc_ func = do
            increment
            func
            increment
      around_ aroundFunc_ $ do
        it "reads 2" $ do
          i <- readTVarIO var
          i `shouldBe` 2
        it "reads 4" $ do
          i <- readTVarIO var
          i `shouldBe` 4
        it "reads 6" $ do
          i <- readTVarIO var
          i `shouldBe` 6

    describe "aroundWith" $ do
      var <- liftIO $ newTVarIO (1 :: Int)
      let increment = atomically $ modifyTVar var succ
          readAndIncrement = atomically $ stateTVar var $ \i -> (i + 1, i + 1)
          aroundWithFunc :: (Int -> IO ()) -> () -> IO ()
          aroundWithFunc intFunc () = do
            i <- readAndIncrement
            intFunc i
            increment
      aroundWith aroundWithFunc $ do
        it "reads 2" $ \i ->
          i `shouldBe` 2
        it "reads 4" $ \i ->
          i `shouldBe` 4
        it "reads 6" $ \i ->
          i `shouldBe` 6

    describe "aroundWith'" $ do
      var <- liftIO $ newTVarIO (1 :: Int)
      let increment = atomically $ modifyTVar var succ
          readAndIncrement = atomically $ stateTVar var $ \i -> (i + 1, i + 1)
          aroundWithFunc :: (() -> Int -> IO ()) -> () -> () -> IO ()
          aroundWithFunc intFunc () () = do
            i <- readAndIncrement
            intFunc () i
            increment
      aroundWith' aroundWithFunc $ do
        it "reads 2" $ \i ->
          i `shouldBe` 2
        it "reads 4" $ \i ->
          i `shouldBe` 4
        it "reads 6" $ \i ->
          i `shouldBe` 6