-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Test monadic side-effects
--   
--   Please see README.md
@package test-fixture
@version 0.5.1.0


-- | <h1>Introduction and motivation</h1>
--   
--   This package provides a set of helper functions and types that are
--   designed to assist with writing tests for functions that encode
--   side-effects into monads using effect-specific typeclasses. Consider a
--   function that performs some sort of side effect, such as a function
--   that looks up a user from a database:
--   
--   <pre>
--   lookupUser :: UserId -&gt; IO (Maybe User)
--   </pre>
--   
--   Now consider a function that uses the <tt>lookupUser</tt> function:
--   
--   <pre>
--   lookupUserIsAdmin :: UserId -&gt; IO Bool
--   lookupUserIsAdmin userId = do
--     maybeUser &lt;- lookupUser userId
--     return $ maybe False isAdmin maybeUser
--   </pre>
--   
--   This function works fine, but it’s very difficult to test, even though
--   it is extremely simple. Since <tt>lookupUser</tt> just runs in
--   <a>IO</a>, it isn’t easy to test <tt>lookupUserIsAdmin</tt> in
--   isolation. To fix this, it’s possible to create a layer of indirection
--   between <tt>lookupUserIsAdmin</tt> and <tt>lookupUser</tt> by making
--   <tt>lookupUser</tt> a method of a typeclass instead of a free
--   function:
--   
--   <pre>
--   class Monad m =&gt; LookupUser m where
--     lookupUser :: UserId -&gt; m (Maybe User)
--   </pre>
--   
--   Implementing the original, <a>IO</a>-bound version of
--   <tt>lookupUser</tt> is easy; we just create a <tt>LookupUser</tt>
--   instance for <a>IO</a>:
--   
--   <pre>
--   instance LookupUser IO where
--     lookupUser = lookupUserIO
--   </pre>
--   
--   However, we can also create other monads that implement the
--   <tt>LookupUser</tt> typeclass. For example, we could create a very
--   simple newtype wrapper around <a>Identity</a> with an implementation
--   that <i>always</i> returns a user successfully:
--   
--   <pre>
--   newtype SuccessMonad a = SuccessMonad (Identity a)
--     deriving (Functor, Applicative, Monad)
--   
--   runSuccess :: SuccessMonad a -&gt; a
--   runSuccess (SuccessMonad (Identity x)) = x
--   
--   instance LookupUser SuccessMonad where
--     lookupUser _ = return $ Just User { isAdmin = True }
--   </pre>
--   
--   Now we can test <tt>lookupUserIsAdmin</tt> completely
--   deterministically without ever needing to touch a real database (using
--   hspec syntax as an example):
--   
--   <pre>
--   lookupUserIsAdmin :: LookupUser m =&gt; UserId -&gt; m Bool
--   lookupUserIsAdmin userId = do
--     maybeUser &lt;- lookupUser userId
--     return $ maybe False isAdmin maybeUser
--   
--   spec = describe "lookupUserIsAdmin" $ do
--     it "returns True when the UserId corresponds to an admin user" $
--       runSuccess (lookupUserIsAdmin (UserId 42)) `shouldBe` True
--   </pre>
--   
--   Similarly, we can also test the failure case by creating a monad that
--   will always return <a>Nothing</a>:
--   
--   <pre>
--   newtype FailureMonad a = FailureMonad (Identity a)
--     deriving (Functor, Applicative, Monad)
--   
--   runFailure :: FailureMonad a -&gt; a
--   runFailure (FailureMonad (Identity x)) = x
--   
--   instance LookupUser FailureMonad where
--     lookupUser _ = return Nothing
--   
--     it "returns False when the UserId does not have a corresponding User" $
--       runFailure (lookupUserIsAdmin (UserId 42)) `shouldBe` False
--   </pre>
--   
--   This is great, but it comes at a pretty significant cost: lots and
--   lots of boilerplate. It could get even worse when you have a typeclass
--   with many methods, or even multiple typeclasses at a time! Clearly,
--   there needs to be some way to abstract this pattern a little bit to
--   make it easier to use.
--   
--   <h1>Creating a customizable monad</h1>
--   
--   To permit creating easily customizable implementations of monadic
--   interfaces, we can <i>reify</i> a typeclass at the value level by
--   creating a record type with a field that corresponds to each method:
--   
--   <pre>
--   data Fixture m = Fixture { _lookupUser :: UserId -&gt; m (Maybe User) }
--   </pre>
--   
--   We have to prefix each method name with an underscore to avoid name
--   clashes, but now we have the ability to create a first-class value
--   that represents a particular implementation of the <tt>LookupUser</tt>
--   typeclass. The next step is turning one of these values into something
--   that can actually be supplied as a monad implementation. One way to do
--   this is to use a reader monad to thread a particular <tt>Fixture</tt>
--   value around. We can create a newtype that will do that for us:
--   
--   <pre>
--   newtype FixtureM a = FixtureM (Fixture Identity -&gt; a)
--     deriving (Functor, Applicative, Monad)
--   
--   runFixture :: Fixture Identity -&gt; FixtureM a -&gt; a
--   runFixture fixture (FixtureM func) = func fixture
--   </pre>
--   
--   By making this new <tt>FixtureM</tt> type an instance of
--   <tt>LookupUser</tt>, we can use the <tt>runFixture</tt> function that
--   we defined to run a particular computation with any arbitrary fixture
--   at runtime:
--   
--   <pre>
--   instance LookupUser FixtureM where
--     lookupUser userId = FixtureM $ \fixture -&gt;
--       runIdentity $ _lookupUser fixture userId
--   </pre>
--   
--   Now we can write all our tests using one-off fixture implementations
--   without creating entirely new types:
--   
--   <pre>
--   spec = describe "lookupUserIsAdmin" $ do
--     it "returns True when the UserId corresponds to an admin user" $ do
--       let fixture = Fixture { _lookupUser = return $ Just User { isAdmin = True } }
--       runFixture fixture (lookupUserIsAdmin (UserId 42)) `shouldBe` True
--   
--     it "returns False when the UserId corresponds to a non-admin user" $ do
--       let fixture = Fixture { _lookupUser = return $ Just User { isAdmin = False } }
--       runFixture fixture (lookupUserIsAdmin (UserId 42)) `shouldBe` False
--   
--     it "returns False when the UserId does not have a corresponding User" $ do
--       let fixture = Fixture { _lookupUser = return Nothing }
--       runFixture fixture (lookupUserIsAdmin (UserId 42)) `shouldBe` False
--   </pre>
--   
--   <h1>Moving beyond a reader</h1>
--   
--   The above example is relatively contrived, but it may be possible to
--   see how this technique could be applied to a larger set of monadic
--   typeclasses by creating more instances on a fixture with more methods.
--   
--   However, it is sometimes useful to do <i>even more</i> with a fixture,
--   such as verifying that a given function was called with a particular
--   argument. For example, consider a function with the following
--   signature:
--   
--   <pre>
--   insertUser :: User -&gt; m ()
--   </pre>
--   
--   In this case, testing the <i>result</i> is likely not particulary
--   interesting, but testing that the function itself is called with the
--   right argument might be helpful. Even more subtly, a function might be
--   called multiple times, and it might need to return different values
--   each time! This requires some degree of state tracking that a reader
--   monad simply cannot provide.
--   
--   To solve this, the provided <a>TestFixture</a> monad combines a
--   <i>reader</i>, <i>writer</i>, and <i>state</i> monad into a single
--   system. This allows “logging” results from a fixture by using
--   <a>tell</a> within the fixture definition and <a>logTestFixture</a>,
--   and it also permits having fixture invocations depend on previous uses
--   of the fixture by using <a>get</a> and <a>put</a> from
--   <a>MonadState</a>.
--   
--   Continuing from the above example but using <a>TestFixture</a>
--   instead, we eschew the simpler <tt>FixtureM</tt> type and create
--   instances over <a>TestFixture</a> instead:
--   
--   <pre>
--   instance Monoid log =&gt; LookupUser (TestFixture Fixture log state) where
--     lookupUser userId = do
--       fn &lt;- asks _lookupUser
--       fn userId
--   </pre>
--   
--   Now we can write our tests using the <a>unTestFixture</a> function,
--   along with the similar <a>logTestFixture</a> functions and friends:
--   
--   <pre>
--   spec = describe "lookupUserIsAdmin" $ do
--     it "returns True when the UserId corresponds to an admin user" $ do
--       let fixture = Fixture { _lookupUser = return $ Just User { isAdmin = True } }
--       unTestFixture (lookupUserIsAdmin (UserId 42)) fixture `shouldBe` True
--   
--     it "returns False when the UserId corresponds to a non-admin user" $ do
--       let fixture = Fixture { _lookupUser = return $ Just User { isAdmin = False } }
--       unTestFixture (lookupUserIsAdmin (UserId 42)) fixture `shouldBe` False
--   
--     it "returns False when the UserId does not have a corresponding User" $ do
--       let fixture = Fixture { _lookupUser = return Nothing }
--       unTestFixture (lookupUserIsAdmin (UserId 42)) fixture `shouldBe` False
--   </pre>
--   
--   As a final note, writing out all of these fixture record definitions
--   and instance declarations can be extremely tedious with large numbers
--   of typeclasses and tests. To mitigate this, the
--   <a>Control.Monad.TestFixture.TH</a> module provides a <a>mkFixture</a>
--   function, which uses Template Haskell to generate the necessary code
--   instead.
module Control.Monad.TestFixture

