module Test.Hspec.Runner (
Specs, hspec, hspecX, hspecB, hHspec, hHspecWithFormat, describe, it, toExitCode
) where
import Test.Hspec.Core
import Test.Hspec.Formatters
import Test.Hspec.Formatters.Internal
import System.IO
import System.Exit
type Specs = [UnevaluatedSpec]
runFormatter :: Formatter -> Int -> String -> UnevaluatedSpec -> FormatM EvaluatedSpec
runFormatter formatter nesting _ (SpecGroup group xs) = do
exampleGroupStarted formatter (nesting) group
ys <- mapM (runFormatter formatter (succ nesting) group) xs
return (SpecGroup group ys)
runFormatter formatter nesting group (SpecExample requirement e) = do
result <- liftIO $ safeEvaluateExample e
case result of
Success -> do
increaseSuccessCount
exampleSucceeded formatter nesting requirement
Fail err -> do
increaseFailCount
exampleFailed formatter nesting requirement err
n <- getFailCount
addFailMessage $ failureDetails group requirement err n
Pending reason -> do
increasePendingCount
examplePending formatter nesting requirement reason
return (SpecExample requirement result)
failureDetails :: String -> String -> String -> Int -> String
failureDetails group requirement err i =
concat [ show i, ") ", group, " ", requirement, " FAILED", if null err then "" else "\n" ++ err ]
hspecX :: Specs -> IO a
hspecX ss = hspecB ss >>= exitWith . toExitCode
hspecB :: Specs -> IO Bool
hspecB ss = hspec ss >>= return . success
hspec :: Specs -> IO [EvaluatedSpec]
hspec ss = hHspec stdout ss
hHspec :: Handle -> Specs -> IO [EvaluatedSpec]
hHspec h specs = do
useColor <- hIsTerminalDevice h
hHspecWithFormat specdoc useColor h specs
hHspecWithFormat :: Formatter -> Bool -> Handle -> Specs -> IO [EvaluatedSpec]
hHspecWithFormat formatter useColor h ss = runFormatM useColor h $ do
specList <- mapM (runFormatter formatter 0 "") ss
failedFormatter formatter
footerFormatter formatter
return specList
toExitCode :: Bool -> ExitCode
toExitCode True = ExitSuccess
toExitCode False = ExitFailure 1