-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | rebindable methods for improving testability -- -- This package provides Method typeclass, which represents monadic -- functions, and provides easy DSL for mocking/verifying methods. @package method @version 0.1.0.0 module Control.Method.Internal class TupleLike a where { type family AsTuple a; } fromTuple :: TupleLike a => AsTuple a -> a toTuple :: TupleLike a => a -> AsTuple a -- | Nullary tuple data Nil Nil :: Nil -- | Tuple constructor data a :* b (:*) :: a -> !b -> (:*) a b infixr 1 :* infixr 1 :* instance GHC.Show.Show Control.Method.Internal.Nil instance GHC.Classes.Ord Control.Method.Internal.Nil instance GHC.Classes.Eq Control.Method.Internal.Nil instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (a Control.Method.Internal.:* b) instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (a Control.Method.Internal.:* b) instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (a Control.Method.Internal.:* b) instance Control.Method.Internal.TupleLike (a Control.Method.Internal.:* Control.Method.Internal.Nil) instance Control.Method.Internal.TupleLike (a Control.Method.Internal.:* (b Control.Method.Internal.:* Control.Method.Internal.Nil)) instance Control.Method.Internal.TupleLike (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* Control.Method.Internal.Nil))) instance Control.Method.Internal.TupleLike (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* Control.Method.Internal.Nil)))) instance Control.Method.Internal.TupleLike (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* (e Control.Method.Internal.:* Control.Method.Internal.Nil))))) instance Control.Method.Internal.TupleLike (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* (e Control.Method.Internal.:* (f Control.Method.Internal.:* Control.Method.Internal.Nil)))))) instance Control.Method.Internal.TupleLike (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* (e Control.Method.Internal.:* (f Control.Method.Internal.:* (g Control.Method.Internal.:* Control.Method.Internal.Nil))))))) instance Control.Method.Internal.TupleLike Control.Method.Internal.Nil module Control.Method -- | Method a is a function of the form a1 -> a2 -> ... -- -> an -> m b where m is Monad -- -- Typical monads in transformers package are supported. If you want to -- support other monads (for example M), add the following -- boilerplate. -- --
--   instance Method (M a) where
--     Base (M a) = M
--     Ret  (M a) = a
--   
-- -- Caution Function monad (-> r) cannot be an instance -- of Method class Monad (Base method) => Method method where { -- | Underling monad -- --
    --   Base (a1 -> ... -> an -> m b) = m
    --   
type family Base method :: Type -> Type; -- | Arguments tuple of the method -- --
    --   Args (a1 -> ... -> an -> m b) = a1 :* ... :* an
    --   
type family Args method :: Type; -- | Return type of the method -- --
    --   Ret  (a1 -> ... -> an -> m b) = b
    --   
type family Ret method :: Type; type Args method = Nil; } -- | Convert method to unary function uncurryMethod :: Method method => method -> Args method -> Base method (Ret method) -- | Convert method to unary function uncurryMethod :: (Method method, method ~ Base method a, Args method ~ Nil, Ret method ~ a) => method -> Args method -> Base method (Ret method) -- | Reconstruct method from unary function curryMethod :: Method method => (Args method -> Base method (Ret method)) -> method -- | Reconstruct method from unary function curryMethod :: (Method method, method ~ Base method a, Args method ~ Nil, Ret method ~ a) => (Args method -> Base method (Ret method)) -> method class TupleLike a where { type family AsTuple a; } fromTuple :: TupleLike a => AsTuple a -> a toTuple :: TupleLike a => a -> AsTuple a -- | Insert hooks before/after calling the argument method decorate :: (Method method, MonadUnliftIO (Base method)) => (Args method -> Base method a) -> (a -> Either SomeException (Ret method) -> Base method ()) -> (a -> method) -> method -- | Insert hooks before/after calling the argument method decorate_ :: (Method method, MonadUnliftIO (Base method)) => (Args method -> Base method ()) -> (Either SomeException (Ret method) -> Base method ()) -> method -> method -- | Insert hooks only before calling the argument method. Because it's -- free from MonadUnliftIO constraint, any methods are supported. decorateBefore_ :: Method method => (Args method -> Base method ()) -> method -> method -- | invoke method taken from reader environment invoke :: (MonadReader env (Base method), Method method) => SimpleGetter env method -> method -- | Generalization of join function liftJoin :: Method method => Base method method -> method instance Control.Method.Method (GHC.Types.IO a) instance Control.Method.Method (RIO.Prelude.RIO.RIO env a) instance Control.Method.Method (Data.Functor.Identity.Identity a) instance Control.Method.Method (GHC.Maybe.Maybe a) instance Control.Method.Method [a] instance Control.Method.Method (Data.Either.Either e a) instance Control.Method.Method (GHC.ST.ST s a) instance (GHC.Base.Monoid w, GHC.Base.Monad m) => Control.Method.Method (Control.Monad.Trans.Accum.AccumT w m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.Cont.ContT r m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.Except.ExceptT e m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.Maybe.MaybeT m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.RWS.CPS.RWST r w s m a) instance (GHC.Base.Monad m, GHC.Base.Monoid w) => Control.Method.Method (Control.Monad.Trans.RWS.Lazy.RWST r w s m a) instance (GHC.Base.Monad m, GHC.Base.Monoid w) => Control.Method.Method (Control.Monad.Trans.RWS.Strict.RWST r w s m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.Reader.ReaderT r m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.Select.SelectT r m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.State.Lazy.StateT s m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.State.Strict.StateT s m a) instance GHC.Base.Monad m => Control.Method.Method (Control.Monad.Trans.Writer.CPS.WriterT w m a) instance (GHC.Base.Monad m, GHC.Base.Monoid w) => Control.Method.Method (Control.Monad.Trans.Writer.Lazy.WriterT w m a) instance (GHC.Base.Monad m, GHC.Base.Monoid w) => Control.Method.Method (Control.Monad.Trans.Writer.Strict.WriterT w m a) instance Control.Method.Method b => Control.Method.Method (a -> b) module Test.Method.Matcher -- | Matcher that matches anything anything :: Matcher a -- | synonym of id function. Use this function for improving -- readability when :: Matcher a -> Matcher a type Matcher a = a -> Bool class TupleLike a where { type family AsTuple a; } fromTuple :: TupleLike a => AsTuple a -> a toTuple :: TupleLike a => a -> AsTuple a -- | Matcher for Args -- --
--   >>> args ((==2), (>3)) (2 :* 4 :* Nil)
--   True
--   
--   >>> args even (1 :* Nil)
--   False
--   
--   >>> args () Nil
--   True
--   
class TupleLike a => ArgsMatcher a where { type family EachMatcher a; } -- | Convert a tuple of matchers to a matcher of tuples args :: ArgsMatcher a => EachMatcher a -> Matcher a -- | Convert a tuple matcher to a tuple-like matcher. -- --
--   >>> args' (\(a, b) -> a * b == 10) (2 :* 5 :* Nil)
--   True
--   
--   >>> args' (\(a, b) -> a * b == 10) (2 :* 4 :* Nil)
--   False
--   
args' :: TupleLike a => Matcher (AsTuple a) -> Matcher a instance Test.Method.Matcher.ArgsMatcher Control.Method.Internal.Nil instance Test.Method.Matcher.ArgsMatcher (a Control.Method.Internal.:* Control.Method.Internal.Nil) instance Test.Method.Matcher.ArgsMatcher (a Control.Method.Internal.:* (b Control.Method.Internal.:* Control.Method.Internal.Nil)) instance Test.Method.Matcher.ArgsMatcher (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* Control.Method.Internal.Nil))) instance Test.Method.Matcher.ArgsMatcher (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* Control.Method.Internal.Nil)))) instance Test.Method.Matcher.ArgsMatcher (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* (e Control.Method.Internal.:* Control.Method.Internal.Nil))))) instance Test.Method.Matcher.ArgsMatcher (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* (e Control.Method.Internal.:* (f Control.Method.Internal.:* Control.Method.Internal.Nil)))))) instance Test.Method.Matcher.ArgsMatcher (a Control.Method.Internal.:* (b Control.Method.Internal.:* (c Control.Method.Internal.:* (d Control.Method.Internal.:* (e Control.Method.Internal.:* (f Control.Method.Internal.:* (g Control.Method.Internal.:* Control.Method.Internal.Nil))))))) -- | DSL to generate mock methods. module Test.Method.Mock type Mock method = Writer (MockSpec method) () data MockSpec method -- | generate a method from Mock DSL. Mock DSL consists of rules. On a call -- of generated method, the first rule matched the arguments is applied. mockup :: (Method method, MonadThrow (Base method)) => Mock method -> method -- | matcher `thenReturn` value means the method return -- value if the arguments matches matcher. thenReturn :: (Method method, Applicative (Base method)) => Matcher (Args method) -> Ret method -> Mock method -- | matcher `thenAction` action means the method executes -- action if the arguments matches matcher. thenAction :: Method method => Matcher (Args method) -> Base method (Ret method) -> Mock method -- | matcher `thenMethod` action means the method call -- method with the arguments if the arguments matches -- matcher. thenMethod :: Method method => Matcher (Args method) -> method -> Mock method -- | throwNoStubShow matcher means the method throws a -- NoStubException if the arguments matches matcher. The -- argument tuple is converted to String by using show -- function. throwNoStubShow :: (Method method, Show (AsTuple (Args method)), MonadThrow (Base method), TupleLike (Args method)) => Matcher (Args method) -> Mock method -- | throwNoStubShow fshow matcher means the method throws -- a NoStubException if the arguments matches matcher. -- The argument tuple is converted to String by using -- fshow function. throwNoStub :: (Method method, MonadThrow (Base method)) => (Args method -> String) -> (Args method -> Bool) -> Mock method newtype NoStubException NoStubException :: String -> NoStubException instance GHC.Show.Show Test.Method.Mock.NoStubException instance GHC.Exception.Type.Exception Test.Method.Mock.NoStubException instance GHC.Base.Semigroup (Test.Method.Mock.MockSpec method) instance GHC.Base.Monoid (Test.Method.Mock.MockSpec method) module Test.Method.Monitor.Internal -- | Tick represents call identifier newtype Tick Tick :: Int -> Tick [unTick] :: Tick -> Int -- | Event args ret is a function call event data Event args ret Enter :: !Tick -> !args -> Event args ret [eventTick] :: Event args ret -> !Tick [eventArgs] :: Event args ret -> !args Leave :: !Tick -> !Tick -> !Either (EqUptoShow SomeException) ret -> Event args ret [eventTick] :: Event args ret -> !Tick [eventEnterTick] :: Event args ret -> !Tick [eventRet] :: Event args ret -> !Either (EqUptoShow SomeException) ret type Clock = IORef Tick -- | newtype to implement show instance which shows its type. newtype ShowType a ShowType :: a -> ShowType a -- | newtype to compare values via show newtype EqUptoShow a EqUptoShow :: a -> EqUptoShow a -- | Monitor arg ret is an event monitor of methods, which logs -- method calls. data Monitor args ret Monitor :: !SomeRef [Event args ret] -> !Clock -> Monitor args ret [monitorTrace] :: Monitor args ret -> !SomeRef [Event args ret] [monitorClock] :: Monitor args ret -> !Clock -- | Generate new instance of Monitor newMonitor :: IO (Monitor args ret) -- | Increment the clock and return the current tick. tick :: MonadIO m => Monitor args ret -> m Tick -- | logs an event logEvent :: MonadIO m => Monitor args ret -> Event args ret -> m () instance GHC.Enum.Enum Test.Method.Monitor.Internal.Tick instance GHC.Show.Show Test.Method.Monitor.Internal.Tick instance GHC.Classes.Ord Test.Method.Monitor.Internal.Tick instance GHC.Classes.Eq Test.Method.Monitor.Internal.Tick instance GHC.Classes.Ord a => GHC.Classes.Ord (Test.Method.Monitor.Internal.ShowType a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Test.Method.Monitor.Internal.ShowType a) instance (GHC.Show.Show args, GHC.Show.Show ret) => GHC.Show.Show (Test.Method.Monitor.Internal.Event args ret) instance (GHC.Classes.Ord args, GHC.Classes.Ord ret) => GHC.Classes.Ord (Test.Method.Monitor.Internal.Event args ret) instance (GHC.Classes.Eq args, GHC.Classes.Eq ret) => GHC.Classes.Eq (Test.Method.Monitor.Internal.Event args ret) instance GHC.Show.Show a => GHC.Show.Show (Test.Method.Monitor.Internal.EqUptoShow a) instance GHC.Show.Show a => GHC.Classes.Eq (Test.Method.Monitor.Internal.EqUptoShow a) instance GHC.Show.Show a => GHC.Classes.Ord (Test.Method.Monitor.Internal.EqUptoShow a) instance Data.Typeable.Internal.Typeable a => GHC.Show.Show (Test.Method.Monitor.Internal.ShowType a) -- | Validating method calls by monitoring module Test.Method.Monitor -- | Event args ret is a function call event data Event args ret -- | Monitor arg ret is an event monitor of methods, which logs -- method calls. data Monitor args ret -- | Generate new instance of Monitor newMonitor :: IO (Monitor args ret) -- | Simplified version of watchBy. It is suitable to monitor single -- method. watch :: (Method method, MonadUnliftIO (Base method)) => Monitor (Args method) (Ret method) -> method -> method -- | watchBy fArgs fRet monitor method decorates method -- so that monitor logs the method calls. This function is -- suited for monitoring multiple methods. -- -- fArgs and fRet is converter for arguments/return -- values of given method. -- --
--   foo :: Int -> IO String
--   foo = ...
--   bar :: Int -> String -> IO ()
--   bar = ...
--   
--   data MonitorArgs = FooArgs Int | BarArgs (Int,String) deriving(Eq,Show)
--   data MonitorRet = FooRet String | BarRet () deriving(Eq, Show)
--   
--   foo' :: Monitor MonitorArgs MonitorRet -> Int -> IO String
--   foo' monitor = watch monitor (FooArgs . toTuple) FooRet foo
--   bar' :: Monitor MonitorArgs MonitorRet -> Int -> String -> IO ()
--   bar' monitor = watch monitor (BarArgs . toTuple) BarRet bar
--   
watchBy :: (Method method, MonadUnliftIO (Base method)) => (Args method -> args) -> (Ret method -> ret) -> Monitor args ret -> method -> method -- | Get current event logs from monitor listenEventLog :: MonadIO m => Monitor args ret -> m [Event args ret] -- | withMonitor f calls f with Monitor, and then -- returns monitored event logs during the function call in addition to -- the return value of the function call withMonitor :: MonadIO m => (Monitor args ret -> m a) -> m (a, [Event args ret]) -- | withMonitor_ f calls f with Monitor, and -- returns event logs during the call. withMonitor_ :: MonadIO m => (Monitor args ret -> m ()) -> m [Event args ret] -- | times countMatcher eventMatcher counts events that -- matches eventMatcher, and then the count matches -- countMatcher times :: Matcher Int -> Matcher (Event args ret) -> Matcher [Event args ret] -- | call matcher matches method call whose arguments -- matches matcher call :: Matcher args -> Matcher (Event args ret) module Test.Method -- | generate a method from Mock DSL. Mock DSL consists of rules. On a call -- of generated method, the first rule matched the arguments is applied. mockup :: (Method method, MonadThrow (Base method)) => Mock method -> method -- | matcher `thenReturn` value means the method return -- value if the arguments matches matcher. thenReturn :: (Method method, Applicative (Base method)) => Matcher (Args method) -> Ret method -> Mock method -- | matcher `thenAction` action means the method executes -- action if the arguments matches matcher. thenAction :: Method method => Matcher (Args method) -> Base method (Ret method) -> Mock method -- | matcher `thenMethod` action means the method call -- method with the arguments if the arguments matches -- matcher. thenMethod :: Method method => Matcher (Args method) -> method -> Mock method -- | throwNoStubShow matcher means the method throws a -- NoStubException if the arguments matches matcher. The -- argument tuple is converted to String by using show -- function. throwNoStubShow :: (Method method, Show (AsTuple (Args method)), MonadThrow (Base method), TupleLike (Args method)) => Matcher (Args method) -> Mock method -- | throwNoStubShow fshow matcher means the method throws -- a NoStubException if the arguments matches matcher. -- The argument tuple is converted to String by using -- fshow function. throwNoStub :: (Method method, MonadThrow (Base method)) => (Args method -> String) -> (Args method -> Bool) -> Mock method newtype NoStubException NoStubException :: String -> NoStubException -- | Monitor arg ret is an event monitor of methods, which logs -- method calls. data Monitor args ret -- | Event args ret is a function call event data Event args ret -- | watchBy fArgs fRet monitor method decorates method -- so that monitor logs the method calls. This function is -- suited for monitoring multiple methods. -- -- fArgs and fRet is converter for arguments/return -- values of given method. -- --
--   foo :: Int -> IO String
--   foo = ...
--   bar :: Int -> String -> IO ()
--   bar = ...
--   
--   data MonitorArgs = FooArgs Int | BarArgs (Int,String) deriving(Eq,Show)
--   data MonitorRet = FooRet String | BarRet () deriving(Eq, Show)
--   
--   foo' :: Monitor MonitorArgs MonitorRet -> Int -> IO String
--   foo' monitor = watch monitor (FooArgs . toTuple) FooRet foo
--   bar' :: Monitor MonitorArgs MonitorRet -> Int -> String -> IO ()
--   bar' monitor = watch monitor (BarArgs . toTuple) BarRet bar
--   
watchBy :: (Method method, MonadUnliftIO (Base method)) => (Args method -> args) -> (Ret method -> ret) -> Monitor args ret -> method -> method -- | Simplified version of watchBy. It is suitable to monitor single -- method. watch :: (Method method, MonadUnliftIO (Base method)) => Monitor (Args method) (Ret method) -> method -> method -- | withMonitor f calls f with Monitor, and then -- returns monitored event logs during the function call in addition to -- the return value of the function call withMonitor :: MonadIO m => (Monitor args ret -> m a) -> m (a, [Event args ret]) -- | withMonitor_ f calls f with Monitor, and -- returns event logs during the call. withMonitor_ :: MonadIO m => (Monitor args ret -> m ()) -> m [Event args ret] -- | call matcher matches method call whose arguments -- matches matcher call :: Matcher args -> Matcher (Event args ret) -- | times countMatcher eventMatcher counts events that -- matches eventMatcher, and then the count matches -- countMatcher times :: Matcher Int -> Matcher (Event args ret) -> Matcher [Event args ret] -- | Generate new instance of Monitor newMonitor :: IO (Monitor args ret) -- | Get current event logs from monitor listenEventLog :: MonadIO m => Monitor args ret -> m [Event args ret] type Matcher a = a -> Bool -- | Matcher that matches anything anything :: Matcher a -- | synonym of id function. Use this function for improving -- readability when :: Matcher a -> Matcher a class TupleLike a where { type family AsTuple a; } fromTuple :: TupleLike a => AsTuple a -> a toTuple :: TupleLike a => a -> AsTuple a -- | Matcher for Args -- --
--   >>> args ((==2), (>3)) (2 :* 4 :* Nil)
--   True
--   
--   >>> args even (1 :* Nil)
--   False
--   
--   >>> args () Nil
--   True
--   
class TupleLike a => ArgsMatcher a -- | Convert a tuple of matchers to a matcher of tuples args :: ArgsMatcher a => EachMatcher a -> Matcher a -- | Convert a tuple matcher to a tuple-like matcher. -- --
--   >>> args' (\(a, b) -> a * b == 10) (2 :* 5 :* Nil)
--   True
--   
--   >>> args' (\(a, b) -> a * b == 10) (2 :* 4 :* Nil)
--   False
--   
args' :: TupleLike a => Matcher (AsTuple a) -> Matcher a