-- | The <a>TestFixture</a> monad. A combination of a <i>reader</i>,
--   <i>writer</i>, and <i>state</i> monad, where the reader portion
--   contains a reified typeclass dictionary used as a fixture. For more
--   information, see the module documentation for
--   <a>Control.Monad.TestFixture</a>.
type TestFixture fixture log state = TestFixtureT fixture log state Identity

-- | The simplest way to run a test given a fixture, <a>unTestFixture</a>
--   simply runs a monadic computation with a particular fixture and
--   returns the computation’s result. Useful for testing impure functions
--   that return useful values.
unTestFixture :: TestFixture fixture () () a -> fixture (TestFixture fixture () ()) -> a

-- | Like <a>unTestFixture</a>, but instead of returning the result of the
--   computation, <a>logTestFixture</a> returns the value written from the
--   writer monad. Useful for testing impure functions called exclusively
--   for side-effects that do not depend on complex prior state.
logTestFixture :: TestFixture fixture log () a -> fixture (TestFixture fixture log ()) -> [log]

-- | Combines <a>unTestFixture</a> and <a>logTestFixture</a> to return
--   <i>both</i> the computation’s result and the written value as a tuple.
evalTestFixture :: TestFixture fixture log () a -> fixture (TestFixture fixture log ()) -> (a, [log])

