{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}

{-# HLINT ignore "Use null" #-}

{- | This module provides bellow functions.

  - Create mocks that can be stubbed and verified.

  - Create stub function.

  - Verify applied mock function.
-}
module Test.MockCat.Mock
  ( createMock,
    createNamedMock,
    createStubFn,
    createNamedStubFn,
    stubFn,
    shouldApplyTo,
    shouldApplyTimes,
    shouldApplyInOrder,
    shouldApplyInPartialOrder,
    shouldApplyTimesGreaterThanEqual,
    shouldApplyTimesLessThanEqual,
    shouldApplyTimesGreaterThan,
    shouldApplyTimesLessThan,
    to,
    module Test.MockCat.Cons,
    module Test.MockCat.Param
  )
where

import Control.Monad (guard)
import Control.Monad.IO.Class (MonadIO (liftIO))
import Data.Function ((&))
import Data.IORef (IORef, modifyIORef', newIORef, readIORef)
import Data.List (elemIndex, intercalate)
import Data.Maybe
import Data.Text (pack, replace, unpack)
import GHC.IO (unsafePerformIO)
import Test.MockCat.Cons
import Test.MockCat.Param
import Test.MockCat.ParamDivider
import Test.MockCat.AssociationList (AssociationList, lookup, update, insert, empty, member)
import Prelude hiding (lookup)

data Mock fun params = Mock (Maybe MockName) fun (Verifier params)

type MockName = String

newtype Verifier params = Verifier (IORef (AppliedRecord params))

{- | Create a mock.
From this mock, you can generate stub functions and verify the functions.

  @
  import Test.Hspec
  import Test.MockCat
  ...
  it "stub & verify" do
    -- create a mock
    m \<- createMock $ "value" |\> True
    -- stub function
    let f = stubFn m
    -- assert
    f "value" \`shouldBe\` True
    -- verify
    m \`shouldApplyTo\` "value"
  @

  If you do not need verification and only need stub functions, you can use @'mockFun'@.

-}
createMock ::
  MockBuilder params fun verifyParams =>
  MonadIO m =>
  params ->
  m (Mock fun verifyParams)
createMock :: forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
params -> m (Mock fun verifyParams)
createMock params
params = IO (Mock fun verifyParams) -> m (Mock fun verifyParams)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Mock fun verifyParams) -> m (Mock fun verifyParams))
-> IO (Mock fun verifyParams) -> m (Mock fun verifyParams)
forall a b. (a -> b) -> a -> b
$ Maybe String -> params -> IO (Mock fun verifyParams)
forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
Maybe String -> params -> m (Mock fun verifyParams)
forall (m :: * -> *).
MonadIO m =>
Maybe String -> params -> m (Mock fun verifyParams)
build Maybe String
forall a. Maybe a
Nothing params
params

{- | Create a named mock. If the test fails, this name is used. This may be useful if you have multiple mocks.

  @
  import Test.Hspec
  import Test.MockCat
  ...
  it "named mock" do
    m \<- createNamedMock "mock" $ "value" |\> True
    stubFn m "value" \`shouldBe\` True
  @
-}
createNamedMock ::
  MockBuilder params fun verifyParams =>
  MonadIO m =>
  MockName ->
  params ->
  m (Mock fun verifyParams)
createNamedMock :: forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
String -> params -> m (Mock fun verifyParams)
createNamedMock String
name params
params = IO (Mock fun verifyParams) -> m (Mock fun verifyParams)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Mock fun verifyParams) -> m (Mock fun verifyParams))
-> IO (Mock fun verifyParams) -> m (Mock fun verifyParams)
forall a b. (a -> b) -> a -> b
$ Maybe String -> params -> IO (Mock fun verifyParams)
forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
Maybe String -> params -> m (Mock fun verifyParams)
forall (m :: * -> *).
MonadIO m =>
Maybe String -> params -> m (Mock fun verifyParams)
build (String -> Maybe String
forall a. a -> Maybe a
Just String
name) params
params

-- | Extract the stub function from the mock.
stubFn :: Mock fun v -> fun
stubFn :: forall fun v. Mock fun v -> fun
stubFn (Mock Maybe String
_ fun
f Verifier v
_) = fun
f

{- | Create a stub function.
  @
  import Test.Hspec
  import Test.MockCat
  ...
  it "stub function" do
    f \<- createStubFn $ "value" |\> True
    f "value" \`shouldBe\` True
  @
-}
createStubFn ::
  MockBuilder params fun verifyParams =>
  MonadIO m =>
  params ->
  m fun
createStubFn :: forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
params -> m fun
createStubFn params
params = Mock fun verifyParams -> fun
forall fun v. Mock fun v -> fun
stubFn (Mock fun verifyParams -> fun)
-> m (Mock fun verifyParams) -> m fun
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> params -> m (Mock fun verifyParams)
forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
params -> m (Mock fun verifyParams)
createMock params
params


-- | Create a named stub function.
createNamedStubFn ::
  MockBuilder params fun verifyParams =>
  MonadIO m =>
  String ->
  params ->
  m fun
createNamedStubFn :: forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
String -> params -> m fun
createNamedStubFn String
name params
params = Mock fun verifyParams -> fun
forall fun v. Mock fun v -> fun
stubFn (Mock fun verifyParams -> fun)
-> m (Mock fun verifyParams) -> m fun
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> params -> m (Mock fun verifyParams)
forall params fun verifyParams (m :: * -> *).
(MockBuilder params fun verifyParams, MonadIO m) =>
String -> params -> m (Mock fun verifyParams)
createNamedMock String
name params
params

-- | Class for creating a mock corresponding to the parameter.
class MockBuilder params fun verifyParams | params -> fun, params -> verifyParams where
  -- build a mock
  build :: MonadIO m => Maybe MockName -> params -> m (Mock fun verifyParams)

-- instances
instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f, Show g, Eq g, Show h, Eq h, Show i, Eq i) =>
  MockBuilder
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param i :> Param r)
    (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param i)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e
                    :> (Param f :> (Param g :> (Param h :> (Param i :> Param r)))))))))
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
build Maybe String
name Param a
:> (Param b
    :> (Param c
        :> (Param d
            :> (Param e
                :> (Param f :> (Param g :> (Param h :> (Param i :> Param r))))))))
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d
                  :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e
                         :> (Param f :> (Param g :> (Param h :> Param i))))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b
              :> (Param c
                  :> (Param d
                      :> (Param e
                          :> (Param f :> (Param g :> (Param h :> Param i))))))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b
                 :> (Param c
                     :> (Param d
                         :> (Param e
                             :> (Param f :> (Param g :> (Param h :> Param i)))))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
-> (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock
      Maybe String
name
      IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d
                  :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
s
      ( \a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 g
g2 h
h2 i
i2 ->
          IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e
                    :> (Param f :> (Param g :> (Param h :> (Param i :> Param r)))))))))
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a
:> (Param b
    :> (Param c
        :> (Param d
            :> (Param e
                :> (Param f :> (Param g :> (Param h :> (Param i :> Param r))))))))
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b
    :> (Param c
        :> (Param d
            :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c
    :> (Param d
        :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))
-> Param b
   :> (Param c
       :> (Param d
           :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d
    :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))
-> Param c
   :> (Param d
       :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d
-> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))
-> Param d
   :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e
-> (Param f :> (Param g :> (Param h :> Param i)))
-> Param e :> (Param f :> (Param g :> (Param h :> Param i)))
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2 Param f
-> (Param g :> (Param h :> Param i))
-> Param f :> (Param g :> (Param h :> Param i))
forall a b. a -> b -> a :> b
:> g -> Param g
forall a. a -> Param a
p g
g2 Param g -> (Param h :> Param i) -> Param g :> (Param h :> Param i)
forall a b. a -> b -> a :> b
:> h -> Param h
forall a. a -> Param a
p h
h2 Param h -> Param i -> Param h :> Param i
forall a b. a -> b -> a :> b
:> i -> Param i
forall a. a -> Param a
p i
i2) IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d
                  :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
s
      )

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f, Show g, Eq g, Show h, Eq h) =>
  MockBuilder
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param r)
    (a -> b -> c -> d -> e -> f -> g -> h -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e :> (Param f :> (Param g :> (Param h :> Param r))))))))
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
build Maybe String
name Param a
:> (Param b
    :> (Param c
        :> (Param d
            :> (Param e :> (Param f :> (Param g :> (Param h :> Param r)))))))
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b
              :> (Param c
                  :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b
                 :> (Param c
                     :> (Param d
                         :> (Param e :> (Param f :> (Param g :> Param h))))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
-> (a -> b -> c -> d -> e -> f -> g -> h -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock
      Maybe String
name
      IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
s
      ( \a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 g
g2 h
h2 ->
          IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e :> (Param f :> (Param g :> (Param h :> Param r))))))))
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a
:> (Param b
    :> (Param c
        :> (Param d
            :> (Param e :> (Param f :> (Param g :> (Param h :> Param r)))))))
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b
    :> (Param c
        :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c
    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))
-> Param b
   :> (Param c
       :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))
-> Param c
   :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d
-> (Param e :> (Param f :> (Param g :> Param h)))
-> Param d :> (Param e :> (Param f :> (Param g :> Param h)))
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e
-> (Param f :> (Param g :> Param h))
-> Param e :> (Param f :> (Param g :> Param h))
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2 Param f -> (Param g :> Param h) -> Param f :> (Param g :> Param h)
forall a b. a -> b -> a :> b
:> g -> Param g
forall a. a -> Param a
p g
g2 Param g -> Param h -> Param g :> Param h
forall a b. a -> b -> a :> b
:> h -> Param h
forall a. a -> Param a
p h
h2) IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
s
      )

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f, Show g, Eq g) =>
  MockBuilder
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param r)
    (a -> b -> c -> d -> e -> f -> g -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d :> (Param e :> (Param f :> (Param g :> Param r)))))))
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> r)
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
build Maybe String
name Param a
:> (Param b
    :> (Param c
        :> (Param d :> (Param e :> (Param f :> (Param g :> Param r))))))
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b
              :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b
                 :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
-> (a -> b -> c -> d -> e -> f -> g -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> r)
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock
      Maybe String
name
      IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
s
      ( \a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 g
g2 ->
          IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d :> (Param e :> (Param f :> (Param g :> Param r)))))))
-> (Param a
    :> (Param b
        :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a
:> (Param b
    :> (Param c
        :> (Param d :> (Param e :> (Param f :> (Param g :> Param r))))))
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b
    :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))
-> Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))
-> Param b
   :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d :> (Param e :> (Param f :> Param g)))
-> Param c :> (Param d :> (Param e :> (Param f :> Param g)))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d
-> (Param e :> (Param f :> Param g))
-> Param d :> (Param e :> (Param f :> Param g))
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e -> (Param f :> Param g) -> Param e :> (Param f :> Param g)
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2 Param f -> Param g -> Param f :> Param g
forall a b. a -> b -> a :> b
:> g -> Param g
forall a. a -> Param a
p g
g2) IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
s
      )

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f) =>
  MockBuilder
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param r)
    (a -> b -> c -> d -> e -> f -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a
    :> (Param b
        :> (Param c :> (Param d :> (Param e :> (Param f :> Param r))))))
-> m (Mock
        (a -> b -> c -> d -> e -> f -> r)
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
build Maybe String
name Param a
:> (Param b
    :> (Param c :> (Param d :> (Param e :> (Param f :> Param r)))))
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
-> (a -> b -> c -> d -> e -> f -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> r)
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord
     (Param a
      :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
s (\a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a
    :> (Param b
        :> (Param c :> (Param d :> (Param e :> (Param f :> Param r))))))
-> (Param a
    :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a
:> (Param b
    :> (Param c :> (Param d :> (Param e :> (Param f :> Param r)))))
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))
-> Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c :> (Param d :> (Param e :> Param f)))
-> Param b :> (Param c :> (Param d :> (Param e :> Param f)))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d :> (Param e :> Param f))
-> Param c :> (Param d :> (Param e :> Param f))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d -> (Param e :> Param f) -> Param d :> (Param e :> Param f)
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e -> Param f -> Param e :> Param f
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2) IORef
  (AppliedRecord
     (Param a
      :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e) =>
  MockBuilder
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param r)
    (a -> b -> c -> d -> e -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a
    :> (Param b :> (Param c :> (Param d :> (Param e :> Param r)))))
-> m (Mock
        (a -> b -> c -> d -> e -> r)
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
build Maybe String
name Param a
:> (Param b :> (Param c :> (Param d :> (Param e :> Param r))))
params = do
    IORef
  (AppliedRecord
     (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
-> m (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
 -> m (IORef
         (AppliedRecord
            (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
-> m (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a :> (Param b :> (Param c :> (Param d :> Param e))))
-> IO
     (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a :> (Param b :> (Param c :> (Param d :> Param e))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
-> (a -> b -> c -> d -> e -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> r)
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord
     (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
s (\a
a2 b
b2 c
c2 d
d2 e
e2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a
    :> (Param b :> (Param c :> (Param d :> (Param e :> Param r)))))
-> (Param a :> (Param b :> (Param c :> (Param d :> Param e))))
-> IORef
     (AppliedRecord
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a
:> (Param b :> (Param c :> (Param d :> (Param e :> Param r))))
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b :> (Param c :> (Param d :> Param e)))
-> Param a :> (Param b :> (Param c :> (Param d :> Param e)))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c :> (Param d :> Param e))
-> Param b :> (Param c :> (Param d :> Param e))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c -> (Param d :> Param e) -> Param c :> (Param d :> Param e)
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d -> Param e -> Param d :> Param e
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2) IORef
  (AppliedRecord
     (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d) =>
  MockBuilder
    (Param a :> Param b :> Param c :> Param d :> Param r)
    (a -> b -> c -> d -> r)
    (Param a :> Param b :> Param c :> Param d)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a :> (Param b :> (Param c :> (Param d :> Param r))))
-> m (Mock
        (a -> b -> c -> d -> r)
        (Param a :> (Param b :> (Param c :> Param d))))
build Maybe String
name Param a :> (Param b :> (Param c :> (Param d :> Param r)))
params = do
    IORef
  (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
s <- IO
  (IORef
     (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
-> m (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
 -> m (IORef
         (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))))
-> IO
     (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
-> m (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))
-> IO
     (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
-> (a -> b -> c -> d -> r)
-> m (Mock
        (a -> b -> c -> d -> r)
        (Param a :> (Param b :> (Param c :> Param d))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
s (\a
a2 b
b2 c
c2 d
d2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a :> (Param b :> (Param c :> (Param d :> Param r))))
-> (Param a :> (Param b :> (Param c :> Param d)))
-> IORef
     (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a :> (Param b :> (Param c :> (Param d :> Param r)))
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b :> (Param c :> Param d))
-> Param a :> (Param b :> (Param c :> Param d))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b -> (Param c :> Param d) -> Param b :> (Param c :> Param d)
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c -> Param d -> Param c :> Param d
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2) IORef
  (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c) =>
  MockBuilder (Param a :> Param b :> Param c :> Param r) (a -> b -> c -> r) (Param a :> Param b :> Param c)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a :> (Param b :> (Param c :> Param r)))
-> m (Mock (a -> b -> c -> r) (Param a :> (Param b :> Param c)))
build Maybe String
name Param a :> (Param b :> (Param c :> Param r))
params = do
    IORef (AppliedRecord (Param a :> (Param b :> Param c)))
s <- IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
-> m (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
 -> m (IORef (AppliedRecord (Param a :> (Param b :> Param c)))))
-> IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
-> m (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a :> (Param b :> Param c))
-> IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a :> (Param b :> Param c))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef (AppliedRecord (Param a :> (Param b :> Param c)))
-> (a -> b -> c -> r)
-> m (Mock (a -> b -> c -> r) (Param a :> (Param b :> Param c)))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef (AppliedRecord (Param a :> (Param b :> Param c)))
s (\a
a2 b
b2 c
c2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a :> (Param b :> (Param c :> Param r)))
-> (Param a :> (Param b :> Param c))
-> IORef (AppliedRecord (Param a :> (Param b :> Param c)))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a :> (Param b :> (Param c :> Param r))
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a -> (Param b :> Param c) -> Param a :> (Param b :> Param c)
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b -> Param c -> Param b :> Param c
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2) IORef (AppliedRecord (Param a :> (Param b :> Param c)))
s)

instance
  (Show a, Eq a, Show b, Eq b) =>
  MockBuilder (Param a :> Param b :> Param r) (a -> b -> r) (Param a :> Param b)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> (Param a :> (Param b :> Param r))
-> m (Mock (a -> b -> r) (Param a :> Param b))
build Maybe String
name Param a :> (Param b :> Param r)
params = do
    IORef (AppliedRecord (Param a :> Param b))
s <- IO (IORef (AppliedRecord (Param a :> Param b)))
-> m (IORef (AppliedRecord (Param a :> Param b)))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (AppliedRecord (Param a :> Param b)))
 -> m (IORef (AppliedRecord (Param a :> Param b))))
-> IO (IORef (AppliedRecord (Param a :> Param b)))
-> m (IORef (AppliedRecord (Param a :> Param b)))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a :> Param b)
-> IO (IORef (AppliedRecord (Param a :> Param b)))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a :> Param b)
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef (AppliedRecord (Param a :> Param b))
-> (a -> b -> r)
-> m (Mock (a -> b -> r) (Param a :> Param b))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef (AppliedRecord (Param a :> Param b))
s (\a
a2 b
b2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a :> (Param b :> Param r))
-> (Param a :> Param b)
-> IORef (AppliedRecord (Param a :> Param b))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a :> (Param b :> Param r)
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a -> Param b -> Param a :> Param b
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2) IORef (AppliedRecord (Param a :> Param b))
s)

instance
  (Show a, Eq a) =>
  MockBuilder (Param a :> Param r) (a -> r) (Param a)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String -> (Param a :> Param r) -> m (Mock (a -> r) (Param a))
build Maybe String
name Param a :> Param r
params = do
    IORef (AppliedRecord (Param a))
s <- IO (IORef (AppliedRecord (Param a)))
-> m (IORef (AppliedRecord (Param a)))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (AppliedRecord (Param a)))
 -> m (IORef (AppliedRecord (Param a))))
-> IO (IORef (AppliedRecord (Param a)))
-> m (IORef (AppliedRecord (Param a)))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a) -> IO (IORef (AppliedRecord (Param a)))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a)
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef (AppliedRecord (Param a))
-> (a -> r)
-> m (Mock (a -> r) (Param a))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef (AppliedRecord (Param a))
s (\a
a2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> (Param a :> Param r)
-> Param a
-> IORef (AppliedRecord (Param a))
-> IO r
forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name Param a :> Param r
params (a -> Param a
forall a. a -> Param a
p a
a2) IORef (AppliedRecord (Param a))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f, Show g, Eq g, Show h, Eq h, Show i, Eq i) =>
  MockBuilder
    [Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param i :> Param r]
    (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param i)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e
                    :> (Param f :> (Param g :> (Param h :> (Param i :> Param r))))))))]
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
build Maybe String
name [Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e
                 :> (Param f :> (Param g :> (Param h :> (Param i :> Param r))))))))]
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d
                  :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e
                         :> (Param f :> (Param g :> (Param h :> Param i))))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b
              :> (Param c
                  :> (Param d
                      :> (Param e
                          :> (Param f :> (Param g :> (Param h :> Param i))))))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b
                 :> (Param c
                     :> (Param d
                         :> (Param e
                             :> (Param f :> (Param g :> (Param h :> Param i)))))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d
                        :> (Param e
                            :> (Param f :> (Param g :> (Param h :> Param i))))))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
-> (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> i -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d
                  :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
s (\a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 g
g2 h
h2 i
i2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e
                    :> (Param f :> (Param g :> (Param h :> (Param i :> Param r))))))))]
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d
                     :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e
                 :> (Param f :> (Param g :> (Param h :> (Param i :> Param r))))))))]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b
    :> (Param c
        :> (Param d
            :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c
    :> (Param d
        :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))
-> Param b
   :> (Param c
       :> (Param d
           :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d
    :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))
-> Param c
   :> (Param d
       :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d
-> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))
-> Param d
   :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e
-> (Param f :> (Param g :> (Param h :> Param i)))
-> Param e :> (Param f :> (Param g :> (Param h :> Param i)))
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2 Param f
-> (Param g :> (Param h :> Param i))
-> Param f :> (Param g :> (Param h :> Param i))
forall a b. a -> b -> a :> b
:> g -> Param g
forall a. a -> Param a
p g
g2 Param g -> (Param h :> Param i) -> Param g :> (Param h :> Param i)
forall a b. a -> b -> a :> b
:> h -> Param h
forall a. a -> Param a
p h
h2 Param h -> Param i -> Param h :> Param i
forall a b. a -> b -> a :> b
:> i -> Param i
forall a. a -> Param a
p i
i2) IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d
                  :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f, Show g, Eq g, Show h, Eq h) =>
  MockBuilder
    [Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param r]
    (a -> b -> c -> d -> e -> f -> g -> h -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e :> (Param f :> (Param g :> (Param h :> Param r)))))))]
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
build Maybe String
name [Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e :> (Param f :> (Param g :> (Param h :> Param r)))))))]
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b
              :> (Param c
                  :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b
                 :> (Param c
                     :> (Param d
                         :> (Param e :> (Param f :> (Param g :> Param h))))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c
                    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
-> (a -> b -> c -> d -> e -> f -> g -> h -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> h -> r)
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
s (\a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 g
g2 h
h2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a
    :> (Param b
        :> (Param c
            :> (Param d
                :> (Param e :> (Param f :> (Param g :> (Param h :> Param r)))))))]
-> (Param a
    :> (Param b
        :> (Param c
            :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c
                 :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e :> (Param f :> (Param g :> (Param h :> Param r)))))))]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b
    :> (Param c
        :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c
    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))
-> Param b
   :> (Param c
       :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))
-> Param c
   :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d
-> (Param e :> (Param f :> (Param g :> Param h)))
-> Param d :> (Param e :> (Param f :> (Param g :> Param h)))
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e
-> (Param f :> (Param g :> Param h))
-> Param e :> (Param f :> (Param g :> Param h))
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2 Param f -> (Param g :> Param h) -> Param f :> (Param g :> Param h)
forall a b. a -> b -> a :> b
:> g -> Param g
forall a. a -> Param a
p g
g2 Param g -> Param h -> Param g :> Param h
forall a b. a -> b -> a :> b
:> h -> Param h
forall a. a -> Param a
p h
h2) IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c
              :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f, Show g, Eq g) =>
  MockBuilder
    [Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param r]
    (a -> b -> c -> d -> e -> f -> g -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a
    :> (Param b
        :> (Param c
            :> (Param d :> (Param e :> (Param f :> (Param g :> Param r))))))]
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> r)
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
build Maybe String
name [Param a
 :> (Param b
     :> (Param c
         :> (Param d :> (Param e :> (Param f :> (Param g :> Param r))))))]
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b
              :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b
                 :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b
                :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
-> (a -> b -> c -> d -> e -> f -> g -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> g -> r)
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
s (\a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 g
g2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a
    :> (Param b
        :> (Param c
            :> (Param d :> (Param e :> (Param f :> (Param g :> Param r))))))]
-> (Param a
    :> (Param b
        :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b
             :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a
 :> (Param b
     :> (Param c
         :> (Param d :> (Param e :> (Param f :> (Param g :> Param r))))))]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b
    :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))
-> Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))
-> Param b
   :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d :> (Param e :> (Param f :> Param g)))
-> Param c :> (Param d :> (Param e :> (Param f :> Param g)))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d
-> (Param e :> (Param f :> Param g))
-> Param d :> (Param e :> (Param f :> Param g))
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e -> (Param f :> Param g) -> Param e :> (Param f :> Param g)
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2 Param f -> Param g -> Param f :> Param g
forall a b. a -> b -> a :> b
:> g -> Param g
forall a. a -> Param a
p g
g2) IORef
  (AppliedRecord
     (Param a
      :> (Param b
          :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e, Show f, Eq f) =>
  MockBuilder
    [Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param r]
    (a -> b -> c -> d -> e -> f -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e :> Param f)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a
    :> (Param b
        :> (Param c :> (Param d :> (Param e :> (Param f :> Param r)))))]
-> m (Mock
        (a -> b -> c -> d -> e -> f -> r)
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
build Maybe String
name [Param a
 :> (Param b
     :> (Param c :> (Param d :> (Param e :> (Param f :> Param r)))))]
params = do
    IORef
  (AppliedRecord
     (Param a
      :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a
          :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
 -> m (IORef
         (AppliedRecord
            (Param a
             :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
-> m (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))
-> IO
     (IORef
        (AppliedRecord
           (Param a
            :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
-> (a -> b -> c -> d -> e -> f -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> f -> r)
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord
     (Param a
      :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
s (\a
a2 b
b2 c
c2 d
d2 e
e2 f
f2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a
    :> (Param b
        :> (Param c :> (Param d :> (Param e :> (Param f :> Param r)))))]
-> (Param a
    :> (Param b :> (Param c :> (Param d :> (Param e :> Param f)))))
-> IORef
     (AppliedRecord
        (Param a
         :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a
 :> (Param b
     :> (Param c :> (Param d :> (Param e :> (Param f :> Param r)))))]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))
-> Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c :> (Param d :> (Param e :> Param f)))
-> Param b :> (Param c :> (Param d :> (Param e :> Param f)))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c
-> (Param d :> (Param e :> Param f))
-> Param c :> (Param d :> (Param e :> Param f))
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d -> (Param e :> Param f) -> Param d :> (Param e :> Param f)
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2 Param e -> Param f -> Param e :> Param f
forall a b. a -> b -> a :> b
:> f -> Param f
forall a. a -> Param a
p f
f2) IORef
  (AppliedRecord
     (Param a
      :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d, Show e, Eq e) =>
  MockBuilder
    [Param a :> Param b :> Param c :> Param d :> Param e :> Param r]
    (a -> b -> c -> d -> e -> r)
    (Param a :> Param b :> Param c :> Param d :> Param e)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a
    :> (Param b :> (Param c :> (Param d :> (Param e :> Param r))))]
-> m (Mock
        (a -> b -> c -> d -> e -> r)
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
build Maybe String
name [Param a
 :> (Param b :> (Param c :> (Param d :> (Param e :> Param r))))]
params = do
    IORef
  (AppliedRecord
     (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
s <- IO
  (IORef
     (AppliedRecord
        (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
-> m (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord
         (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
 -> m (IORef
         (AppliedRecord
            (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))))
-> IO
     (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
-> m (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord
  (Param a :> (Param b :> (Param c :> (Param d :> Param e))))
-> IO
     (IORef
        (AppliedRecord
           (Param a :> (Param b :> (Param c :> (Param d :> Param e))))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord
  (Param a :> (Param b :> (Param c :> (Param d :> Param e))))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
-> (a -> b -> c -> d -> e -> r)
-> m (Mock
        (a -> b -> c -> d -> e -> r)
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord
     (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
s (\a
a2 b
b2 c
c2 d
d2 e
e2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a
    :> (Param b :> (Param c :> (Param d :> (Param e :> Param r))))]
-> (Param a :> (Param b :> (Param c :> (Param d :> Param e))))
-> IORef
     (AppliedRecord
        (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a
 :> (Param b :> (Param c :> (Param d :> (Param e :> Param r))))]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b :> (Param c :> (Param d :> Param e)))
-> Param a :> (Param b :> (Param c :> (Param d :> Param e)))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b
-> (Param c :> (Param d :> Param e))
-> Param b :> (Param c :> (Param d :> Param e))
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c -> (Param d :> Param e) -> Param c :> (Param d :> Param e)
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2 Param d -> Param e -> Param d :> Param e
forall a b. a -> b -> a :> b
:> e -> Param e
forall a. a -> Param a
p e
e2) IORef
  (AppliedRecord
     (Param a :> (Param b :> (Param c :> (Param d :> Param e)))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c, Show d, Eq d) =>
  MockBuilder
    [Param a :> Param b :> Param c :> Param d :> Param r]
    (a -> b -> c -> d -> r)
    (Param a :> Param b :> Param c :> Param d)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a :> (Param b :> (Param c :> (Param d :> Param r)))]
-> m (Mock
        (a -> b -> c -> d -> r)
        (Param a :> (Param b :> (Param c :> Param d))))
build Maybe String
name [Param a :> (Param b :> (Param c :> (Param d :> Param r)))]
params = do
    IORef
  (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
s <- IO
  (IORef
     (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
-> m (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO
   (IORef
      (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
 -> m (IORef
         (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))))
-> IO
     (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
-> m (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))
-> IO
     (IORef
        (AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a :> (Param b :> (Param c :> Param d)))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef
     (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
-> (a -> b -> c -> d -> r)
-> m (Mock
        (a -> b -> c -> d -> r)
        (Param a :> (Param b :> (Param c :> Param d))))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef
  (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
s (\a
a2 b
b2 c
c2 d
d2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a :> (Param b :> (Param c :> (Param d :> Param r)))]
-> (Param a :> (Param b :> (Param c :> Param d)))
-> IORef
     (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a :> (Param b :> (Param c :> (Param d :> Param r)))]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a
-> (Param b :> (Param c :> Param d))
-> Param a :> (Param b :> (Param c :> Param d))
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b -> (Param c :> Param d) -> Param b :> (Param c :> Param d)
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2 Param c -> Param d -> Param c :> Param d
forall a b. a -> b -> a :> b
:> d -> Param d
forall a. a -> Param a
p d
d2) IORef
  (AppliedRecord (Param a :> (Param b :> (Param c :> Param d))))
s)

instance
  (Show a, Eq a, Show b, Eq b, Show c, Eq c) =>
  MockBuilder
    [Param a :> Param b :> Param c :> Param r]
    (a -> b -> c -> r)
    (Param a :> Param b :> Param c)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a :> (Param b :> (Param c :> Param r))]
-> m (Mock (a -> b -> c -> r) (Param a :> (Param b :> Param c)))
build Maybe String
name [Param a :> (Param b :> (Param c :> Param r))]
params = do
    IORef (AppliedRecord (Param a :> (Param b :> Param c)))
s <- IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
-> m (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
 -> m (IORef (AppliedRecord (Param a :> (Param b :> Param c)))))
-> IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
-> m (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a :> (Param b :> Param c))
-> IO (IORef (AppliedRecord (Param a :> (Param b :> Param c))))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a :> (Param b :> Param c))
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef (AppliedRecord (Param a :> (Param b :> Param c)))
-> (a -> b -> c -> r)
-> m (Mock (a -> b -> c -> r) (Param a :> (Param b :> Param c)))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef (AppliedRecord (Param a :> (Param b :> Param c)))
s (\a
a2 b
b2 c
c2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a :> (Param b :> (Param c :> Param r))]
-> (Param a :> (Param b :> Param c))
-> IORef (AppliedRecord (Param a :> (Param b :> Param c)))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a :> (Param b :> (Param c :> Param r))]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a -> (Param b :> Param c) -> Param a :> (Param b :> Param c)
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2 Param b -> Param c -> Param b :> Param c
forall a b. a -> b -> a :> b
:> c -> Param c
forall a. a -> Param a
p c
c2) IORef (AppliedRecord (Param a :> (Param b :> Param c)))
s)

instance
  (Show a, Eq a, Show b, Eq b) =>
  MockBuilder [Param a :> Param b :> Param r] (a -> b -> r) (Param a :> Param b)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String
-> [Param a :> (Param b :> Param r)]
-> m (Mock (a -> b -> r) (Param a :> Param b))
build Maybe String
name [Param a :> (Param b :> Param r)]
params = do
    IORef (AppliedRecord (Param a :> Param b))
s <- IO (IORef (AppliedRecord (Param a :> Param b)))
-> m (IORef (AppliedRecord (Param a :> Param b)))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (AppliedRecord (Param a :> Param b)))
 -> m (IORef (AppliedRecord (Param a :> Param b))))
-> IO (IORef (AppliedRecord (Param a :> Param b)))
-> m (IORef (AppliedRecord (Param a :> Param b)))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a :> Param b)
-> IO (IORef (AppliedRecord (Param a :> Param b)))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a :> Param b)
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef (AppliedRecord (Param a :> Param b))
-> (a -> b -> r)
-> m (Mock (a -> b -> r) (Param a :> Param b))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef (AppliedRecord (Param a :> Param b))
s (\a
a2 b
b2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a :> (Param b :> Param r)]
-> (Param a :> Param b)
-> IORef (AppliedRecord (Param a :> Param b))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a :> (Param b :> Param r)]
params (a -> Param a
forall a. a -> Param a
p a
a2 Param a -> Param b -> Param a :> Param b
forall a b. a -> b -> a :> b
:> b -> Param b
forall a. a -> Param a
p b
b2) IORef (AppliedRecord (Param a :> Param b))
s)

instance
  (Show a, Eq a) =>
  MockBuilder [Param a :> Param r] (a -> r) (Param a)
  where
  build :: forall (m :: * -> *).
MonadIO m =>
Maybe String -> [Param a :> Param r] -> m (Mock (a -> r) (Param a))
build Maybe String
name [Param a :> Param r]
params = do
    IORef (AppliedRecord (Param a))
s <- IO (IORef (AppliedRecord (Param a)))
-> m (IORef (AppliedRecord (Param a)))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (AppliedRecord (Param a)))
 -> m (IORef (AppliedRecord (Param a))))
-> IO (IORef (AppliedRecord (Param a)))
-> m (IORef (AppliedRecord (Param a)))
forall a b. (a -> b) -> a -> b
$ AppliedRecord (Param a) -> IO (IORef (AppliedRecord (Param a)))
forall a. a -> IO (IORef a)
newIORef AppliedRecord (Param a)
forall params. AppliedRecord params
appliedRecord
    Maybe String
-> IORef (AppliedRecord (Param a))
-> (a -> r)
-> m (Mock (a -> r) (Param a))
forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef (AppliedRecord (Param a))
s (\a
a2 -> IO r -> r
forall a. IO a -> a
unsafePerformIO (IO r -> r) -> IO r -> r
forall a b. (a -> b) -> a -> b
$ Maybe String
-> [Param a :> Param r]
-> Param a
-> IORef (AppliedRecord (Param a))
-> IO r
forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name [Param a :> Param r]
params (a -> Param a
forall a. a -> Param a
p a
a2) IORef (AppliedRecord (Param a))
s)

-- ------

p :: a -> Param a
p :: forall a. a -> Param a
p = a -> Param a
forall a. a -> Param a
param

makeMock :: MonadIO m => Maybe MockName -> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock :: forall (m :: * -> *) params fun.
MonadIO m =>
Maybe String
-> IORef (AppliedRecord params) -> fun -> m (Mock fun params)
makeMock Maybe String
name IORef (AppliedRecord params)
l fun
fn = Mock fun params -> m (Mock fun params)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Mock fun params -> m (Mock fun params))
-> Mock fun params -> m (Mock fun params)
forall a b. (a -> b) -> a -> b
$ Maybe String -> fun -> Verifier params -> Mock fun params
forall fun params.
Maybe String -> fun -> Verifier params -> Mock fun params
Mock Maybe String
name fun
fn (IORef (AppliedRecord params) -> Verifier params
forall params. IORef (AppliedRecord params) -> Verifier params
Verifier IORef (AppliedRecord params)
l)

extractReturnValueWithValidate ::
  ParamDivider params args (Param r) =>
  Eq args =>
  Show args =>
  Maybe MockName ->
  params ->
  args ->
  IORef (AppliedRecord args) ->
  IO r
extractReturnValueWithValidate :: forall params args r.
(ParamDivider params args (Param r), Eq args, Show args) =>
Maybe String
-> params -> args -> IORef (AppliedRecord args) -> IO r
extractReturnValueWithValidate Maybe String
name params
params args
inputParams IORef (AppliedRecord args)
s = do
  Maybe String -> IORef (AppliedRecord args) -> args -> args -> IO ()
forall a.
(Eq a, Show a) =>
Maybe String -> IORef (AppliedRecord a) -> a -> a -> IO ()
validateWithStoreParams Maybe String
name IORef (AppliedRecord args)
s (params -> args
forall params args return.
ParamDivider params args return =>
params -> args
args params
params) args
inputParams
  r -> IO r
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (r -> IO r) -> r -> IO r
forall a b. (a -> b) -> a -> b
$ params -> r
forall params args r.
ParamDivider params args (Param r) =>
params -> r
returnValue params
params

findReturnValueWithStore ::
  Eq args =>
  Show args =>
  ParamDivider params args (Param r) =>
  Maybe MockName ->
  AppliedParamsList params ->
  args ->
  IORef (AppliedRecord args) ->
  IO r
findReturnValueWithStore :: forall args params r.
(Eq args, Show args, ParamDivider params args (Param r)) =>
Maybe String
-> AppliedParamsList params
-> args
-> IORef (AppliedRecord args)
-> IO r
findReturnValueWithStore Maybe String
name AppliedParamsList params
paramsList args
inputParams IORef (AppliedRecord args)
ref = do
  IORef (AppliedRecord args) -> args -> IO ()
forall params. IORef (AppliedRecord params) -> params -> IO ()
appendAppliedParams IORef (AppliedRecord args)
ref args
inputParams
  let expectedArgs :: [args]
expectedArgs = params -> args
forall params args return.
ParamDivider params args return =>
params -> args
args (params -> args) -> AppliedParamsList params -> [args]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AppliedParamsList params
paramsList
  Maybe r
r <- AppliedParamsList params
-> args -> IORef (AppliedRecord args) -> IO (Maybe r)
forall args params r.
(Eq args, ParamDivider params args (Param r)) =>
AppliedParamsList params
-> args -> IORef (AppliedRecord args) -> IO (Maybe r)
findReturnValue AppliedParamsList params
paramsList args
inputParams IORef (AppliedRecord args)
ref
  IO r -> (r -> IO r) -> Maybe r -> IO r
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
    (String -> IO r
forall a. String -> a
errorWithoutStackTrace (String -> IO r) -> String -> IO r
forall a b. (a -> b) -> a -> b
$ Maybe String -> [args] -> args -> String
forall a. Show a => Maybe String -> [a] -> a -> String
messageForMultiMock Maybe String
name [args]
expectedArgs args
inputParams)
    r -> IO r
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    Maybe r
r

findReturnValue ::
  Eq args =>
  ParamDivider params args (Param r) =>
  AppliedParamsList params ->
  args ->
  IORef (AppliedRecord args) ->
  IO (Maybe r)
findReturnValue :: forall args params r.
(Eq args, ParamDivider params args (Param r)) =>
AppliedParamsList params
-> args -> IORef (AppliedRecord args) -> IO (Maybe r)
findReturnValue AppliedParamsList params
paramsList args
inputParams IORef (AppliedRecord args)
ref = do
  let matchedParams :: AppliedParamsList params
matchedParams = (params -> Bool)
-> AppliedParamsList params -> AppliedParamsList params
forall a. (a -> Bool) -> [a] -> [a]
filter (\params
params -> params -> args
forall params args return.
ParamDivider params args return =>
params -> args
args params
params args -> args -> Bool
forall a. Eq a => a -> a -> Bool
== args
inputParams) AppliedParamsList params
paramsList
  case AppliedParamsList params
matchedParams of
    [] -> Maybe r -> IO (Maybe r)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe r
forall a. Maybe a
Nothing
    AppliedParamsList params
_ -> do
      Int
count <- IORef (AppliedRecord args) -> args -> IO Int
forall params.
Eq params =>
IORef (AppliedRecord params) -> params -> IO Int
readAppliedCount IORef (AppliedRecord args)
ref args
inputParams
      let index :: Int
index = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
count (AppliedParamsList params -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList params
matchedParams Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
      IORef (AppliedRecord args) -> args -> IO ()
forall params.
Eq params =>
IORef (AppliedRecord params) -> params -> IO ()
incrementAppliedParamCount IORef (AppliedRecord args)
ref args
inputParams
      Maybe r -> IO (Maybe r)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe r -> IO (Maybe r)) -> Maybe r -> IO (Maybe r)
forall a b. (a -> b) -> a -> b
$ params -> r
forall params args r.
ParamDivider params args (Param r) =>
params -> r
returnValue (params -> r) -> Maybe params -> Maybe r
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AppliedParamsList params -> Int -> Maybe params
forall a. [a] -> Int -> Maybe a
safeIndex AppliedParamsList params
matchedParams Int
index

validateWithStoreParams :: (Eq a, Show a) => Maybe MockName -> IORef (AppliedRecord a) -> a -> a -> IO ()
validateWithStoreParams :: forall a.
(Eq a, Show a) =>
Maybe String -> IORef (AppliedRecord a) -> a -> a -> IO ()
validateWithStoreParams Maybe String
name IORef (AppliedRecord a)
ref a
expected a
actual = do
  Maybe String -> a -> a -> IO ()
forall a. (Eq a, Show a) => Maybe String -> a -> a -> IO ()
validateParams Maybe String
name a
expected a
actual
  IORef (AppliedRecord a) -> a -> IO ()
forall params. IORef (AppliedRecord params) -> params -> IO ()
appendAppliedParams IORef (AppliedRecord a)
ref a
actual

validateParams :: (Eq a, Show a) => Maybe MockName -> a -> a -> IO ()
validateParams :: forall a. (Eq a, Show a) => Maybe String -> a -> a -> IO ()
validateParams Maybe String
name a
expected a
actual =
  if a
expected a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
actual
    then () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    else String -> IO ()
forall a. String -> a
errorWithoutStackTrace (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Maybe String -> a -> a -> String
forall a. Show a => Maybe String -> a -> a -> String
message Maybe String
name a
expected a
actual

message :: Show a => Maybe MockName -> a -> a -> String
message :: forall a. Show a => Maybe String -> a -> a -> String
message Maybe String
name a
expected a
actual =
  String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
    String
"\n"
    [ String
"Expected arguments were not applied to the function" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe String -> String
mockNameLabel Maybe String
name String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
".",
      String
"  expected: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
expected,
      String
"   but got: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
actual
    ]

messageForMultiMock :: Show a => Maybe MockName -> [a] -> a -> String
messageForMultiMock :: forall a. Show a => Maybe String -> [a] -> a -> String
messageForMultiMock Maybe String
name [a]
expecteds a
actual =
  String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
    String
"\n"
    [ String
"Expected arguments were not applied to the function" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe String -> String
mockNameLabel Maybe String
name String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
".",
      String
"  expected one of the following:",
      String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String
"    " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show (a -> String) -> [a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
expecteds,
      String
"  but got:",
      (String
"    " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show (a -> String) -> a -> String
forall a b. (a -> b) -> a -> b
$ a
actual
    ]

mockNameLabel :: Maybe MockName -> String
mockNameLabel :: Maybe String -> String
mockNameLabel = String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
forall a. Monoid a => a
mempty (String
" " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (Maybe String -> String)
-> (Maybe String -> Maybe String) -> Maybe String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe String -> Maybe String
enclose String
"`"

enclose :: String -> Maybe String -> Maybe String
enclose :: String -> Maybe String -> Maybe String
enclose String
e = (String -> String) -> Maybe String -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\String
v -> String
e String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
v String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
e)

-- verify
data VerifyMatchType a = MatchAny a | MatchAll a

-- | Class for verifying mock function.
class Verify params input where
  -- | Verifies that the function has been applied to the expected arguments.
  shouldApplyTo :: Mock fun params -> input -> IO ()

instance (Eq a, Show a) => Verify (Param a) a where
  shouldApplyTo :: forall fun. Mock fun (Param a) -> a -> IO ()
shouldApplyTo Mock fun (Param a)
v a
a = Mock fun (Param a) -> VerifyMatchType (Param a) -> IO ()
forall params fun.
(Eq params, Show params) =>
Mock fun params -> VerifyMatchType params -> IO ()
verify Mock fun (Param a)
v (Param a -> VerifyMatchType (Param a)
forall a. a -> VerifyMatchType a
MatchAny (a -> Param a
forall a. a -> Param a
param a
a))

instance (Eq a, Show a) => Verify a a where
  shouldApplyTo :: forall fun. Mock fun a -> a -> IO ()
shouldApplyTo Mock fun a
v a
a = Mock fun a -> VerifyMatchType a -> IO ()
forall params fun.
(Eq params, Show params) =>
Mock fun params -> VerifyMatchType params -> IO ()
verify Mock fun a
v (a -> VerifyMatchType a
forall a. a -> VerifyMatchType a
MatchAny a
a)

verify :: (Eq params, Show params) => Mock fun params -> VerifyMatchType params -> IO ()
verify :: forall params fun.
(Eq params, Show params) =>
Mock fun params -> VerifyMatchType params -> IO ()
verify (Mock Maybe String
name fun
_ (Verifier IORef (AppliedRecord params)
ref)) VerifyMatchType params
matchType = do
  AppliedParamsList params
calledParamsList <- IORef (AppliedRecord params) -> IO (AppliedParamsList params)
forall params.
IORef (AppliedRecord params) -> IO (AppliedParamsList params)
readAppliedParamsList IORef (AppliedRecord params)
ref
  let result :: Maybe VerifyFailed
result = Maybe String
-> AppliedParamsList params
-> VerifyMatchType params
-> Maybe VerifyFailed
forall a.
(Eq a, Show a) =>
Maybe String
-> AppliedParamsList a -> VerifyMatchType a -> Maybe VerifyFailed
doVerify Maybe String
name AppliedParamsList params
calledParamsList VerifyMatchType params
matchType
  Maybe VerifyFailed
result Maybe VerifyFailed -> (Maybe VerifyFailed -> IO ()) -> IO ()
forall a b. a -> (a -> b) -> b
& IO () -> (VerifyFailed -> IO ()) -> Maybe VerifyFailed -> IO ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (\(VerifyFailed String
msg) -> String -> IO ()
forall a. String -> a
errorWithoutStackTrace String
msg)

newtype VerifyFailed = VerifyFailed Message

type Message = String

doVerify :: (Eq a, Show a) => Maybe MockName -> AppliedParamsList a -> VerifyMatchType a -> Maybe VerifyFailed
doVerify :: forall a.
(Eq a, Show a) =>
Maybe String
-> AppliedParamsList a -> VerifyMatchType a -> Maybe VerifyFailed
doVerify Maybe String
name AppliedParamsList a
list (MatchAny a
a) = do
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ a -> AppliedParamsList a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
notElem a
a AppliedParamsList a
list
  VerifyFailed -> Maybe VerifyFailed
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VerifyFailed -> Maybe VerifyFailed)
-> VerifyFailed -> Maybe VerifyFailed
forall a b. (a -> b) -> a -> b
$ Maybe String -> AppliedParamsList a -> a -> VerifyFailed
forall a.
Show a =>
Maybe String -> AppliedParamsList a -> a -> VerifyFailed
verifyFailedMesssage Maybe String
name AppliedParamsList a
list a
a
doVerify Maybe String
name AppliedParamsList a
list (MatchAll a
a) = do
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> AppliedParamsList a -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
Prelude.any (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/=) AppliedParamsList a
list
  VerifyFailed -> Maybe VerifyFailed
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VerifyFailed -> Maybe VerifyFailed)
-> VerifyFailed -> Maybe VerifyFailed
forall a b. (a -> b) -> a -> b
$ Maybe String -> AppliedParamsList a -> a -> VerifyFailed
forall a.
Show a =>
Maybe String -> AppliedParamsList a -> a -> VerifyFailed
verifyFailedMesssage Maybe String
name AppliedParamsList a
list a
a

