Skip to content

Commit

Permalink
Show callstack HUnit failures, not only source loc
Browse files Browse the repository at this point in the history
  • Loading branch information
smatting committed Sep 16, 2022
1 parent df7ccab commit 3934275
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 15 deletions.
2 changes: 1 addition & 1 deletion hunit/Test/Tasty/HUnit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@ instance IsTest TestCase where
return $
case hunitResult of
Right info -> testPassed info
Left (HUnitFailure mbloc message) -> testFailed $ prependLocation mbloc message
Left (HUnitFailure cs message) -> testFailed $ prependCallStack cs message

testOptions = return []
40 changes: 27 additions & 13 deletions hunit/Test/Tasty/HUnit/Orig.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, TypeSynonymInstances #-}
{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, TypeSynonymInstances, RecordWildCards #-}

-- required for HasCallStack by different versions of GHC
{-# LANGUAGE ConstraintKinds, FlexibleContexts #-}
Expand All @@ -11,6 +11,7 @@ import qualified Control.Exception as E
import Control.Monad
import Data.Typeable (Typeable)
import Data.CallStack
import Data.List

-- Interfaces
-- ----------
Expand Down Expand Up @@ -38,12 +39,7 @@ assertFailure
:: HasCallStack
=> String -- ^ A message that is displayed with the assertion failure
-> IO a
assertFailure msg = E.throwIO (HUnitFailure location msg)
where
location :: Maybe SrcLoc
location = case reverse callStack of
(_, loc) : _ -> Just loc
[] -> Nothing
assertFailure msg = E.throwIO (HUnitFailure callStack msg)

-- Conditional Assertion Functions
-- -------------------------------
Expand Down Expand Up @@ -133,15 +129,33 @@ instance (AssertionPredicable t) => AssertionPredicable (IO t)


-- | Exception thrown by 'assertFailure' etc.
data HUnitFailure = HUnitFailure (Maybe SrcLoc) String
data HUnitFailure = HUnitFailure CallStack String
deriving (Eq, Show, Typeable)
instance E.Exception HUnitFailure

prependLocation :: Maybe SrcLoc -> String -> String
prependLocation mbloc s =
case mbloc of
Nothing -> s
Just loc -> srcLocFile loc ++ ":" ++ show (srcLocStartLine loc) ++ ":\n" ++ s
prependCallStack :: CallStack -> String -> String
prependCallStack cs s =
"Error message: " <> s <> "\n\n" <> prettyCallStack cs

prettyCallStack :: CallStack -> String
prettyCallStack = intercalate "\n" . prettyCallStackLines

prettyCallStackLines :: CallStack -> [String]
prettyCallStackLines cs = case cs of
[] -> []
stk -> "CallStack (from HasCallStack):"
: map ((" " ++) . prettyCallSite) stk
where
prettyCallSite (f, loc) = f ++ ", called at " ++ prettySrcLoc loc

prettySrcLoc :: SrcLoc -> String
prettySrcLoc SrcLoc {..}
= foldr (++) ""
[ srcLocFile, ":"
, show srcLocStartLine, ":"
, show srcLocStartCol, " in "
, srcLocPackage, ":", srcLocModule
]

----------------------------------------------------------------------
-- DEPRECATED CODE
Expand Down
2 changes: 1 addition & 1 deletion hunit/Test/Tasty/HUnit/Steps.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ instance IsTest TestCaseSteps where
atomicModifyIORef ref (\l -> ((tme,msg):l, ()))

hunitResult <- (Right <$> assertionFn stepFn) `catches`
[ Handler (\(HUnitFailure mbloc errMsg) -> return $ Left (prependLocation mbloc errMsg))
[ Handler (\(HUnitFailure cs errMsg) -> return $ Left (prependCallStack cs errMsg))
, Handler (\(SomeException ex) -> return $ Left (show ex))
]

Expand Down

0 comments on commit 3934275

Please sign in to comment.