-- | Like <a>logTestFixture</a> but accepts an initial state and returns
--   the final monadic state tupled with the value written from the writer
--   monad. Useful for testing stateful side-effectful computations.
execTestFixture :: TestFixture fixture log state a -> fixture (TestFixture fixture log state) -> state -> (state, [log])

-- | Runs a test fixture given an initial state and returns all three
--   pieces of resulting information: the computation’s result, the final
--   monadic state, and the value written from the writer.
runTestFixture :: TestFixture fixture log state a -> fixture (TestFixture fixture log state) -> state -> (a, state, [log])

-- | <a>TestFixture</a> as a monad transformer instead of as a monad.
data TestFixtureT fixture log state m a

-- | The transformer equivalent of <a>unTestFixture</a>.
unTestFixtureT :: Monad m => TestFixtureT fixture () () m a -> fixture (TestFixtureT fixture () () m) -> m a

-- | The transformer equivalent of <a>logTestFixture</a>.
logTestFixtureT :: Monad m => TestFixtureT fixture log () m a -> fixture (TestFixtureT fixture log () m) -> m [log]

-- | The transformer equivalent of <a>evalTestFixture</a>.
evalTestFixtureT :: Monad m => TestFixtureT fixture log () m a -> fixture (TestFixtureT fixture log () m) -> m (a, [log])

