packages feed

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