throwable-exceptions-0.1.0.3: test/Control/Exception/ThrowableTest.hs
module Control.Exception.ThrowableTest where
import Control.Exception.Safe (Exception)
import Control.Exception.Safe (MonadThrow, throwM, fromException, SomeException)
import Data.Either (isLeft)
import Test.Tasty (TestTree)
import Test.Tasty.HUnit (testCase, Assertion, assertBool, (@?=))
import qualified Control.Exception.Throwable as ET
-- The message is never used in tasty-hunit
assertBool' :: Bool -> Assertion
assertBool' = assertBool ""
canBeShown :: Exception e => e -> Assertion
canBeShown = assertBool' . not . null . show
canBeThrown :: Exception e => e -> Assertion
canBeThrown e = assertBool' . isLeft $ throwM e
test_io_exception_prim :: [TestTree]
test_io_exception_prim =
[ testCase "can be shown in most cases" $
canBeShown $ ET.ioException' "honoka-chan!" -- IOException' can be shown, because IOException' is an Exception instance
, testCase "can be thrown in all case" $
canBeThrown $ ET.ioException' "kotori-chan ga!" -- IOException' can be thrown by throwM, because IOException' is an Exception instance !
]
test_index_out_of_bounds_exception :: [TestTree]
test_index_out_of_bounds_exception =
[ testCase "finds the perpetrator with the clue" $
program -- You can find the perpetrator of some bug if you see the message ('.. looks like bad')
]
where
program :: IO ()
program = do
case someCalculation of
Right _ -> putStrLn "the calculation is succeed"
Left e -> case fromException' e of
Nothing -> putStrLn "!? I don't know !"
Just (ET.IndexOutOfBoundsException _ clue) -> putStrLn $ show clue ++ " looks like bad"
-- monomorphic function
fromException' :: SomeException -> Maybe (ET.IndexOutOfBoundsException ([Int], Int))
fromException' = fromException
at :: MonadThrow m => [Int] -> Int -> m Int
xs `at` i | length xs <= i = throwM $ ET.IndexOutOfBoundsException "mmm..?" (xs, i)
| otherwise = return $ xs !! i
someCalculation = [10..13] `at` 4
test_general_exception :: [TestTree]
test_general_exception =
[ testCase "looks like other exception when GeneralException is executed `show`" $
show (ET.generalException "MyTest" "nico-chan") @?= "MyTestException: nico-chan"
]