{-# LANGUAGE CPP #-} module Test.Chell.Output ( Output(..) , plainOutput , colorOutput ) where import Control.Monad (forM_, unless, when) import Data.Text (Text) import qualified Data.Text.IO #ifdef MIN_VERSION_ansi_terminal import qualified System.Console.ANSI as AnsiTerminal #endif import Test.Chell.Types data Output = Output { outputStart :: Test -> IO () , outputResult :: Test -> TestResult -> IO () } plainOutput :: Bool -> Output plainOutput v = Output { outputStart = plainOutputStart v , outputResult = plainOutputResult v } plainOutputStart :: Bool -> Test -> IO () plainOutputStart v t = when v $ do putStr "[ RUN ] " Data.Text.IO.putStrLn (testName t) plainOutputResult :: Bool -> Test -> TestResult -> IO () plainOutputResult v t (TestPassed _) = when v $ do putStr "[ PASS ] " Data.Text.IO.putStrLn (testName t) putStrLn "" plainOutputResult v t TestSkipped = when v $ do putStr "[ SKIP ] " Data.Text.IO.putStrLn (testName t) putStrLn "" plainOutputResult _ t (TestFailed notes fs) = do putStr "[ FAIL ] " Data.Text.IO.putStrLn (testName t) printNotes notes printFailures fs plainOutputResult _ t (TestAborted notes msg) = do putStr "[ ABORT ] " Data.Text.IO.putStrLn (testName t) printNotes notes putStr " " Data.Text.IO.putStr msg putStrLn "\n" colorOutput :: Bool -> Output #ifndef MIN_VERSION_ansi_terminal colorOutput = plainOutput #else colorOutput v = Output { outputStart = colorOutputStart v , outputResult = colorOutputResult v } colorOutputStart :: Bool -> Test -> IO () colorOutputStart v t = when v $ do putStr "[ RUN ] " Data.Text.IO.putStrLn (testName t) colorOutputResult :: Bool -> Test -> TestResult -> IO () colorOutputResult v t (TestPassed _) = when v $ do putStr "[ " AnsiTerminal.setSGR [ AnsiTerminal.SetColor AnsiTerminal.Foreground AnsiTerminal.Vivid AnsiTerminal.Green ] putStr "PASS" AnsiTerminal.setSGR [ AnsiTerminal.Reset ] putStr " ] " Data.Text.IO.putStrLn (testName t) putStrLn "" colorOutputResult v t TestSkipped = when v $ do putStr "[ " AnsiTerminal.setSGR [ AnsiTerminal.SetColor AnsiTerminal.Foreground AnsiTerminal.Vivid AnsiTerminal.Yellow ] putStr "SKIP" AnsiTerminal.setSGR [ AnsiTerminal.Reset ] putStr " ] " Data.Text.IO.putStrLn (testName t) putStrLn "" colorOutputResult _ t (TestFailed notes fs) = do putStr "[ " AnsiTerminal.setSGR [ AnsiTerminal.SetColor AnsiTerminal.Foreground AnsiTerminal.Vivid AnsiTerminal.Red ] putStr "FAIL" AnsiTerminal.setSGR [ AnsiTerminal.Reset ] putStr " ] " Data.Text.IO.putStrLn (testName t) printNotes notes printFailures fs colorOutputResult _ t (TestAborted notes msg) = do putStr "[ " AnsiTerminal.setSGR [ AnsiTerminal.SetColor AnsiTerminal.Foreground AnsiTerminal.Vivid AnsiTerminal.Red ] putStr "ABORT" AnsiTerminal.setSGR [ AnsiTerminal.Reset ] putStr " ] " Data.Text.IO.putStrLn (testName t) printNotes notes putStr " " Data.Text.IO.putStr msg putStrLn "\n" #endif printNotes :: [(Text, Text)] -> IO () printNotes notes = unless (null notes) $ do forM_ notes $ \(key, value) -> do putStr " note: " Data.Text.IO.putStr key putStr "=" Data.Text.IO.putStrLn value putStrLn "" printFailures :: [Failure] -> IO () printFailures fs = forM_ fs $ \(Failure loc msg) -> do putStr " " case loc of Just loc' -> do Data.Text.IO.putStr (locationFile loc') putStr ":" putStrLn (show (locationLine loc')) Nothing -> return () putStr " " Data.Text.IO.putStr msg putStrLn "\n"