-- | The transformer equivalent of <a>execTestFixture</a>.
execTestFixtureT :: Monad m => TestFixtureT fixture log state m a -> fixture (TestFixtureT fixture log state m) -> state -> m (state, [log])

-- | The transformer equivalent of <a>runTestFixture</a>.
runTestFixtureT :: Monad m => TestFixtureT fixture log state m a -> fixture (TestFixtureT fixture log state m) -> state -> m (a, state, [log])

-- | A helper function for implementing typeclass instances over
--   <a>TestFixture</a> that pull a value out of a monadic dictionary. For
--   example, given the following instance:
--   
--   <pre>
--   instance Monoid log =&gt; MonadSomething (TestFixture Fixture log state) where
--     getSomething = do
--       something &lt;- asks _getSomething
--       something
--   </pre>
--   
--   Using <a>arg0</a>, it can be rewritten like this:
--   
--   <pre>
--   instance Monoid log =&gt; MonadSomething (TestFixture Fixture log state) where
--     getSomething = arg0 _getSomething
--   </pre>
--   
--   For functions of various arities instead of plain values, use
--   <a>arg1</a> through <a>arg7</a>, instead.
arg0 :: (fixture (TestFixture fixture log state) -> TestFixture fixture log state a) -> TestFixture fixture log state a

-- | Like <a>arg0</a>, but for lifting record accessors containing
--   functions of arity one. For example, given the following instance:
--   
--   <pre>
--   instance Monoid log =&gt; MonadSomething (TestFixture Fixture log state) where
--     doSomething x = do
--       fn &lt;- asks _doSomething
--       fn x
--   </pre>
--   
--   Using <a>arg1</a>, it can be rewritten like this:
--   
--   <pre>
--   instance Monoid log =&gt; MonadSomething (TestFixture Fixture log state) where
--     doSomething = arg1 _doSomething
--   </pre>
--   
--   For functions of higher arities, use <a>arg2</a> through <a>arg7</a>.
arg1 :: Monad m => (fixture (TestFixtureT fixture log state m) -> a -> TestFixtureT fixture log state m b) -> a -> TestFixtureT fixture log state m b

-- | Like <a>arg1</a>, but for functions of arity 2.
arg2 :: Monad m => (fixture (TestFixtureT fixture log state m) -> a -> b -> TestFixtureT fixture log state m c) -> a -> b -> TestFixtureT fixture log state m c

-- | Like <a>arg1</a>, but for functions of arity 3.
arg3 :: Monad m => (fixture (TestFixtureT fixture log state m) -> a -> b -> c -> TestFixtureT fixture log state m d) -> a -> b -> c -> TestFixtureT fixture log state m d

-- | Like <a>arg1</a>, but for functions of arity 4.
arg4 :: Monad m => (fixture (TestFixtureT fixture log state m) -> a -> b -> c -> d -> TestFixtureT fixture log state m e) -> a -> b -> c -> d -> TestFixtureT fixture log state m e

-- | Like <a>arg1</a>, but for functions of arity 5.
arg5 :: Monad m => (fixture (TestFixtureT fixture log state m) -> a -> b -> c -> d -> e -> TestFixtureT fixture log state m f) -> a -> b -> c -> d -> e -> TestFixtureT fixture log state m f

