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

-- | Experimental Hspec support for testing WAI applications
--   
--   Experimental Hspec support for testing WAI applications
@package hspec-wai
@version 0.10.1

module Test.Hspec.Wai.Matcher
data ResponseMatcher
ResponseMatcher :: Int -> [MatchHeader] -> MatchBody -> ResponseMatcher
[matchStatus] :: ResponseMatcher -> Int
[matchHeaders] :: ResponseMatcher -> [MatchHeader]
[matchBody] :: ResponseMatcher -> MatchBody
data MatchHeader
MatchHeader :: ([Header] -> Body -> Maybe String) -> MatchHeader
data MatchBody
MatchBody :: ([Header] -> Body -> Maybe String) -> MatchBody
type Body = ByteString
(<:>) :: HeaderName -> ByteString -> MatchHeader
bodyEquals :: Body -> MatchBody
match :: SResponse -> ResponseMatcher -> Maybe String
formatHeader :: Header -> String
instance Data.String.IsString Test.Hspec.Wai.Matcher.ResponseMatcher
instance GHC.Num.Num Test.Hspec.Wai.Matcher.ResponseMatcher
instance Data.String.IsString Test.Hspec.Wai.Matcher.MatchBody

module Test.Hspec.Wai.Internal

-- | An expectation in the WaiSession monad. Failing expectations
--   are communicated through exceptions (similar to Expectation and
--   Assertion).
type WaiExpectation st = WaiSession st ()

-- | A WAI test session that carries the Application under
--   test and some client state.
newtype WaiSession st a
WaiSession :: ReaderT st Session a -> WaiSession st a
[unWaiSession] :: WaiSession st a -> ReaderT st Session a
runWaiSession :: WaiSession () a -> Application -> IO a
runWithState :: WaiSession st a -> (st, Application) -> IO a
withApplication :: Application -> WaiSession () a -> IO a
getApp :: WaiSession st Application
getState :: WaiSession st st
formatHeader :: Header -> String
instance Control.Monad.Fail.MonadFail (Test.Hspec.Wai.Internal.WaiSession st)
instance Control.Monad.IO.Class.MonadIO (Test.Hspec.Wai.Internal.WaiSession st)
instance GHC.Base.Monad (Test.Hspec.Wai.Internal.WaiSession st)
instance GHC.Base.Applicative (Test.Hspec.Wai.Internal.WaiSession st)
instance GHC.Base.Functor (Test.Hspec.Wai.Internal.WaiSession st)
instance Test.Hspec.Core.Example.Example (Test.Hspec.Wai.Internal.WaiExpectation st)

module Test.Hspec.Wai.QuickCheck
property :: Testable a => a -> (State a, Application) -> Property
(==>) :: Testable prop => Bool -> prop -> WaiProperty (State prop)
infixr 0 ==>

-- | Random generation and shrinking of values.
--   
--   QuickCheck provides Arbitrary instances for most types in
--   base, except those which incur extra dependencies. For a
--   wider range of Arbitrary instances see the
--   quickcheck-instances package.
class Arbitrary a

-- | A generator for values of the given type.
--   
--   It is worth spending time thinking about what sort of test data you
--   want - good generators are often the difference between finding bugs
--   and not finding them. You can use sample, label and
--   classify to check the quality of your test data.
--   
--   There is no generic arbitrary implementation included because
--   we don't know how to make a high-quality one. If you want one,
--   consider using the testing-feat or generic-random
--   packages.
--   
--   The QuickCheck manual goes into detail on how to write good
--   generators. Make sure to look at it, especially if your type is
--   recursive!
arbitrary :: Arbitrary a => Gen a

-- | Produces a (possibly) empty list of all the possible immediate shrinks
--   of the given value.
--   
--   The default implementation returns the empty list, so will not try to
--   shrink the value. If your data type has no special invariants, you can
--   enable shrinking by defining shrink = genericShrink,
--   but by customising the behaviour of shrink you can often get
--   simpler counterexamples.
--   
--   Most implementations of shrink should try at least three
--   things:
--   
--   
--   
- Shrink a term to any of its immediate subterms. You can use
--   subterms to do this.
--   
- Recursively apply shrink to all immediate subterms. You can
--   use recursivelyShrink to do this.
--   
- Type-specific shrinkings such as replacing a constructor by a
--   simpler constructor.
--   
--   
--   For example, suppose we have the following implementation of binary
--   trees:
--   
--   
--   data Tree a = Nil | Branch a (Tree a) (Tree a)
--   
--   
--   We can then define shrink as follows:
--   
--   
--   shrink Nil = []
--   shrink (Branch x l r) =
--     -- shrink Branch to Nil
--     [Nil] ++
--     -- shrink to subterms
--     [l, r] ++
--     -- recursively shrink subterms
--     [Branch x' l' r' | (x', l', r') <- shrink (x, l, r)]
--   
--   
--   There are a couple of subtleties here:
--   
--   
--   
- QuickCheck tries the shrinking candidates in the order they appear
--   in the list, so we put more aggressive shrinking steps (such as
--   replacing the whole tree by Nil) before smaller ones (such as
--   recursively shrinking the subtrees).
--   
- It is tempting to write the last line as [Branch x' l' r' | x'
--   <- shrink x, l' <- shrink l, r' <- shrink r] but this is
--   the wrong thing! It will force QuickCheck to shrink x,
--   l and r in tandem, and shrinking will stop once
--   one of the three is fully shrunk.
--   
--   
--   There is a fair bit of boilerplate in the code above. We can avoid it
--   with the help of some generic functions. The function
--   genericShrink tries shrinking a term to all of its subterms
--   and, failing that, recursively shrinks the subterms. Using it, we can
--   define shrink as:
--   
--   
--   shrink x = shrinkToNil x ++ genericShrink x
--     where
--       shrinkToNil Nil = []
--       shrinkToNil (Branch _ l r) = [Nil]
--   
--   
--   genericShrink is a combination of subterms, which
--   shrinks a term to any of its subterms, and recursivelyShrink,
--   which shrinks all subterms of a term. These may be useful if you need
--   a bit more control over shrinking than genericShrink gives you.
--   
--   A final gotcha: we cannot define shrink as simply
--   shrink x = Nil:genericShrink x as this shrinks
--   Nil to Nil, and shrinking will go into an infinite
--   loop.
--   
--   If all this leaves you bewildered, you might try shrink =
--   genericShrink to begin with, after deriving
--   Generic for your type. However, if your data type has any
--   special invariants, you will need to check that genericShrink
--   can't break those invariants.
shrink :: Arbitrary a => a -> [a]
class Testable a where {
    type family State a;
}
toProperty :: Testable a => a -> WaiProperty (State a)
data WaiProperty st
WaiProperty :: ((st, Application) -> Property) -> WaiProperty st
[unWaiProperty] :: WaiProperty st -> (st, Application) -> Property
instance Test.Hspec.Wai.QuickCheck.Testable (Test.Hspec.Wai.QuickCheck.WaiProperty st)
instance Test.Hspec.Wai.QuickCheck.Testable (Test.Hspec.Wai.Internal.WaiExpectation st)
instance (Test.QuickCheck.Arbitrary.Arbitrary a, GHC.Show.Show a, Test.Hspec.Wai.QuickCheck.Testable prop) => Test.Hspec.Wai.QuickCheck.Testable (a -> prop)

