packages feed

servant-mock 0.4.4.7 → 0.5

raw patch · 7 files changed

+181/−61 lines, 7 filesdep +bytestring-conversiondep +hspecdep +hspec-waidep ~QuickCheckdep ~basedep ~servantPVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring-conversion, hspec, hspec-wai

Dependency ranges changed: QuickCheck, base, servant, servant-server, wai

API changes (from Hackage documentation)

- Servant.Mock: instance (GHC.TypeLits.KnownSymbol h, Servant.Common.Text.FromText a, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.Header.Header h a Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol path, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (path Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol s, Servant.Common.Text.FromText a, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.Capture.Capture s a Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol s, Servant.Common.Text.FromText a, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.MatrixParam.MatrixParam s a Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol s, Servant.Common.Text.FromText a, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.MatrixParam.MatrixParams s a Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol s, Servant.Common.Text.FromText a, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.QueryParam.QueryParam s a Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol s, Servant.Common.Text.FromText a, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.QueryParam.QueryParams s a Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol s, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.MatrixParam.MatrixFlag s Servant.API.Sub.:> rest)
- Servant.Mock: instance (GHC.TypeLits.KnownSymbol s, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.QueryParam.QueryFlag s Servant.API.Sub.:> rest)
- Servant.Mock: instance (Servant.API.ContentTypes.AllCTUnrender ctypes a, Servant.Mock.HasMock rest) => Servant.Mock.HasMock (Servant.API.ReqBody.ReqBody ctypes a Servant.API.Sub.:> rest)
- Servant.Mock: instance (Servant.Mock.HasMock a, Servant.Mock.HasMock b) => Servant.Mock.HasMock (a Servant.API.Alternative.:<|> b)
- Servant.Mock: instance (Test.QuickCheck.Arbitrary.Arbitrary a, Servant.API.ContentTypes.AllCTRender ctypes a) => Servant.Mock.HasMock (Servant.API.Delete.Delete ctypes a)
- Servant.Mock: instance (Test.QuickCheck.Arbitrary.Arbitrary a, Servant.API.ContentTypes.AllCTRender ctypes a) => Servant.Mock.HasMock (Servant.API.Get.Get ctypes a)
- Servant.Mock: instance (Test.QuickCheck.Arbitrary.Arbitrary a, Servant.API.ContentTypes.AllCTRender ctypes a) => Servant.Mock.HasMock (Servant.API.Patch.Patch ctypes a)
- Servant.Mock: instance (Test.QuickCheck.Arbitrary.Arbitrary a, Servant.API.ContentTypes.AllCTRender ctypes a) => Servant.Mock.HasMock (Servant.API.Post.Post ctypes a)
- Servant.Mock: instance (Test.QuickCheck.Arbitrary.Arbitrary a, Servant.API.ContentTypes.AllCTRender ctypes a) => Servant.Mock.HasMock (Servant.API.Put.Put ctypes a)
- Servant.Mock: instance Servant.Mock.HasMock Servant.API.Raw.Raw
+ Servant.Mock: instance (Servant.Mock.HasMock a context, Servant.Mock.HasMock b context) => Servant.Mock.HasMock (a Servant.API.Alternative.:<|> b) context
+ Servant.Mock: instance (Servant.Server.Internal.Context.HasContextEntry context (Servant.Server.Internal.Context.NamedContext name subContext), Servant.Mock.HasMock rest subContext) => Servant.Mock.HasMock (Servant.API.WithNamedContext.WithNamedContext name subContext rest) context
+ Servant.Mock: instance Servant.Mock.HasMock Servant.API.Raw.Raw context
+ Servant.Mock: instance forall (k :: BOX) (ctypes :: [*]) a (rest :: k) (context :: [*]). (Servant.API.ContentTypes.AllCTUnrender ctypes a, Servant.Mock.HasMock rest context) => Servant.Mock.HasMock (Servant.API.ReqBody.ReqBody ctypes a Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (h :: GHC.TypeLits.Symbol) a (rest :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol h, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Mock.HasMock rest context) => Servant.Mock.HasMock (Servant.API.Header.Header h a Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (method :: k) (status :: GHC.TypeLits.Nat) (ctypes :: [*]) (headerTypes :: [*]) a (context :: [*]). (Servant.API.ResponseHeaders.GetHeaders (Servant.API.ResponseHeaders.Headers headerTypes a), Test.QuickCheck.Arbitrary.Arbitrary (Servant.API.ResponseHeaders.HList headerTypes), Test.QuickCheck.Arbitrary.Arbitrary a, GHC.TypeLits.KnownNat status, Servant.API.Verbs.ReflectMethod method, Servant.API.ContentTypes.AllCTRender ctypes a) => Servant.Mock.HasMock (Servant.API.Verbs.Verb method status ctypes (Servant.API.ResponseHeaders.Headers headerTypes a)) context
+ Servant.Mock: instance forall (k :: BOX) (method :: k) (status :: GHC.TypeLits.Nat) (ctypes :: [*]) a (context :: [*]). (Test.QuickCheck.Arbitrary.Arbitrary a, GHC.TypeLits.KnownNat status, Servant.API.Verbs.ReflectMethod method, Servant.API.ContentTypes.AllCTRender ctypes a) => Servant.Mock.HasMock (Servant.API.Verbs.Verb method status ctypes a) context
+ Servant.Mock: instance forall (k :: BOX) (path :: GHC.TypeLits.Symbol) (rest :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol path, Servant.Mock.HasMock rest context) => Servant.Mock.HasMock (path Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (rest :: k) (context :: [*]). Servant.Mock.HasMock rest context => Servant.Mock.HasMock (Data.Vault.Lazy.Vault Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (rest :: k) (context :: [*]). Servant.Mock.HasMock rest context => Servant.Mock.HasMock (Network.HTTP.Types.Version.HttpVersion Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (rest :: k) (context :: [*]). Servant.Mock.HasMock rest context => Servant.Mock.HasMock (Servant.API.IsSecure.IsSecure Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (rest :: k) (context :: [*]). Servant.Mock.HasMock rest context => Servant.Mock.HasMock (Servant.API.RemoteHost.RemoteHost Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (s :: GHC.TypeLits.Symbol) (rest :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol s, Servant.Mock.HasMock rest context) => Servant.Mock.HasMock (Servant.API.QueryParam.QueryFlag s Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (s :: GHC.TypeLits.Symbol) a (rest :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol s, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Mock.HasMock rest context) => Servant.Mock.HasMock (Servant.API.Capture.Capture s a Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (s :: GHC.TypeLits.Symbol) a (rest :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol s, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Mock.HasMock rest context) => Servant.Mock.HasMock (Servant.API.QueryParam.QueryParam s a Servant.API.Sub.:> rest) context
+ Servant.Mock: instance forall (k :: BOX) (s :: GHC.TypeLits.Symbol) a (rest :: k) (context :: [*]). (GHC.TypeLits.KnownSymbol s, Web.HttpApiData.Internal.FromHttpApiData a, Servant.Mock.HasMock rest context) => Servant.Mock.HasMock (Servant.API.QueryParam.QueryParams s a Servant.API.Sub.:> rest) context
- Servant.Mock: class HasServer api => HasMock api
+ Servant.Mock: class HasServer api context => HasMock api context
- Servant.Mock: mock :: HasMock api => Proxy api -> Server api
+ Servant.Mock: mock :: HasMock api context => Proxy api -> Proxy context -> Server api

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2015, Alp Mestanogullari+Copyright (c) 2015-2016, Servant Contributors  All rights reserved. 
example/main.hs view
@@ -20,4 +20,4 @@ api = Proxy  main :: IO ()-main = run 8080 (serve api $ mock api)+main = run 8080 (serve api $ mock api Proxy)
+ include/overlapping-compat.h view
@@ -0,0 +1,8 @@+#if __GLASGOW_HASKELL__ >= 710+#define OVERLAPPABLE_ {-# OVERLAPPABLE #-}+#define OVERLAPPING_  {-# OVERLAPPING #-}+#else+{-# LANGUAGE OverlappingInstances #-}+#define OVERLAPPABLE_+#define OVERLAPPING_+#endif
servant-mock.cabal view
@@ -1,5 +1,5 @@ name:                servant-mock-version:             0.4.4.7+version:             0.5 synopsis:            Derive a mock server for free from your servant API types description:   Derive a mock server for free from your servant API types@@ -8,17 +8,17 @@ homepage:            http://github.com/haskell-servant/servant license:             BSD3 license-file:        LICENSE-author:              Alp Mestanogullari-maintainer:          alpmestan@gmail.com-copyright:           2015 Alp Mestanogullari+author:              Servant Contributors+maintainer:          haskell-servant-maintainers@googlegroups.com+copyright:           2015-2016 Servant Contributors category:            Web build-type:          Simple+extra-source-files:  include/*.h cabal-version:       >=1.10  flag example   description: Build the example too-  manual: True-  default: False+  default: True  library   exposed-modules:@@ -30,10 +30,11 @@     servant >= 0.4,     servant-server >= 0.4,     transformers >= 0.3 && <0.5,-    QuickCheck >= 2.8 && <2.9,+    QuickCheck >= 2.7 && <2.9,     wai >= 3.0 && <3.3   hs-source-dirs:      src   default-language:    Haskell2010+  include-dirs: include  executable mock-app   main-is: main.hs@@ -44,3 +45,24 @@     buildable: True   else     buildable: False++test-suite spec+  type: exitcode-stdio-1.0+  ghc-options:+    -Wall -fno-warn-name-shadowing+  default-language: Haskell2010+  hs-source-dirs: test+  main-is: Spec.hs+  other-modules:+    Servant.MockSpec+  build-depends:+    base,+    hspec,+    hspec-wai,+    QuickCheck,+    servant,+    servant-server,+    servant-mock,+    aeson,+    bytestring-conversion,+    wai
src/Servant/Mock.hs view
@@ -1,11 +1,16 @@-{-# LANGUAGE CPP                 #-}-{-# LANGUAGE DataKinds           #-}-{-# LANGUAGE FlexibleContexts    #-}-{-# LANGUAGE FlexibleInstances   #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies        #-}-{-# LANGUAGE TypeOperators       #-}+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-} {-# OPTIONS_GHC -fno-warn-orphans #-}++#include "overlapping-compat.h"+ -- | -- Module     : Servant.Mock -- Copyright  : 2015 Alp Mestanogullari@@ -69,7 +74,7 @@ --   than turns them into random-response-generating --   request handlers, hence providing an instance for --   all the combinators of the core /servant/ library.-class HasServer api => HasMock api where+class HasServer api context => HasMock api context where   -- | Calling this method creates request handlers of   --   the right type to implement the API described by   --   @api@ that just generate random response values of@@ -92,74 +97,75 @@   --   actually "means" 2 request handlers, of the following types:   --   --   @-  --   getUser :: EitherT ServantErr IO User-  --   getBook :: EitherT ServantErr IO Book+  --   getUser :: ExceptT ServantErr IO User+  --   getBook :: ExceptT ServantErr IO Book   --   @   --   --   So under the hood, 'mock' uses the 'IO' bit to generate   --   random values of type 'User' and 'Book' every time these   --   endpoints are requested.-  mock :: Proxy api -> Server api+  mock :: Proxy api -> Proxy context -> Server api -instance (HasMock a, HasMock b) => HasMock (a :<|> b) where-  mock _ = mock (Proxy :: Proxy a) :<|> mock (Proxy :: Proxy b)+instance (HasMock a context, HasMock b context) => HasMock (a :<|> b) context where+  mock _ context = mock (Proxy :: Proxy a) context :<|> mock (Proxy :: Proxy b) context -instance (KnownSymbol path, HasMock rest) => HasMock (path :> rest) where+instance (KnownSymbol path, HasMock rest context) => HasMock (path :> rest) context where   mock _ = mock (Proxy :: Proxy rest) -instance (KnownSymbol s, FromText a, HasMock rest) => HasMock (Capture s a :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)--instance (AllCTUnrender ctypes a, HasMock rest) => HasMock (ReqBody ctypes a :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)--instance (KnownSymbol s, FromText a, HasMock rest)-      => HasMock (QueryParam s a :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)+instance (KnownSymbol s, FromHttpApiData a, HasMock rest context) => HasMock (Capture s a :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (KnownSymbol s, FromText a, HasMock rest)-      => HasMock (QueryParams s a :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)+instance (AllCTUnrender ctypes a, HasMock rest context) => HasMock (ReqBody ctypes a :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (KnownSymbol s, HasMock rest) => HasMock (QueryFlag s :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)+instance HasMock rest context => HasMock (RemoteHost :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (KnownSymbol s, FromText a, HasMock rest)-      => HasMock (MatrixParam s a :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)+instance HasMock rest context => HasMock (IsSecure :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (KnownSymbol s, FromText a, HasMock rest)-      => HasMock (MatrixParams s a :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)+instance HasMock rest context => HasMock (Vault :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (KnownSymbol s, HasMock rest) => HasMock (MatrixFlag s :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)+instance HasMock rest context => HasMock (HttpVersion :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (KnownSymbol h, FromText a, HasMock rest) => HasMock (Header h a :> rest) where-  mock _ = \_ -> mock (Proxy :: Proxy rest)+instance (KnownSymbol s, FromHttpApiData a, HasMock rest context)+      => HasMock (QueryParam s a :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Delete ctypes a) where-  mock _ = mockArbitrary+instance (KnownSymbol s, FromHttpApiData a, HasMock rest context)+      => HasMock (QueryParams s a :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Get ctypes a) where-  mock _ = mockArbitrary+instance (KnownSymbol s, HasMock rest context) => HasMock (QueryFlag s :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Patch ctypes a) where-  mock _ = mockArbitrary+instance (KnownSymbol h, FromHttpApiData a, HasMock rest context) => HasMock (Header h a :> rest) context where+  mock _ context = \_ -> mock (Proxy :: Proxy rest) context -instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Post ctypes a) where-  mock _ = mockArbitrary+instance (Arbitrary a, KnownNat status, ReflectMethod method, AllCTRender ctypes a)+    => HasMock (Verb method status ctypes a) context where+  mock _ _ = mockArbitrary -instance (Arbitrary a, AllCTRender ctypes a) => HasMock (Put ctypes a) where-  mock _ = mockArbitrary+instance OVERLAPPING_+    (GetHeaders (Headers headerTypes a), Arbitrary (HList headerTypes),+     Arbitrary a, KnownNat status, ReflectMethod method, AllCTRender ctypes a)+    => HasMock (Verb method status ctypes (Headers headerTypes a)) context where+  mock _ _ = mockArbitrary -instance HasMock Raw where-  mock _ = \_ respond -> do+instance HasMock Raw context where+  mock _ _ = \_req respond -> do     bdy <- genBody     respond $ responseLBS status200 [] bdy      where genBody = pack <$> generate (vector 100 :: Gen [Char]) +instance (HasContextEntry context (NamedContext name subContext), HasMock rest subContext) =>+  HasMock (WithNamedContext name subContext rest) context where++  mock _ _ = mock (Proxy :: Proxy rest) (Proxy :: Proxy subContext)+ mockArbitrary :: (MonadIO m, Arbitrary a) => m a mockArbitrary = liftIO (generate arbitrary) @@ -174,5 +180,3 @@ instance (Arbitrary a, Arbitrary (HList hs))       => Arbitrary (HList (Header h a ': hs)) where   arbitrary = HCons <$> fmap Header arbitrary <*> arbitrary--
+ test/Servant/MockSpec.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeOperators #-}++module Servant.MockSpec where++import           Data.Aeson as Aeson+import           Data.ByteString.Conversion.To+import           Data.Proxy+import           Data.String+import           GHC.Generics+import           Network.Wai+import           Servant.API+import           Test.Hspec hiding (pending)+import           Test.Hspec.Wai+import           Test.QuickCheck++import           Servant+import           Servant.API.Internal.Test.ComprehensiveAPI+import           Servant.Mock++-- This declaration simply checks that all instances are in place.+_ = mock comprehensiveAPI (Proxy :: Proxy '[NamedContext "foo" '[]])++data Body+  = Body+  | ArbitraryBody+  deriving (Generic)++instance ToJSON Body++instance Arbitrary Body where+  arbitrary = return ArbitraryBody++data TestHeader+  = TestHeader+  | ArbitraryHeader+  deriving (Show)++instance ToByteString TestHeader where+  builder = fromString . show++instance Arbitrary TestHeader where+  arbitrary = return ArbitraryHeader++spec :: Spec+spec = do+  describe "mock" $ do+    context "Get" $ do+      let api :: Proxy (Get '[JSON] Body)+          api = Proxy+          app = serve api (mock api Proxy)+      with (return app) $ do+        it "serves arbitrary response bodies" $ do+          get "/" `shouldRespondWith` 200{+            matchBody = Just $ Aeson.encode ArbitraryBody+          }++    context "response headers" $ do+      let withHeader :: Proxy (Get '[JSON] (Headers '[Header "foo" TestHeader] Body))+          withHeader = Proxy+          withoutHeader :: Proxy (Get '[JSON] (Headers '[] Body))+          withoutHeader = Proxy+          toApp :: (HasMock api '[]) => Proxy api -> IO Application+          toApp api = return $ serve api (mock api (Proxy :: Proxy '[]))+      with (toApp withHeader) $ do+        it "serves arbitrary response bodies" $ do+          get "/" `shouldRespondWith` 200{+            matchHeaders = return $ MatchHeader $ \ h ->+             if h == [("Content-Type", "application/json"), ("foo", "ArbitraryHeader")]+                then Nothing+                else Just ("headers not correct\n")+          }++      with (toApp withoutHeader) $ do+        it "works for no additional headers" $ do+          get "/" `shouldRespondWith` 200{+            matchHeaders = return $ MatchHeader $ \ h ->+             if h == [("Content-Type", "application/json")]+                then Nothing+                else Just ("headers not correct\n")+          }
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}