-- | Like <a>arg1</a>, but for functions of arity 6.
arg6 :: Monad m => (fixture (TestFixtureT fixture log state m) -> a -> b -> c -> d -> e -> f -> TestFixtureT fixture log state m g) -> a -> b -> c -> d -> e -> f -> TestFixtureT fixture log state m g

-- | Like <a>arg1</a>, but for functions of arity 7.
arg7 :: Monad m => (fixture (TestFixtureT fixture log state m) -> a -> b -> c -> d -> e -> f -> g -> TestFixtureT fixture log state m h) -> a -> b -> c -> d -> e -> f -> g -> TestFixtureT fixture log state m h

-- | An extremely simple helper function for creating “base” fixture
--   dictionaries with implementations that will simply throw as soon as
--   they are called using a helpful error message. The provided argument
--   should be the name of a method being implemented.
--   
--   <pre>
--   &gt;&gt;&gt; unimplemented "_getSomething"
--   *** Exception: unimplemented fixture method `_getSomething`
--   </pre>
unimplemented :: String -> a

-- | Logs a single value using <a>MonadWriter</a> when the writer state is
--   a list. Equivalent to <tt><a>tell</a> . <a>pure</a></tt>. Useful with
--   <a>TestFixture</a> implementations to record values when using
--   functions like <a>logTestFixture</a>.
log :: MonadWriter [log] m => log -> m ()
instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState state (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance GHC.Base.Monad m => Control.Monad.Writer.Class.MonadWriter [log] (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (fixture (Control.Monad.TestFixture.TestFixtureT fixture log state m)) (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.TestFixture.TestFixtureT fixture log state m)
instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.TestFixture.TestFixtureT fixture log state)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Control.Monad.TestFixture.TestFixtureT fixture log state m)


-- | This module provides a Template Haskell function for automatically
--   generating reified typeclass dictionaries for use with
--   <a>Control.Monad.TestFixture</a>. These generated dictionaries can be
--   used with functions like <a>unTestFixture</a> and
--   <a>logTestFixture</a> to quickly implement monadic typeclasses in a
--   way that can be used to “stub out” functionality in unit tests.
--   
--   The <a>mkFixture</a> function is a Template Haskell code generation
--   tool, which generates three things:
--   
--   <ol>
--   <li>A record type that represents a reified typeclass dictionary (or
--   set of typeclass dictionaries). The record contains fields that
--   correspond to the methods of the provided typeclasses, with ordinary
--   method names prefixed with a <tt>_</tt> character and infix method
--   names prefixed with a <tt>~</tt> character.</li>
--   <li>A <tt>Default</tt> instance for the generated record type, which
--   automatically fills all fields with stub implementations that will
--   throw using <tt>unimplemented</tt>.</li>
--   <li>Typeclass implementations for all of the provided typeclasses
--   using <tt>TestFixture</tt> and the generated record type that defer to
--   the implementations provided through the reified dictionary.</li>
--   </ol>
--   
--   In practice, this is used for generate “fixture” types that are used
--   within tests. For example, consider some typeclasses that encode
--   side-effectful monadic operations:
--   
--   <pre>
--   class Monad m =&gt; DB m where
--     fetchRecord :: DBRecord a =&gt; Id a -&gt; m (Either DBError a)
--     insertRecord :: DBRecord a =&gt; a -&gt; m (Either DBError (Id a))
--   
--   class Monad m =&gt; HTTP m where
--     sendRequest :: HTTPRequest -&gt; m (Either HTTPError HTTPResponse)
--   </pre>
--   
--   The typeclasses may have relatively straightforward instances for
--   <a>IO</a>. However, one of the main values of them is that alternative
--   instances may be provided in unit tests, which is what
--   <tt>TestFixture</tt> provides. Therefore, one might use
--   <a>mkFixture</a> to create some utilities for stubbing these
--   typeclasses out:
--   
--   <pre>
--   mkFixture "Fixture" [ts| DB, HTTP |]
--   </pre>
--   
--   This generates code much like the following:
--   
--   <pre>
--   data Fixture m =
--     { _fetchRecord :: DBRecord a =&gt; Id a -&gt; m (Either DBError a)
--     , _insertRecord :: DBRecord a =&gt; a -&gt; m (Either DBError (Id a))
--     , _sendRequest :: HTTPRequest -&gt; m (Either HTTPError HTTPResponse)
--     }
--   
--   instance Default (Fixture m) where
--     def = Fixture
--       { _fetchRecord = unimplemented "_fetchRecord"
--       , _insertRecord = unimplemented "_insertRecord"
--       , _sendRequest = unimplemented "_sendRequest"
--       }
--   
--   type FixturePure = Fixture (TestFixture Fixture () ())
--   type FixtureLog log = Fixture (TestFixture Fixture log ())
--   type FixtureState state = Fixture (TestFixture Fixture () state)
--   type FixtureLogState log state = Fixture (TestFixture Fixture log state)
--   
--   type FixturePureT m = Fixture (TestFixture Fixture () () m)
--   type FixtureLogT log m = Fixture (TestFixture Fixture log () m)
--   type FixtureStateT state m = Fixture (TestFixture Fixture () state m)
--   type FixtureLogStateT log state m = Fixture (TestFixtureT Fixture log state m)
--   
--   instance Monad m =&gt; DB (TestFixtureT Fixture w s m) where
--     fetchRecord r = do
--       fn &lt;- asks _fetchRecord
--       fn r
--     insertRecord r = do
--       fn &lt;- asks _insertRecord
--       fn r
--   
--   instance Monad m =&gt; HTTP (TestFixtureT Fixture w s m) where
--     sendRequest r = do
--       fn &lt;- asks _sendRequest
--       fn r
--   </pre>
--   
--   This type can then be used in tandem with
--   <a>Control.Monad.TestFixture</a> to create stubbed typeclass instances
--   and run computations using them.
module Control.Monad.TestFixture.TH

