ki-0.1.0: test/unit-tests/TestUtils.hs
{-# LANGUAGE TypeApplications #-}
module TestUtils
( fail,
shouldReturn,
shouldReturnSuchThat,
shouldThrow,
shouldThrowSuchThat,
test,
)
where
import Control.Exception
import Control.Monad (unless)
import Data.Either (isRight)
import qualified Ki.Implicit as Ki
import System.Exit (exitFailure)
import Text.Printf (printf)
import Prelude hiding (fail)
newtype TestFailure
= TestFailure String
deriving stock (Show)
instance Exception TestFailure where
displayException (TestFailure message) =
message
fail :: String -> IO ()
fail =
throwIO . TestFailure
shouldReturn :: (Eq a, Show a) => IO a -> a -> IO ()
shouldReturn action expected = do
actual <- action
unless (actual == expected) (fail ("expected " ++ show expected ++ ", got " ++ show actual))
shouldReturnSuchThat :: Show a => IO a -> (a -> Bool) -> IO ()
shouldReturnSuchThat action predicate = do
result <- action
unless (predicate result) (fail ("result " ++ show result ++ " did not pass predicate"))
shouldThrow :: (Show a, Eq e, Exception e) => IO a -> e -> IO ()
shouldThrow action expected =
try @SomeException action >>= \case
Left exception | fromException exception == Just expected -> pure ()
Left exception ->
fail ("expected exception " ++ displayException expected ++ ", got exception " ++ displayException exception)
Right value -> fail ("expected exception " ++ displayException expected ++ ", got " ++ show value)
shouldThrowSuchThat :: (Show a, Exception e) => IO a -> (e -> Bool) -> IO ()
shouldThrowSuchThat action predicate =
try @SomeException action >>= \case
Left exception ->
case fromException exception of
Nothing ->
fail ("expected exception, got exception " ++ displayException exception)
Just exception' ->
unless
(predicate exception')
(fail ("exception " ++ displayException exception' ++ " did not pass predicate"))
Right value -> fail ("expected exception, got " ++ show value)
test :: String -> (Ki.Context => IO ()) -> IO ()
test name action = do
result <- try @SomeException (Ki.withGlobalContext action)
printf "[%s] %s\n" (if isRight result then "x" else " ") name
case result of
Left exception -> do
putStrLn (displayException exception)
exitFailure
Right () -> pure ()