{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Prelude hiding (catch)
import Control.Monad.Exception
import Control.Monad.Trans.Error
import Control.Monad.IO.Class
import Data.IORef
import System.Exit (exitFailure, exitSuccess)
import Test.HUnit
main :: IO ()
main = do
count <- runTestTT tests
case failures count of
0 -> exitSuccess
_ -> exitFailure
tests :: Test
tests = TestList [mkTest (conl ++ " " ++ whatl) con what | (conl, con) <- cons, (whatl, what) <- whats]
where
whats :: [(String, ErrorT String IO ())]
whats = [("return", return ()),
("error", error "error"),
("throwError", throwError "throwError")]
cons :: [(String, ErrorT String IO () -> ErrorT String IO () -> ErrorT String IO ())]
cons = [("finally", \what sequel -> what `finally` sequel),
("bracket_", \what sequel -> bracket_ (return ()) sequel what)]
mkTest :: String
-> (ErrorT String IO () -> ErrorT String IO () -> ErrorT String IO ())
-> ErrorT String IO ()
-> Test
mkTest label con what =
label ~: tst
where
tst = do
ref <- newIORef "sequel not called"
let sequel = liftIO $ writeIORef ref expected
_ <- runErrorT (con what sequel) `catch` \(e :: SomeException) -> return (Left (show e))
actual <- readIORef ref
return $ assertEqual "" expected actual
expected :: String
expected = "sequel called"