git.iko.soy/typeable/servant
on master help sign in
Merge pull request #600 from phadej/remove-servant-mock

Move servant-mock to https://github.com/haskell-servant/servant-mock

commit1842de477577c43febc235e96da6611226d699e2 authorJulian Arni <jkarni@gmail.com> dateThu 8 Sep 2016, 13:39 (10 years ago) parent040db21782f8e1
14 files changed−427
servant-mock/.ghci−1 servant-mock/LICENSE−30 servant-mock/Setup.hs−2 servant-mock/example/main.hs−26 servant-mock/include/overlapping-compat.h−8 servant-mock/servant-mock.cabal−72 servant-mock/src/Servant/Mock.hs−188 servant-mock/test/Servant/MockSpec.hs−86 servant-mock/test/Spec.hs−1 servant-mock/tinc.yaml−5 sources.txt−1 stack-ghc-7.8.4.yaml−5 stack-ghc-8.0.1.yaml−1 stack.yaml−1
servant-mock/.ghcideleted−1
@@ -1 +0,0 @@
1−:set -Wall -itest -isrc -optP-include -optPdist/build/autogen/cabal_macros.h -Iinclude
servant-mock/LICENSEdeleted−30
@@ -1,30 +0,0 @@
1−Copyright (c) 2015-2016, Servant Contributors
2−
3−All rights reserved.
4−
5−Redistribution and use in source and binary forms, with or without
6−modification, are permitted provided that the following conditions are met:
7−
8− * Redistributions of source code must retain the above copyright
9− notice, this list of conditions and the following disclaimer.
10−
11− * Redistributions in binary form must reproduce the above
12− copyright notice, this list of conditions and the following
13− disclaimer in the documentation and/or other materials provided
14− with the distribution.
15−
16− * Neither the name of Alp Mestanogullari nor the names of other
17− contributors may be used to endorse or promote products derived
18− from this software without specific prior written permission.
19−
20−THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21−"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22−LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23−A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24−OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25−SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26−LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27−DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28−THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29−(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30−OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
servant-mock/Setup.hsdeleted−2
@@ -1,2 +0,0 @@
1−import Distribution.Simple
2−main = defaultMain
servant-mock/example/main.hsdeleted−26
@@ -1,26 +0,0 @@
1−{-# LANGUAGE DataKinds #-}
2−{-# LANGUAGE DeriveGeneric #-}
3−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4−{-# LANGUAGE TypeOperators #-}
5−
6−{-# OPTIONS_GHC -fno-warn-unused-binds #-}
7−
8−import Data.Aeson
9−import GHC.Generics
10−import Network.Wai.Handler.Warp
11−import Servant
12−import Servant.Mock
13−import Test.QuickCheck.Arbitrary
14−
15−newtype User = User { username :: String }
16− deriving (Eq, Show, Arbitrary, Generic)
17−
18−instance ToJSON User
19−
20−type API = "user" :> Get '[JSON] User
21−
22−api :: Proxy API
23−api = Proxy
24−
25−main :: IO ()
26−main = run 8080 (serve api $ mock api Proxy)
servant-mock/include/overlapping-compat.hdeleted−8
@@ -1,8 +0,0 @@
1−#if __GLASGOW_HASKELL__ >= 710
2−#define OVERLAPPABLE_ {-# OVERLAPPABLE #-}
3−#define OVERLAPPING_ {-# OVERLAPPING #-}
4−#else
5−{-# LANGUAGE OverlappingInstances #-}
6−#define OVERLAPPABLE_
7−#define OVERLAPPING_
8−#endif
servant-mock/servant-mock.cabaldeleted−72
@@ -1,72 +0,0 @@
1−name: servant-mock
2−version: 0.8.1
3−synopsis: Derive a mock server for free from your servant API types
4−description:
5− Derive a mock server for free from your servant API types
6− .
7− See the @Servant.Mock@ module for the documentation and an example.
8−homepage: http://github.com/haskell-servant/servant
9−license: BSD3
10−license-file: LICENSE
11−author: Servant Contributors
12−maintainer: haskell-servant-maintainers@googlegroups.com
13−copyright: 2015-2016 Servant Contributors
14−category: Web
15−build-type: Simple
16−extra-source-files: include/*.h
17−cabal-version: >=1.10
18−bug-reports: http://github.com/haskell-servant/servant/issues
19−source-repository head
20− type: git
21− location: http://github.com/haskell-servant/servant.git
22−
23−flag example
24− description: Build the example too
25− default: True
26−
27−library
28− exposed-modules:
29− Servant.Mock
30− build-depends:
31− base >=4.7 && <5,
32− bytestring >= 0.10 && <0.11,
33− http-types >= 0.8 && <0.10,
34− servant == 0.8.*,
35− servant-server == 0.8.*,
36− transformers >= 0.3 && <0.6,
37− QuickCheck >= 2.7 && <2.10,
38− wai >= 3.0 && <3.3
39− hs-source-dirs: src
40− default-language: Haskell2010
41− include-dirs: include
42− ghc-options: -Wall
43−
44−executable mock-app
45− main-is: main.hs
46− hs-source-dirs: example
47− default-language: Haskell2010
48− build-depends: aeson, base, servant-mock, servant-server, QuickCheck, warp
49− if flag(example)
50− buildable: True
51− else
52− buildable: False
53− ghc-options: -Wall
54−
55−test-suite spec
56− type: exitcode-stdio-1.0
57− ghc-options: -Wall
58− default-language: Haskell2010
59− hs-source-dirs: test
60− main-is: Spec.hs
61− other-modules:
62− Servant.MockSpec
63− build-depends:
64− base,
65− hspec,
66− hspec-wai,
67− QuickCheck,
68− servant,
69− servant-server,
70− servant-mock,
71− aeson,
72− wai
servant-mock/src/Servant/Mock.hsdeleted−188
@@ -1,188 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−{-# LANGUAGE DataKinds #-}
3−{-# LANGUAGE FlexibleContexts #-}
4−{-# LANGUAGE FlexibleInstances #-}
5−{-# LANGUAGE MultiParamTypeClasses #-}
6−{-# LANGUAGE PolyKinds #-}
7−{-# LANGUAGE ScopedTypeVariables #-}
8−{-# LANGUAGE TypeFamilies #-}
9−{-# LANGUAGE TypeOperators #-}
10−{-# OPTIONS_GHC -fno-warn-orphans #-}
11−
12−#include "overlapping-compat.h"
13−
14−-- |
15−-- Module : Servant.Mock
16−-- Copyright : 2015 Alp Mestanogullari
17−-- License : BSD3
18−--
19−-- Maintainer : Alp Mestanogullari <alpmestan@gmail.com>
20−-- Stability : experimental
21−-- Portability : portable
22−--
23−-- Automatically derive a mock webserver that implements some API type,
24−-- just from the said API type's definition.
25−--
26−-- Using this module couldn't be simpler. Given some API type, like:
27−--
28−-- > type API = "user" :> Get '[JSON] User
29−--
30−-- that describes your web application, all you have to do is define
31−-- a 'Proxy' to it:
32−--
33−-- > myAPI :: Proxy API
34−-- > myAPI = Proxy
35−--
36−-- and call 'mock', which has the following type:
37−--
38−-- @
39−-- 'mock' :: 'HasMock' api context => 'Proxy' api -> 'Proxy' context -> 'Server' api
40−-- @
41−--
42−-- What this says is, given some API type @api@ that it knows it can
43−-- "mock", 'mock' hands you an implementation of the API type. It does so
44−-- by having each request handler generate a random value of the
45−-- appropriate type (@User@ in our case). All you need for this to work is
46−-- to provide 'Arbitrary' instances for the data types returned as response
47−-- bodies, hence appearing next to 'Delete', 'Get', 'Patch', 'Post' and 'Put'.
48−--
49−-- To put this all to work and run the mock server, just call 'serve' on the
50−-- result of 'mock' to get an 'Application' that you can then run with warp.
51−--
52−-- @
53−-- main :: IO ()
54−-- main = Network.Wai.Handler.Warp.run 8080 $
55−-- 'serve' myAPI ('mock' myAPI Proxy)
56−-- @
57−module Servant.Mock ( HasMock(..) ) where
58−
59−#if !MIN_VERSION_base(4,8,0)
60−import Control.Applicative
61−#endif
62−import Control.Monad.IO.Class
63−import Data.ByteString.Lazy.Char8 (pack)
64−import Data.Proxy
65−import GHC.TypeLits
66−import Network.HTTP.Types.Status
67−import Network.Wai
68−import Servant
69−import Servant.API.ContentTypes
70−import Test.QuickCheck.Arbitrary (Arbitrary (..), vector)
71−import Test.QuickCheck.Gen (Gen, generate)
72−
73−-- | 'HasMock' defines an interpretation of API types
74−-- than turns them into random-response-generating
75−-- request handlers, hence providing an instance for
76−-- all the combinators of the core /servant/ library.
77−class HasServer api context => HasMock api context where
78− -- | Calling this method creates request handlers of
79− -- the right type to implement the API described by
80− -- @api@ that just generate random response values of
81− -- the right type. E.g:
82− --
83− -- @
84− -- type API = "user" :> Get '[JSON] User
85− -- :<|> "book" :> Get '[JSON] Book
86− --
87− -- api :: Proxy API
88− -- api = Proxy
89− --
90− -- -- let's say we will start with the frontend,
91− -- -- and hence need a placeholder server
92− -- server :: Server API
93− -- server = mock api Proxy
94− -- @
95− --
96− -- What happens here is that @'Server' API@
97− -- actually "means" 2 request handlers, of the following types:
98− --
99− -- @
100− -- getUser :: Handler User
101− -- getBook :: Handler Book
102− -- @
103− --
104− -- So under the hood, 'mock' uses the 'IO' bit to generate
105− -- random values of type 'User' and 'Book' every time these
106− -- endpoints are requested.
107− mock :: Proxy api -> Proxy context -> Server api
108−
109−instance (HasMock a context, HasMock b context) => HasMock (a :<|> b) context where
110− mock _ context = mock (Proxy :: Proxy a) context :<|> mock (Proxy :: Proxy b) context
111−
112−instance (KnownSymbol path, HasMock rest context) => HasMock (path :> rest) context where
113− mock _ = mock (Proxy :: Proxy rest)
114−
115−instance (KnownSymbol s, FromHttpApiData a, HasMock rest context) => HasMock (Capture s a :> rest) context where
116− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
117−
118−instance (KnownSymbol s, FromHttpApiData a, HasMock rest context) => HasMock (CaptureAll s a :> rest) context where
119− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
120−
121−instance (AllCTUnrender ctypes a, HasMock rest context) => HasMock (ReqBody ctypes a :> rest) context where
122− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
123−
124−instance HasMock rest context => HasMock (RemoteHost :> rest) context where
125− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
126−
127−instance HasMock rest context => HasMock (IsSecure :> rest) context where
128− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
129−
130−instance HasMock rest context => HasMock (Vault :> rest) context where
131− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
132−
133−instance HasMock rest context => HasMock (HttpVersion :> rest) context where
134− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
135−
136−instance (KnownSymbol s, FromHttpApiData a, HasMock rest context)
137− => HasMock (QueryParam s a :> rest) context where
138− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
139−
140−instance (KnownSymbol s, FromHttpApiData a, HasMock rest context)
141− => HasMock (QueryParams s a :> rest) context where
142− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
143−
144−instance (KnownSymbol s, HasMock rest context) => HasMock (QueryFlag s :> rest) context where
145− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
146−
147−instance (KnownSymbol h, FromHttpApiData a, HasMock rest context) => HasMock (Header h a :> rest) context where
148− mock _ context = \_ -> mock (Proxy :: Proxy rest) context
149−
150−instance (Arbitrary a, KnownNat status, ReflectMethod method, AllCTRender ctypes a)
151− => HasMock (Verb method status ctypes a) context where
152− mock _ _ = mockArbitrary
153−
154−instance OVERLAPPING_
155− (GetHeaders (Headers headerTypes a), Arbitrary (HList headerTypes),
156− Arbitrary a, KnownNat status, ReflectMethod method, AllCTRender ctypes a)
157− => HasMock (Verb method status ctypes (Headers headerTypes a)) context where
158− mock _ _ = mockArbitrary
159−
160−instance HasMock Raw context where
161− mock _ _ = \_req respond -> do
162− bdy <- genBody
163− respond $ responseLBS status200 [] bdy
164−
165− where genBody = pack <$> generate (vector 100 :: Gen [Char])
166−
167−instance (HasContextEntry context (NamedContext name subContext), HasMock rest subContext) =>
168− HasMock (WithNamedContext name subContext rest) context where
169−
170− mock _ _ = mock (Proxy :: Proxy rest) (Proxy :: Proxy subContext)
171−
172−mockArbitrary :: (MonadIO m, Arbitrary a) => m a
173−mockArbitrary = liftIO (generate arbitrary)
174−
175−-- utility instance
176−instance (Arbitrary (HList ls), Arbitrary a)
177− => Arbitrary (Headers ls a) where
178− arbitrary = Headers <$> arbitrary <*> arbitrary
179−
180−instance Arbitrary (HList '[]) where
181− arbitrary = pure HNil
182−
183−instance (Arbitrary a, Arbitrary (HList hs))
184− => Arbitrary (HList (Header h a ': hs)) where
185− arbitrary = HCons <$> fmap Header arbitrary <*> arbitrary
186−
187−instance Arbitrary NoContent where
188− arbitrary = pure NoContent
servant-mock/test/Servant/MockSpec.hsdeleted−86
@@ -1,86 +0,0 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE DataKinds #-}
3−{-# LANGUAGE DeriveGeneric #-}
4−{-# LANGUAGE FlexibleContexts #-}
5−{-# LANGUAGE OverloadedStrings #-}
6−{-# LANGUAGE TypeOperators #-}
7−
8−module Servant.MockSpec where
9−
10−import Data.Aeson as Aeson
11−import Data.Proxy
12−import GHC.Generics
13−import Network.Wai
14−import Servant.API
15−import Test.Hspec hiding (pending)
16−import Test.Hspec.Wai
17−import Test.QuickCheck
18−
19−import Servant
20−import Servant.API.Internal.Test.ComprehensiveAPI
21−import Servant.Mock
22−
23−-- This declaration simply checks that all instances are in place.
24−_ = mock comprehensiveAPI (Proxy :: Proxy '[NamedContext "foo" '[]])
25−
26−data Body
27− = Body
28− | ArbitraryBody
29− deriving (Generic)
30−
31−instance ToJSON Body
32−
33−instance Arbitrary Body where
34− arbitrary = return ArbitraryBody
35−
36−data TestHeader
37− = TestHeader
38− | ArbitraryHeader
39− deriving (Show)
40−
41−instance ToHttpApiData TestHeader where
42− toHeader = toHeader . show
43− toUrlPiece = toUrlPiece . show
44− toQueryParam = toQueryParam . show
45−
46−
47−instance Arbitrary TestHeader where
48− arbitrary = return ArbitraryHeader
49−
50−spec :: Spec
51−spec = do
52− describe "mock" $ do
53− context "Get" $ do
54− let api :: Proxy (Get '[JSON] Body)
55− api = Proxy
56− app = serve api (mock api Proxy)
57− with (return app) $ do
58− it "serves arbitrary response bodies" $ do
59− get "/" `shouldRespondWith` 200{
60− matchBody = Just $ Aeson.encode ArbitraryBody
61− }
62−
63− context "response headers" $ do
64− let withHeader :: Proxy (Get '[JSON] (Headers '[Header "foo" TestHeader] Body))
65− withHeader = Proxy
66− withoutHeader :: Proxy (Get '[JSON] (Headers '[] Body))
67− withoutHeader = Proxy
68− toApp :: (HasMock api '[]) => Proxy api -> IO Application
69− toApp api = return $ serve api (mock api (Proxy :: Proxy '[]))
70− with (toApp withHeader) $ do
71− it "serves arbitrary response bodies" $ do
72− get "/" `shouldRespondWith` 200{
73− matchHeaders = return $ MatchHeader $ \ h ->
74− if h == [("Content-Type", "application/json"), ("foo", "ArbitraryHeader")]
75− then Nothing
76− else Just ("headers not correct\n")
77− }
78−
79− with (toApp withoutHeader) $ do
80− it "works for no additional headers" $ do
81− get "/" `shouldRespondWith` 200{
82− matchHeaders = return $ MatchHeader $ \ h ->
83− if h == [("Content-Type", "application/json")]
84− then Nothing
85− else Just ("headers not correct\n")
86− }
servant-mock/test/Spec.hsdeleted−1
@@ -1 +0,0 @@
1−{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
servant-mock/tinc.yamldeleted−5
@@ -1,5 +0,0 @@
1−dependencies:
2− - name: servant
3− path: ../servant
4− - name: servant-server
5− path: ../servant-server
sources.txt−1
@@ -4,4 +4,3 @@ servant-client
44servant-docs
55servant-foreign
66servant-js
7−servant-mock
stack-ghc-7.8.4.yaml−5
@@ -5,7 +5,6 @@ packages:
55- servant-docs/
66- servant-foreign/
77- servant-js/
8−- servant-mock/
98- servant-server/
109extra-deps:
1110- base-compat-0.9.1
@@ -18,10 +17,6 @@ extra-deps:
1817- hspec-expectations-0.7.2
1918- http-api-data-0.2.2
2019- primitive-0.6.1.0
21−- servant-0.7.1
22−- servant-client-0.7.1
23−- servant-docs-0.7.1
24−- servant-server-0.7.1
2520- should-not-typecheck-2.1.0
2621- time-locale-compat-0.1.1.1
2722- wai-app-static-3.1.5
stack-ghc-8.0.1.yaml−1
@@ -5,7 +5,6 @@ packages:
55- servant-docs/
66- servant-foreign/
77- servant-js/
8−- servant-mock/
98- servant-server/
109extra-deps: []
1110flags: {}
stack.yaml−1
@@ -5,7 +5,6 @@ packages:
55- servant-docs/
66- servant-foreign/
77- servant-js/
8−- servant-mock/
98- servant-server/
109- doc/tutorial
1110extra-deps: