{-# OPTIONS_GHC -Werror #-}
module Utils where
import Control.Exception (ErrorCall, catch)
import Control.Monad
import GHC.IO.Handle
import System.IO
import System.Directory
import Test.HUnit hiding (State)
-- | capture stdout
-- [[https://stackoverflow.com/a/9664017][source]]
catchOutput :: IO a -> IO (a, String)
catchOutput f = do
tmpd <- getTemporaryDirectory
(tmpf, tmph) <- openTempFile tmpd "haskell_stdout"
stdout_dup <- hDuplicate stdout
hDuplicateTo tmph stdout
hClose tmph
fVal <- f
hDuplicateTo stdout_dup stdout
str <- readFile tmpf
removeFile tmpf
return (fVal, str)
showLn :: Show a => a -> String
showLn x = unlines $ [show x]
showLines :: Show a => [a] -> String
showLines xs = unlines $ map show xs
withError :: a -> ErrorCall -> a
withError a _ = a
assertUndefined :: a -> Assertion
assertUndefined a = catch (seq a $ assertFailure "") (withError $ return ())
assertNoUndefined :: a -> Assertion
assertNoUndefined a = catch (seq a $ return ()) (withError $ assertFailure "")
allEqual :: Eq a => [a] -> Bool
allEqual = all (uncurry (==)) . pairs
where
pairs l = zip l $ tail l
safeLast :: [a] -> Maybe a
safeLast [] = Nothing
safeLast l = Just $ last l
add :: Monad m => m Int -> m Int -> m Int
add = liftM2 (+)