module Test.HUnit.Lang
(
Assertion,
assertFailure,
performTestCase
)
where
#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
import Data.Dynamic
import Control.Exception as E
#else
import Data.List (isPrefixOf)
import System.IO.Error (ioeGetErrorString, try)
#endif
import Control.DeepSeq
type Assertion = IO ()
assertFailure :: String
-> Assertion
performTestCase :: Assertion
-> IO (Maybe (Bool, String))
#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
data HUnitFailure = HUnitFailure String
deriving Show
hunitFailureTc :: TyCon
hunitFailureTc = mkTyCon "HUnitFailure"
instance Typeable HUnitFailure where
typeOf _ = mkTyConApp hunitFailureTc []
#ifdef BASE4
instance Exception HUnitFailure
assertFailure msg = msg `deepseq` E.throwIO (HUnitFailure msg)
performTestCase action =
do action
return Nothing
`E.catches`
[E.Handler (\(HUnitFailure msg) -> return $ Just (True, msg)),
E.Handler (\e -> throw (e :: E.AsyncException)),
E.Handler (\e -> return $ Just (False, show (e :: E.SomeException)))]
#else
assertFailure msg = msg `deepseq` E.throwDyn (HUnitFailure msg)
performTestCase action =
do r <- E.try action
case r of
Right () -> return Nothing
Left e@(E.DynException dyn) ->
case fromDynamic dyn of
Just (HUnitFailure msg) -> return $ Just (True, msg)
Nothing -> return $ Just (False, show e)
Left e -> return $ Just (False, show e)
#endif
#else
hunitPrefix = "HUnit:"
nhc98Prefix = "I/O error (user-defined), call to function `userError':\n "
assertFailure msg = msg `deepseq` ioError (userError (hunitPrefix ++ msg))
performTestCase action = do r <- try action
case r of Right () -> return Nothing
Left e -> return (Just (decode e))
where
decode e = let s0 = ioeGetErrorString e
(_, s1) = dropPrefix nhc98Prefix s0
in dropPrefix hunitPrefix s1
dropPrefix pref str = if pref `isPrefixOf` str
then (True, drop (length pref) str)
else (False, str)
#endif