verifyFailedMesssage :: Show a => Maybe MockName -> AppliedParamsList a -> a -> VerifyFailed
verifyFailedMesssage :: forall a.
Show a =>
Maybe String -> AppliedParamsList a -> a -> VerifyFailed
verifyFailedMesssage Maybe String
name AppliedParamsList a
calledParams a
expected =
  String -> VerifyFailed
VerifyFailed (String -> VerifyFailed) -> String -> VerifyFailed
forall a b. (a -> b) -> a -> b
$
    String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
      String
"\n"
      [ String
"Expected arguments were not applied to the function" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe String -> String
mockNameLabel Maybe String
name String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
".",
        String
"  expected: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
expected,
        String
"   but got: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> AppliedParamsList a -> String
forall a. Show a => AppliedParamsList a -> String
formatCalledParamsList AppliedParamsList a
calledParams
      ]

formatCalledParamsList :: Show a => AppliedParamsList a -> String
formatCalledParamsList :: forall a. Show a => AppliedParamsList a -> String
formatCalledParamsList AppliedParamsList a
calledParams
  | AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
calledParams Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = String
"Never been called."
  | AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
calledParams Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = String -> String
forall a. HasCallStack => [a] -> [a]
init (String -> String)
-> (AppliedParamsList a -> String) -> AppliedParamsList a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
1 (String -> String)
-> (AppliedParamsList a -> String) -> AppliedParamsList a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AppliedParamsList a -> String
forall a. Show a => a -> String
show (AppliedParamsList a -> String) -> AppliedParamsList a -> String
forall a b. (a -> b) -> a -> b
$ AppliedParamsList a
calledParams
  | Bool