-- | Have a look at the README for an example of how to use this
--   library.
module Test.Hspec.Wai

-- | A WAI test session that carries the Application under
--   test and some client state.
data WaiSession st a

-- | An expectation in the WaiSession monad. Failing expectations
--   are communicated through exceptions (similar to Expectation and
--   Assertion).
type WaiExpectation st = WaiSession st ()

-- | Perform a GET request to the application under test.
get :: ByteString -> WaiSession st SResponse

-- | Perform a POST request to the application under test.
post :: ByteString -> ByteString -> WaiSession st SResponse

-- | Perform a PUT request to the application under test.
put :: ByteString -> ByteString -> WaiSession st SResponse

-- | Perform a PATCH request to the application under test.
patch :: ByteString -> ByteString -> WaiSession st SResponse

-- | Perform an OPTIONS request to the application under test.
options :: ByteString -> WaiSession st SResponse

-- | Perform a DELETE request to the application under test.
delete :: ByteString -> WaiSession st SResponse

-- | Perform a request to the application under test, with specified HTTP
--   method, request path, headers and body.
request :: Method -> ByteString -> [Header] -> ByteString -> WaiSession st SResponse

-- | Perform a POST request to the application under test.
--   
--   The specified list of key-value pairs is encoded as
--   application/x-www-form-urlencoded and used as request body.
--   
--   In addition the Content-Type is set to
--   application/x-www-form-urlencoded.
postHtmlForm :: ByteString -> [(String, String)] -> WaiSession st SResponse

-- | Set the expectation that a response matches a specified
--   ResponseMatcher.
--   
--   A ResponseMatcher matches a response if:
--   
--   
--   
- the specified status matches the HTTP response status code
--   
- the specified body (if any) matches the response body
--   
- the response has all of the specified Header fields (the
--   response may have arbitrary additional Header fields)
--   
--   
--   You can use ResponseMatcher's (broken) Num instance to
--   match for a HTTP status code:
--   
--   
--   get "/" `shouldRespondWith` 200
--   -- matches if status is 200
--   
--   
--   You can use ResponseMatcher's IsString instance to
--   match for a HTTP status 200 and a body:
--   
--   
--   get "/" `shouldRespondWith` "foo"
--   -- matches if body is "foo" and status is 200
--   
--   
--   If you want to match for a different HTTP status, you can use record
--   update notation to specify matchStatus explicitly:
--   
--   
--   get "/" `shouldRespondWith` "foo" {matchStatus = 404}
--   -- matches if body is "foo" and status is 404
--   
--   
--   If you want to require a specific header field you can specify
--   matchHeaders:
--   
--   
--   get "/" `shouldRespondWith` "foo" {matchHeaders = ["Content-Type" <:> "text/plain"]}
--   -- matches if body is "foo", status is 200 and there is a header field "Content-Type: text/plain"
--   
shouldRespondWith :: HasCallStack => WaiSession st SResponse -> ResponseMatcher -> WaiExpectation st
data ResponseMatcher
ResponseMatcher :: Int -> [MatchHeader] -> MatchBody -> ResponseMatcher
[matchStatus] :: ResponseMatcher -> Int
[matchHeaders] :: ResponseMatcher -> [MatchHeader]
[matchBody] :: ResponseMatcher -> MatchBody
data MatchHeader
MatchHeader :: ([Header] -> Body -> Maybe String) -> MatchHeader
data MatchBody
MatchBody :: ([Header] -> Body -> Maybe String) -> MatchBody
type Body = ByteString
(<:>) :: HeaderName -> ByteString -> MatchHeader
liftIO :: MonadIO m => IO a -> m a
with :: IO Application -> SpecWith ((), Application) -> Spec
withState :: IO (st, Application) -> SpecWith (st, Application) -> Spec
getState :: WaiSession st st

-- | A lifted version of pending.
pending :: WaiSession st ()

-- | A lifted version of pendingWith.
pendingWith :: String -> WaiSession st ()
