module FreeC.Monad.ReporterTests ( testReporter ) where
import System.IO.Error ( ioError, userError )
import Test.Hspec
import FreeC.IR.SrcSpan
import FreeC.Monad.Reporter
testReporter :: Spec
testReporter = describe "FreeC.Monad.Reporter" $ do
testRunReporter
testIsFatal
testMessages
testLiftIO
testRunReporter :: Spec
testRunReporter = describe "runReporter" $ do
it "returns 'Just' the produced value if no message was reported" $ do
runReporter (return testValue) `shouldBe` (Just testValue, [])
it "returns 'Just' the produced value if no fatal message was reported" $ do
runReporter (report testMessage1 >> return testValue)
`shouldBe` (Just testValue, [testMessage1])
it "returns 'Nothing' if a fatal message was reported" $ do
runReporter (reportFatal testMessage1)
`shouldBe` (Nothing :: Maybe (), [testMessage1])
testMessage1 :: Message
testMessage1 = Message NoSrcSpan Error "Keyboard not found\nPress F1 to Resume"
testMessage2 :: Message
testMessage2 = Message NoSrcSpan Error "Maximum call stack size exceeded!"
testValue :: Int
testValue = 42
testIsFatal :: Spec
testIsFatal = describe "isFatal" $ do
it "is not fatal to return from a reporter" $ do
isFatal (return testValue) `shouldBe` False
it "is not fatal to report a regular message" $ do
isFatal (report testMessage1) `shouldBe` False
it "is fatal to report a fatal message" $ do
isFatal (reportFatal testMessage1) `shouldBe` True
it "is fatal if a computation involves reporting a fatal message" $ do
isFatal (reportFatal testMessage1 >> return testValue) `shouldBe` True
testMessages :: Spec
testMessages = describe "messages" $ do
it "collects all reported messages" $ do
let reporter = report testMessage1 >> report testMessage1
length (messages reporter) `shouldBe` 2
it "collects all messages reported before a fatal message" $ do
let reporter = report testMessage1 >> reportFatal testMessage1
length (messages reporter) `shouldBe` 2
it "collects no messages reported after a fatal messages" $ do
let reporter = reportFatal testMessage1 >> report testMessage1
length (messages reporter) `shouldBe` 1
it "collects no messages in the right order" $ do
let reporter = report testMessage1 >> report testMessage2
messages reporter `shouldBe` [testMessage1, testMessage2]
testLiftIO :: Spec
testLiftIO = describe "liftIO reports IO errors" $ do
it "catches IO errors" $ do
reporter <- unhoist $ liftIO $ ioError (userError "catch me")
isFatal reporter `shouldBe` True
length (messages reporter) `shouldBe` 1
it "forwards result" $ do
reporter <- unhoist $ liftIO (return ())
isFatal reporter `shouldBe` False
length (messages reporter) `shouldBe` 0