otherwise = AppliedParamsList a -> String
forall a. Show a => a -> String
show AppliedParamsList a
calledParams

_replace :: Show a => String -> a -> String
_replace :: forall a. Show a => String -> a -> String
_replace String
r a
s = Text -> String
unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
replace (String -> Text
pack String
r) (String -> Text
pack String
"") (String -> Text
pack (a -> String
forall a. Show a => a -> String
show a
s))

class VerifyCount countType params a where
  -- | Verify the number of times a function has been applied to an argument.
  --
  -- @
  -- import Test.Hspec
  -- import Test.MockCat
  -- ...
  -- it "verify to applied times." do
  --   m \<- createMock $ "value" |\> True
  --   print $ stubFn m "value"
  --   print $ stubFn m "value"
  --   m \`shouldApplyTimes\` (2 :: Int) \`to\` "value" 
  -- @
  --
  shouldApplyTimes :: Eq params => Mock fun params -> countType -> a -> IO ()

instance VerifyCount CountVerifyMethod (Param a) a where
  shouldApplyTimes :: forall fun.
Eq (Param a) =>
Mock fun (Param a) -> CountVerifyMethod -> a -> IO ()
shouldApplyTimes Mock fun (Param a)
v CountVerifyMethod
count a
a = Mock fun (Param a) -> Param a -> CountVerifyMethod -> IO ()
forall params fun.
Eq params =>
Mock fun params -> params -> CountVerifyMethod -> IO ()
verifyCount Mock fun (Param a)
v (a -> Param a
forall a. a -> Param a
param a
a) CountVerifyMethod
count

instance VerifyCount Int (Param a) a where
  shouldApplyTimes :: forall fun. Eq (Param a) => Mock fun (Param a) -> Int -> a -> IO ()
shouldApplyTimes Mock fun (Param a)
v Int
count a
a = Mock fun (Param a) -> Param a -> CountVerifyMethod -> IO ()
forall params fun.
Eq params =>
Mock fun params -> params -> CountVerifyMethod -> IO ()
verifyCount Mock fun (Param a)
v (a -> Param a
forall a. a -> Param a
param a
a) (Int -> CountVerifyMethod
Equal Int
count)

instance {-# OVERLAPPABLE #-} VerifyCount CountVerifyMethod a a where
  shouldApplyTimes :: forall fun. Eq a => Mock fun a -> CountVerifyMethod -> a -> IO ()
shouldApplyTimes Mock fun a
v CountVerifyMethod
count a
a = Mock fun a -> a -> CountVerifyMethod -> IO ()
forall params fun.
Eq params =>
Mock fun params -> params -> CountVerifyMethod -> IO ()
verifyCount Mock fun a
v a
a CountVerifyMethod
count

instance {-# OVERLAPPABLE #-} VerifyCount Int a a where
  shouldApplyTimes :: forall fun. Eq a => Mock fun a -> Int -> a -> IO ()
shouldApplyTimes Mock fun a
v Int
count a
a = Mock fun a -> a -> CountVerifyMethod -> IO ()
forall params fun.
Eq params =>
Mock fun params -> params -> CountVerifyMethod -> IO ()
verifyCount Mock fun a
v a
a (Int -> CountVerifyMethod
Equal Int
count)

data CountVerifyMethod
  = Equal Int
  | LessThanEqual Int
  | GreaterThanEqual Int
  | LessThan Int
  | GreaterThan Int

instance Show CountVerifyMethod where
  show :: CountVerifyMethod -> String
show (Equal Int
e) = Int -> String
forall a. Show a => a -> String
show Int
e
  show (LessThanEqual Int
e) = String
"<= " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
e
  show (LessThan Int
e) = String
"< " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
e
  show (GreaterThanEqual Int
e) = String
">= " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
e
  show (GreaterThan Int
e) = String
"> " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
e

compareCount :: CountVerifyMethod -> Int -> Bool
compareCount :: CountVerifyMethod -> Int -> Bool
compareCount (Equal Int
e) Int
a = Int
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e
compareCount (LessThanEqual Int
e) Int
a = Int
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
e
compareCount (LessThan Int
e) Int
a = Int
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
e
compareCount (GreaterThanEqual Int
e) Int
a = Int
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
e
compareCount (GreaterThan Int
e) Int
a = Int
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
e

verifyCount :: Eq params => Mock fun params -> params -> CountVerifyMethod -> IO ()
verifyCount :: forall params fun.
Eq params =>
Mock fun params -> params -> CountVerifyMethod -> IO ()
verifyCount (Mock Maybe String
name fun
_ (Verifier IORef (AppliedRecord params)
ref)) params
v CountVerifyMethod
method = do
  AppliedParamsList params
calledParamsList <- IORef (AppliedRecord params) -> IO (AppliedParamsList params)
forall params.
IORef (AppliedRecord params) -> IO (AppliedParamsList params)
readAppliedParamsList IORef (AppliedRecord params)
ref
  let callCount :: Int
callCount = AppliedParamsList params -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((params -> Bool)
-> AppliedParamsList params -> AppliedParamsList params
forall a. (a -> Bool) -> [a] -> [a]
filter (params
v params -> params -> Bool
forall a. Eq a => a -> a -> Bool
==) AppliedParamsList params
calledParamsList)
  if CountVerifyMethod -> Int -> Bool
compareCount CountVerifyMethod
method Int
callCount
    then () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    else
      String -> IO ()
forall a. String -> a
errorWithoutStackTrace (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
        String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
          String
"\n"
          [ String
"The expected argument was not applied the expected number of times to the function" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe String -> String
mockNameLabel Maybe String
name String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
".",
            String
"  expected: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> CountVerifyMethod -> String
forall a. Show a => a -> String
show CountVerifyMethod
method,
            String
"   but got: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
callCount
          ]

to :: (a -> IO ()) -> a -> IO ()
to :: forall a. (a -> IO ()) -> a -> IO ()
to a -> IO ()
f = a -> IO ()
f

class VerifyOrder params input where
  -- | Verify functions are applied in the expected order.
  --
  -- @
  -- import Test.Hspec
  -- import Test.MockCat
  -- import Prelude hiding (any)
  -- ...
  -- it "verify order of apply" do
  --   m \<- createMock $ any |\> True |\> ()
  --   print $ stubFn m "a" True
  --   print $ stubFn m "b" True
  --   m \`shouldApplyInOrder\` ["a" |\> True, "b" |\> True]
  -- @
  shouldApplyInOrder :: Mock fun params -> [input] -> IO ()

  -- | Verify that functions are applied in the expected order.
  --
  -- Unlike @'shouldApplyInOrder'@, not all applications need to match exactly.
  --
  -- As long as the order matches, the verification succeeds.
  shouldApplyInPartialOrder :: Mock fun params -> [input] -> IO ()

instance (Eq a, Show a) => VerifyOrder (Param a) a where
  shouldApplyInOrder :: forall fun. Mock fun (Param a) -> [a] -> IO ()
shouldApplyInOrder Mock fun (Param a)
v [a]
a = VerifyOrderMethod -> Mock fun (Param a) -> [Param a] -> IO ()
forall params fun.
(Eq params, Show params) =>
VerifyOrderMethod -> Mock fun params -> [params] -> IO ()
verifyOrder VerifyOrderMethod
ExactlySequence Mock fun (Param a)
v ([Param a] -> IO ()) -> [Param a] -> IO ()
forall a b. (a -> b) -> a -> b
$ a -> Param a
forall a. a -> Param a
param (a -> Param a) -> [a] -> [Param a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
a
  shouldApplyInPartialOrder :: forall fun. Mock fun (Param a) -> [a] -> IO ()
shouldApplyInPartialOrder Mock fun (Param a)
v [a]
a = VerifyOrderMethod -> Mock fun (Param a) -> [Param a] -> IO ()
forall params fun.
(Eq params, Show params) =>
VerifyOrderMethod -> Mock fun params -> [params] -> IO ()
verifyOrder VerifyOrderMethod
PartiallySequence Mock fun (Param a)
v ([Param a] -> IO ()) -> [Param a] -> IO ()
forall a b. (a -> b) -> a -> b
$ a -> Param a
forall a. a -> Param a
param (a -> Param a) -> [a] -> [Param a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
a

instance {-# OVERLAPPABLE #-} (Eq a, Show a) => VerifyOrder a a where
  shouldApplyInOrder :: forall fun. Mock fun a -> [a] -> IO ()
shouldApplyInOrder = VerifyOrderMethod -> Mock fun a -> [a] -> IO ()
forall params fun.
(Eq params, Show params) =>
VerifyOrderMethod -> Mock fun params -> [params] -> IO ()
verifyOrder VerifyOrderMethod
ExactlySequence
  shouldApplyInPartialOrder :: forall fun. Mock fun a -> [a] -> IO ()
shouldApplyInPartialOrder = VerifyOrderMethod -> Mock fun a -> [a] -> IO ()
forall params fun.
(Eq params, Show params) =>
VerifyOrderMethod -> Mock fun params -> [params] -> IO ()
verifyOrder VerifyOrderMethod
PartiallySequence

data VerifyOrderMethod
  = ExactlySequence
  | PartiallySequence

verifyOrder ::
  Eq params =>
  Show params =>
  VerifyOrderMethod ->
  Mock fun params ->
  [params] ->
  IO ()
verifyOrder :: forall params fun.
(Eq params, Show params) =>
VerifyOrderMethod -> Mock fun params -> [params] -> IO ()
verifyOrder VerifyOrderMethod
method (Mock Maybe String
name fun
_ (Verifier IORef (AppliedRecord params)
ref)) [params]
matchers = do
  [params]
calledParamsList <- IORef (AppliedRecord params) -> IO [params]
forall params.
IORef (AppliedRecord params) -> IO (AppliedParamsList params)
readAppliedParamsList IORef (AppliedRecord params)
ref
  let result :: Maybe VerifyFailed
result = VerifyOrderMethod
-> Maybe String -> [params] -> [params] -> Maybe VerifyFailed
forall a.
(Eq a, Show a) =>
VerifyOrderMethod
-> Maybe String
-> AppliedParamsList a
-> AppliedParamsList a
-> Maybe VerifyFailed
doVerifyOrder VerifyOrderMethod
method Maybe String
name [params]
calledParamsList [params]
matchers
  Maybe VerifyFailed
result Maybe VerifyFailed -> (Maybe VerifyFailed -> IO ()) -> IO ()
forall a b. a -> (a -> b) -> b
& IO () -> (VerifyFailed -> IO ()) -> Maybe VerifyFailed -> IO ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (\(VerifyFailed String
msg) -> String -> IO ()
forall a. String -> a
errorWithoutStackTrace String
msg)

doVerifyOrder ::
  Eq a =>
  Show a =>
  VerifyOrderMethod ->
  Maybe MockName ->
  AppliedParamsList a ->
  [a] ->
  Maybe VerifyFailed
doVerifyOrder :: forall a.
(Eq a, Show a) =>
VerifyOrderMethod
-> Maybe String
-> AppliedParamsList a
-> AppliedParamsList a
-> Maybe VerifyFailed
doVerifyOrder VerifyOrderMethod
ExactlySequence Maybe String
name AppliedParamsList a
calledValues AppliedParamsList a
expectedValues
  | AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
calledValues Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
expectedValues = do
      VerifyFailed -> Maybe VerifyFailed
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VerifyFailed -> Maybe VerifyFailed)
-> VerifyFailed -> Maybe VerifyFailed
forall a b. (a -> b) -> a -> b
$ Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
forall a.
Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
verifyFailedOrderParamCountMismatch Maybe String
name AppliedParamsList a
calledValues AppliedParamsList a
expectedValues
  | Bool
otherwise = do
      let unexpectedOrders :: [VerifyOrderResult a]
unexpectedOrders = AppliedParamsList a -> AppliedParamsList a -> [VerifyOrderResult a]
forall a.
Eq a =>
AppliedParamsList a -> AppliedParamsList a -> [VerifyOrderResult a]
collectUnExpectedOrder AppliedParamsList a
calledValues AppliedParamsList a
expectedValues
      Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ [VerifyOrderResult a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [VerifyOrderResult a]
unexpectedOrders Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
      VerifyFailed -> Maybe VerifyFailed
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VerifyFailed -> Maybe VerifyFailed)
-> VerifyFailed -> Maybe VerifyFailed
forall a b. (a -> b) -> a -> b
$ Maybe String -> [VerifyOrderResult a] -> VerifyFailed
forall a.
Show a =>
Maybe String -> [VerifyOrderResult a] -> VerifyFailed
verifyFailedSequence Maybe String
name [VerifyOrderResult a]
unexpectedOrders
doVerifyOrder VerifyOrderMethod
PartiallySequence Maybe String
name AppliedParamsList a
calledValues AppliedParamsList a
expectedValues
  | AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
calledValues Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
expectedValues = do
      VerifyFailed -> Maybe VerifyFailed
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VerifyFailed -> Maybe VerifyFailed)
-> VerifyFailed -> Maybe VerifyFailed
forall a b. (a -> b) -> a -> b
$ Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
forall a.
Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
verifyFailedOrderParamCountMismatch Maybe String
name AppliedParamsList a
calledValues AppliedParamsList a
expectedValues
  | Bool
otherwise = do
      Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ AppliedParamsList a -> AppliedParamsList a -> Bool
forall a.
Eq a =>
AppliedParamsList a -> AppliedParamsList a -> Bool
isOrderNotMatched AppliedParamsList a
calledValues AppliedParamsList a
expectedValues
      VerifyFailed -> Maybe VerifyFailed
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VerifyFailed -> Maybe VerifyFailed)
-> VerifyFailed -> Maybe VerifyFailed
forall a b. (a -> b) -> a -> b
$ Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
forall a.
Show a =>
Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
verifyFailedPartiallySequence Maybe String
name AppliedParamsList a
calledValues AppliedParamsList a
expectedValues

verifyFailedPartiallySequence :: Show a => Maybe MockName -> AppliedParamsList a -> [a] -> VerifyFailed
verifyFailedPartiallySequence :: forall a.
Show a =>
Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
verifyFailedPartiallySequence Maybe String
name AppliedParamsList a
calledValues AppliedParamsList a
expectedValues =
  String -> VerifyFailed
VerifyFailed (String -> VerifyFailed) -> String -> VerifyFailed
forall a b. (a -> b) -> a -> b
$
    String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
      String
"\n"
      [ String
"Expected arguments were not applied to the function" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe String -> String
mockNameLabel Maybe String
name String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" in the expected order.",
        String
"  expected order:",
        String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String
"    " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show (a -> String) -> AppliedParamsList a -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AppliedParamsList a
expectedValues,
        String
"  but got:",
        String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String
"    " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show (a -> String) -> AppliedParamsList a -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AppliedParamsList a
calledValues
      ]

isOrderNotMatched :: Eq a => AppliedParamsList a -> [a] -> Bool
isOrderNotMatched :: forall a.
Eq a =>
AppliedParamsList a -> AppliedParamsList a -> Bool
isOrderNotMatched AppliedParamsList a
calledValues AppliedParamsList a
expectedValues =
  Maybe (AppliedParamsList a) -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe (AppliedParamsList a) -> Bool)
-> Maybe (AppliedParamsList a) -> Bool
forall a b. (a -> b) -> a -> b
$
    (Maybe (AppliedParamsList a) -> a -> Maybe (AppliedParamsList a))
-> Maybe (AppliedParamsList a)
-> AppliedParamsList a
-> Maybe (AppliedParamsList a)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl
      ( \Maybe (AppliedParamsList a)
candidates a
e -> do
          Maybe (AppliedParamsList a)
candidates Maybe (AppliedParamsList a)
-> (AppliedParamsList a -> Maybe (AppliedParamsList a))
-> Maybe (AppliedParamsList a)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \AppliedParamsList a
c -> do
            Int
index <- a -> AppliedParamsList a -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex a
e AppliedParamsList a
c
            AppliedParamsList a -> Maybe (AppliedParamsList a)
forall a. a -> Maybe a
Just (AppliedParamsList a -> Maybe (AppliedParamsList a))
-> AppliedParamsList a -> Maybe (AppliedParamsList a)
forall a b. (a -> b) -> a -> b
$ Int -> AppliedParamsList a -> AppliedParamsList a
forall a. Int -> [a] -> [a]
drop (Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) AppliedParamsList a
c
      )
      (AppliedParamsList a -> Maybe (AppliedParamsList a)
forall a. a -> Maybe a
Just AppliedParamsList a
calledValues)
      AppliedParamsList a
expectedValues

verifyFailedOrderParamCountMismatch :: Maybe MockName -> AppliedParamsList a -> [a] -> VerifyFailed
verifyFailedOrderParamCountMismatch :: forall a.
Maybe String
-> AppliedParamsList a -> AppliedParamsList a -> VerifyFailed
verifyFailedOrderParamCountMismatch Maybe String
name AppliedParamsList a
calledValues AppliedParamsList a
expectedValues =
  String -> VerifyFailed
VerifyFailed (String -> VerifyFailed) -> String -> VerifyFailed
forall a b. (a -> b) -> a -> b
$
    String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
      String
"\n"
      [ String
"Expected arguments were not applied to the function" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe String -> String
mockNameLabel Maybe String
name String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" in the expected order (count mismatch).",
        String
"  expected: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show (AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
expectedValues),
        String
"   but got: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show (AppliedParamsList a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length AppliedParamsList a
calledValues)
      ]

verifyFailedSequence :: Show a => Maybe MockName -> [VerifyOrderResult a] -> VerifyFailed
verifyFailedSequence :: forall a.
Show a =>
Maybe String -> [VerifyOrderResult a] -> VerifyFailed
verifyFailedSequence Maybe String
name [VerifyOrderResult a]
fails =
  String -> VerifyFailed
VerifyFailed (String -> VerifyFailed) -> String -> VerifyFailed
forall a b. (a -> b) -> a -> b
$
    String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
      String
"\n"
      ( (String
"Expected arguments were not applied to the function" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe String -> String
mockNameLabel Maybe String
name String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" in the expected order.") String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (VerifyOrderResult a -> String
forall a. Show a => VerifyOrderResult a -> String
verifyOrderFailedMesssage (VerifyOrderResult a -> String)
-> [VerifyOrderResult a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VerifyOrderResult a]
fails)
      )

verifyOrderFailedMesssage :: Show a => VerifyOrderResult a -> String
verifyOrderFailedMesssage :: forall a. Show a => VerifyOrderResult a -> String
verifyOrderFailedMesssage VerifyOrderResult {Int
index :: Int
index :: forall a. VerifyOrderResult a -> Int
index, a
calledValue :: a
calledValue :: forall a. VerifyOrderResult a -> a
calledValue, a
expectedValue :: a
expectedValue :: forall a. VerifyOrderResult a -> a
expectedValue} =
  let callCount :: String
callCount = Int -> String
showHumanReadable (Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
   in String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
        String
"\n"
        [ String
"  expected " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
callCount String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" applied: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
expectedValue,
          String
"   but got " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
callCount String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" applied: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
calledValue
        ]
  where
    showHumanReadable :: Int -> String
    showHumanReadable :: Int -> String
showHumanReadable Int
1 = String
"1st"
    showHumanReadable Int
2 = String
"2nd"
    showHumanReadable Int
3 = String
"3rd"
    showHumanReadable Int
n = Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"th"

data VerifyOrderResult a = VerifyOrderResult
  { forall a. VerifyOrderResult a -> Int
index :: Int,
    forall a. VerifyOrderResult a -> a
calledValue :: a,
    forall a. VerifyOrderResult a -> a
expectedValue :: a
  }

collectUnExpectedOrder :: Eq a => AppliedParamsList a -> [a] -> [VerifyOrderResult a]
collectUnExpectedOrder :: forall a.
Eq a =>
AppliedParamsList a -> AppliedParamsList a -> [VerifyOrderResult a]
collectUnExpectedOrder AppliedParamsList a
calledValues AppliedParamsList a
expectedValues =
  [Maybe (VerifyOrderResult a)] -> [VerifyOrderResult a]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (VerifyOrderResult a)] -> [VerifyOrderResult a])
-> [Maybe (VerifyOrderResult a)] -> [VerifyOrderResult a]
forall a b. (a -> b) -> a -> b
$
    (Int -> a -> Maybe (VerifyOrderResult a))
-> AppliedParamsList a -> [Maybe (VerifyOrderResult a)]
forall a b. (Int -> a -> b) -> [a] -> [b]
mapWithIndex
      ( \Int
i a
expectedValue -> do
          let calledValue :: a
calledValue = AppliedParamsList a
calledValues AppliedParamsList a -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!! Int
i
          Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ a
expectedValue a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
calledValue
          VerifyOrderResult a -> Maybe (VerifyOrderResult a)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure VerifyOrderResult {index :: Int
index = Int
i, a
calledValue :: a
calledValue :: a
calledValue, a
expectedValue :: a
expectedValue :: a
expectedValue}
      )
      AppliedParamsList a
expectedValues

mapWithIndex :: (Int -> a -> b) -> [a] -> [b]
mapWithIndex :: forall a b. (Int -> a -> b) -> [a] -> [b]
mapWithIndex Int -> a -> b
f [a]
xs = [Int -> a -> b
f Int
i a
x | (Int
i, a
x) <- [Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] [a]
xs]

shouldApplyTimesGreaterThanEqual ::
  VerifyCount CountVerifyMethod params a =>
  Eq params =>
  Mock fun params ->
  Int ->
  a ->
  IO ()
shouldApplyTimesGreaterThanEqual :: forall params a fun.
(VerifyCount CountVerifyMethod params a, Eq params) =>
Mock fun params -> Int -> a -> IO ()
shouldApplyTimesGreaterThanEqual Mock fun params
m Int
i = Mock fun params -> CountVerifyMethod -> a -> IO ()
forall fun.
Eq params =>
Mock fun params -> CountVerifyMethod -> a -> IO ()
forall countType params a fun.
(VerifyCount countType params a, Eq params) =>
Mock fun params -> countType -> a -> IO ()
shouldApplyTimes Mock fun params
m (Int -> CountVerifyMethod
GreaterThanEqual Int
i)

shouldApplyTimesLessThanEqual ::
  VerifyCount CountVerifyMethod params a =>
  Eq params =>
  Mock fun params ->
  Int ->
  a ->
  IO ()
shouldApplyTimesLessThanEqual :: forall params a fun.
(VerifyCount CountVerifyMethod params a, Eq params) =>
Mock fun params -> Int -> a -> IO ()
shouldApplyTimesLessThanEqual Mock fun params
m Int
i = Mock fun params -> CountVerifyMethod -> a -> IO ()
forall fun.
Eq params =>
Mock fun params -> CountVerifyMethod -> a -> IO ()
forall countType params a fun.
(VerifyCount countType params a, Eq params) =>
Mock fun params -> countType -> a -> IO ()
shouldApplyTimes Mock fun params
m (Int -> CountVerifyMethod
LessThanEqual Int
i)

shouldApplyTimesGreaterThan ::
  VerifyCount CountVerifyMethod params a =>
  Eq params =>
  Mock fun params ->
  Int ->
  a ->
  IO ()
shouldApplyTimesGreaterThan :: forall params a fun.
(VerifyCount CountVerifyMethod params a, Eq params) =>
Mock fun params -> Int -> a -> IO ()
shouldApplyTimesGreaterThan Mock fun params
m Int
i = Mock fun params -> CountVerifyMethod -> a -> IO ()
forall fun.
Eq params =>
Mock fun params -> CountVerifyMethod -> a -> IO ()
forall countType params a fun.
(VerifyCount countType params a, Eq params) =>
Mock fun params -> countType -> a -> IO ()
shouldApplyTimes Mock fun params
m (Int -> CountVerifyMethod
GreaterThan Int
i)

shouldApplyTimesLessThan ::
  VerifyCount CountVerifyMethod params a =>
  Eq params =>
  Mock fun params ->
  Int ->
  a ->
  IO ()
shouldApplyTimesLessThan :: forall params a fun.
(VerifyCount CountVerifyMethod params a, Eq params) =>
Mock fun params -> Int -> a -> IO ()
shouldApplyTimesLessThan Mock fun params
m Int
i = Mock fun params -> CountVerifyMethod -> a -> IO ()
forall fun.
Eq params =>
Mock fun params -> CountVerifyMethod -> a -> IO ()
forall countType params a fun.
(VerifyCount countType params a, Eq params) =>
Mock fun params -> countType -> a -> IO ()
shouldApplyTimes Mock fun params
m (Int -> CountVerifyMethod
LessThan Int
i)



type AppliedParamsList params = [params]
type AppliedParamsCounter params = AssociationList params Int

data AppliedRecord params = AppliedRecord {
  forall params. AppliedRecord params -> AppliedParamsList params
appliedParamsList :: AppliedParamsList params,
  forall params. AppliedRecord params -> AppliedParamsCounter params
appliedParamsCounter :: AppliedParamsCounter params
}

appliedRecord :: AppliedRecord params
appliedRecord :: forall params. AppliedRecord params
appliedRecord = AppliedRecord {
  appliedParamsList :: AppliedParamsList params
appliedParamsList = AppliedParamsList params
forall a. Monoid a => a
mempty,
  appliedParamsCounter :: AppliedParamsCounter params
appliedParamsCounter = AppliedParamsCounter params
forall k a. AssociationList k a
empty
}

readAppliedParamsList :: IORef (AppliedRecord params) -> IO (AppliedParamsList params)
readAppliedParamsList :: forall params.
IORef (AppliedRecord params) -> IO (AppliedParamsList params)
readAppliedParamsList IORef (AppliedRecord params)
ref = do
  AppliedRecord params
record <- IORef (AppliedRecord params) -> IO (AppliedRecord params)
forall a. IORef a -> IO a
readIORef IORef (AppliedRecord params)
ref
  AppliedParamsList params -> IO (AppliedParamsList params)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AppliedParamsList params -> IO (AppliedParamsList params))
-> AppliedParamsList params -> IO (AppliedParamsList params)
forall a b. (a -> b) -> a -> b
$ AppliedRecord params -> AppliedParamsList params
forall params. AppliedRecord params -> AppliedParamsList params
appliedParamsList AppliedRecord params
record

readAppliedCount :: Eq params => IORef (AppliedRecord params) -> params -> IO Int
readAppliedCount :: forall params.
Eq params =>
IORef (AppliedRecord params) -> params -> IO Int
readAppliedCount IORef (AppliedRecord params)
ref params
params = do
  AppliedRecord params
record <- IORef (AppliedRecord params) -> IO (AppliedRecord params)
forall a. IORef a -> IO a
readIORef IORef (AppliedRecord params)
ref
  let count :: AppliedParamsCounter params
count = AppliedRecord params -> AppliedParamsCounter params
forall params. AppliedRecord params -> AppliedParamsCounter params
appliedParamsCounter AppliedRecord params
record
  Int -> IO Int
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> IO Int) -> Int -> IO Int
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (params -> AppliedParamsCounter params -> Maybe Int
forall k a. Eq k => k -> AssociationList k a -> Maybe a
lookup params
params AppliedParamsCounter params
count)

appendAppliedParams :: IORef (AppliedRecord params) -> params -> IO ()
appendAppliedParams :: forall params. IORef (AppliedRecord params) -> params -> IO ()
appendAppliedParams IORef (AppliedRecord params)
ref params
inputParams = do
  IORef (AppliedRecord params)
-> (AppliedRecord params -> AppliedRecord params) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (AppliedRecord params)
ref (\AppliedRecord {AppliedParamsList params
appliedParamsList :: forall params. AppliedRecord params -> AppliedParamsList params
appliedParamsList :: AppliedParamsList params
appliedParamsList, AppliedParamsCounter params
appliedParamsCounter :: forall params. AppliedRecord params -> AppliedParamsCounter params
appliedParamsCounter :: AppliedParamsCounter params
appliedParamsCounter} -> AppliedRecord {
    appliedParamsList :: AppliedParamsList params
appliedParamsList = AppliedParamsList params
appliedParamsList AppliedParamsList params
-> AppliedParamsList params -> AppliedParamsList params
forall a. [a] -> [a] -> [a]
++ [params
inputParams],
    appliedParamsCounter :: AppliedParamsCounter params
appliedParamsCounter = AppliedParamsCounter params
appliedParamsCounter
  })

incrementAppliedParamCount ::Eq params => IORef (AppliedRecord params) -> params -> IO ()
incrementAppliedParamCount :: forall params.
Eq params =>
IORef (AppliedRecord params) -> params -> IO ()
incrementAppliedParamCount IORef (AppliedRecord params)
ref params
inputParams = do
  IORef (AppliedRecord params)
-> (AppliedRecord params -> AppliedRecord params) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (AppliedRecord params)
ref (\AppliedRecord {AppliedParamsList params
appliedParamsList :: forall params. AppliedRecord params -> AppliedParamsList params
appliedParamsList :: AppliedParamsList params
appliedParamsList, AppliedParamsCounter params
appliedParamsCounter :: forall params. AppliedRecord params -> AppliedParamsCounter params
appliedParamsCounter :: AppliedParamsCounter params
appliedParamsCounter} -> AppliedRecord {
    appliedParamsList :: AppliedParamsList params
appliedParamsList = AppliedParamsList params
appliedParamsList,
    appliedParamsCounter :: AppliedParamsCounter params
appliedParamsCounter = params
-> AppliedParamsCounter params -> AppliedParamsCounter params
forall k.
Eq k =>
k -> AppliedParamsCounter k -> AppliedParamsCounter k
incrementCount params
inputParams AppliedParamsCounter params
appliedParamsCounter
  })

incrementCount :: Eq k => k -> AppliedParamsCounter k -> AppliedParamsCounter k
incrementCount :: forall k.
Eq k =>
k -> AppliedParamsCounter k -> AppliedParamsCounter k
incrementCount k
key AppliedParamsCounter k
list =
  if k -> AppliedParamsCounter k -> Bool
forall k a. Eq k => k -> AssociationList k a -> Bool
member k
key AppliedParamsCounter k
list then (Int -> Int)
-> k -> AppliedParamsCounter k -> AppliedParamsCounter k
forall k a.
Eq k =>
(a -> a) -> k -> AssociationList k a -> AssociationList k a
update (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) k
key AppliedParamsCounter k
list
  else k -> Int -> AppliedParamsCounter k -> AppliedParamsCounter k
forall k a.
Eq k =>
k -> a -> AssociationList k a -> AssociationList k a
insert k
key Int
1 AppliedParamsCounter k
list

safeIndex :: [a] -> Int -> Maybe a
safeIndex :: forall a. [a] -> Int -> Maybe a
safeIndex [a]
xs Int
n
  | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Maybe a
forall a. Maybe a
Nothing
  | Bool
otherwise = [a] -> Maybe a
forall a. [a] -> Maybe a
listToMaybe (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
n [a]
xs)