jupyter-0.9.0: tests/Jupyter/Test/Utils.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Jupyter.Test.Utils where
-- Imports from 'base'
import Control.Exception (catch, Exception)
-- Imports from 'tasty-hunit
import Test.Tasty.HUnit (assertFailure)
-- Imports from 'extra'
import System.IO.Extra (withTempDir)
import System.Directory.Extra (withCurrentDirectory)
-- Imports from 'zeromq4-haskell'
import System.ZMQ4.Monadic (socket, connect, ZMQ, Socket, SocketType)
-- Imports from 'jupyter'
import Jupyter.ZeroMQ (KernelProfile, Port)
-- | Create a temporary directory and execute an action with that temporary directory as the working
-- directory. This is not threadsafe, since working directories are global values.
inTempDir :: (FilePath -> IO a) -> IO a
inTempDir action = withTempDir $ \tmp -> withCurrentDirectory tmp (action tmp)
-- | Check that an IO action throws an exception of the expected type.
shouldThrow :: forall a proxy e. Exception e => IO a -> proxy e -> IO ()
shouldThrow action _ =
catch (action >> assertFailure "Did not throw expected exception") handler
where
handler :: e -> IO ()
handler _ = return ()
-- | Create and connect a socket to a port, obtained by applying an accessor to a 'KernelProfile'.
connectedSocket :: SocketType s
=> KernelProfile -- ^ Profile to get port from
-> (KernelProfile -> Port) -- ^ Accessor to get port from profile
-> s -- ^ Socket type to create, e.g. 'Rep'
-> ZMQ z (Socket z s) -- ^ Returns connected ZeroMQ socket
connectedSocket profile accessor socketType = do
sock <- socket socketType
connect sock $ "tcp://127.0.0.1:" ++ show (accessor profile)
return sock
-- | An exception type to be thrown during tests.
data HandlerException = HandlerException | HandlerExceptionWithMessage String
deriving (Eq, Ord, Show)
-- | Make 'HandlerException' an instance of 'Exception' so it can be thrown
instance Exception HandlerException