-- | A Template Haskell function that generates a fixture record type with
--   a given name that reifies the set of typeclass dictionaries provided,
--   as described in the module documentation for
--   <a>Control.Monad.TestFixture.TH</a>. For example, the following splice
--   would create a new record type called <tt>Fixture</tt> with fields and
--   instances for typeclasses called <tt>Foo</tt> and <tt>Bar</tt>:
--   
--   <pre>
--   mkFixture "Fixture" [ts| Foo, Bar |]
--   </pre>
--   
--   <a>mkFixture</a> supports types in the same format that
--   <tt>deriving</tt> clauses do when used with the
--   <tt>GeneralizedNewtypeDeriving</tt> GHC extension, so deriving
--   multi-parameter typeclasses is possible if they are partially applied.
--   For example, the following is valid:
--   
--   <pre>
--   class MultiParam a m where
--     doSomething :: a -&gt; m ()
--   
--   mkFixture "Fixture" [ts| MultiParam String |]
--   </pre>
mkFixture :: String -> [Type] -> Q [Dec]

-- | The default value for this type.
def :: Default a => a

-- | A quasi-quoter like the built-in <tt>[t| ... |]</tt> quasi-quoter, but
--   produces a <i>list</i> of types instead of a single type. Each type
--   should be separated by a comma.
--   
--   <pre>
--   &gt;&gt;&gt; [ts| Bool, (), String |]
--   [ConT GHC.Types.Bool,ConT GHC.Tuple.(),ConT GHC.Base.String]
--   
--   &gt;&gt;&gt; [ts| Maybe Int, Monad m |]
--   [AppT (ConT GHC.Base.Maybe) (ConT GHC.Types.Int),AppT (ConT GHC.Base.Monad) (VarT m)]
--   </pre>
ts :: QuasiQuoter
