bugsnag-haskell-0.0.1.1: test/Network/BugsnagSpec.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Network.BugsnagSpec
( spec
) where
import Test.Hspec
import Control.Exception
import Network.Bugsnag
brokenFunctionIO :: IO a
brokenFunctionIO = throw $ bugsnagException
"IOException" "Something exploded" [$(currentStackFrame) "brokenFunctionIO"]
brokenFunction :: HasCallStack => a
brokenFunction = sillyHead [] `seq` undefined
sillyHead :: HasCallStack => [a] -> a
sillyHead (x:_) = x
sillyHead _ = error "empty list"
spec :: Spec
spec = do
describe "BugsnagException" $ do
it "can be thrown and caught" $ do
ex <- brokenFunctionIO `catch` pure
beErrorClass ex `shouldBe` "IOException"
beMessage ex `shouldBe` Just "Something exploded"
beStacktrace ex `shouldSatisfy` (not . null)
let frame = head $ beStacktrace ex
bsfFile frame `shouldBe` "test/Network/BugsnagSpec.hs"
bsfLineNumber frame `shouldBe` 16
bsfColumnNumber frame `shouldBe` Just 43
bsfMethod frame `shouldBe` "brokenFunctionIO"
bsfInProject frame `shouldBe` Just True
describe "bugsnagExceptionFromSomeException" $ do
it "can parse errors with callstacks" $ do
e <- evaluate brokenFunction `catch` pure
let ex = bugsnagExceptionFromSomeException e
beErrorClass ex `shouldBe` "ErrorCall"
beMessage ex `shouldBe` Just "empty list"
beStacktrace ex `shouldSatisfy` ((== 3) . length)
let frame = head $ beStacktrace ex
bsfFile frame `shouldBe` "test/Network/BugsnagSpec.hs"
bsfLineNumber frame `shouldBe` 23
bsfColumnNumber frame `shouldBe` Just 15
bsfMethod frame `shouldBe` "error"
map bsfMethod (beStacktrace ex)
`shouldBe` ["error", "sillyHead", "brokenFunction"]