git.iko.soy/servant-quickcheck
on master help sign in
Documentation improvements
26a6171Julian K. Arni
src/Servant/QuickCheck.hs+7
@@ -59,9 +59,12 @@ module Servant.QuickCheck
59 , defaultArgs
59 , defaultArgs
60
60
61 -- ** Re-exports
61 -- ** Re-exports
62+ -- | Types and constructors from other packages that are generally needed for
63+ -- using @servant-quickcheck@.
62 , BaseUrl(..)
64 , BaseUrl(..)
63 , Scheme(..)
65 , Scheme(..)
64 , Args(..)
66 , Args(..)
67+ , Proxy(..)
65
68
66
69
67 ) where
70 ) where
@@ -69,6 +72,10 @@ module Servant.QuickCheck
69import Servant.QuickCheck.Internal
72import Servant.QuickCheck.Internal
70import Servant.Client (BaseUrl(..), Scheme(..))
73import Servant.Client (BaseUrl(..), Scheme(..))
71import Test.QuickCheck (Args(..), stdArgs)
74import Test.QuickCheck (Args(..), stdArgs)
75+import Data.Proxy (Proxy(..))
72
76
77+-- | QuickCheck @Args@ with 1000 rather than 100 test cases.
78+--
79+-- /Since 0.0.0.0/
73defaultArgs :: Args
80defaultArgs :: Args
74defaultArgs = stdArgs { maxSuccess = 1000 }
81defaultArgs = stdArgs { maxSuccess = 1000 }
src/Servant/QuickCheck/Internal/Equality.hs+2−2
@@ -14,12 +14,12 @@ instance Monoid (ResponseEquality b) where
14
14
15-- | Use `Eq` instance for `Response`
15-- | Use `Eq` instance for `Response`
16--
16--
17−-- #SINCE#
17+-- /Since 0.0.0.0/
18allEquality :: Eq b => ResponseEquality b
18allEquality :: Eq b => ResponseEquality b
19allEquality = ResponseEquality (==)
19allEquality = ResponseEquality (==)
20
20
21-- | ByteString `Eq` instance over the response body.
21-- | ByteString `Eq` instance over the response body.
22--
22--
23−-- #SINCE#
23+-- /Since 0.0.0.0/
24bodyEquality :: Eq b => ResponseEquality b
24bodyEquality :: Eq b => ResponseEquality b
25bodyEquality = ResponseEquality ((==) `on` responseBody)
25bodyEquality = ResponseEquality ((==) `on` responseBody)
src/Servant/QuickCheck/Internal/Predicates.hs+21−4
@@ -31,6 +31,8 @@ import Network.HTTP.Types (methodGet, methodHead, parseMethod,
31-- indication of how to proceed or what went wrong.
31-- indication of how to proceed or what went wrong.
32--
32--
33-- This function checks that the response code is not 500.
33-- This function checks that the response code is not 500.
34+--
35+-- /Since 0.0.0.0/
34not500 :: ResponsePredicate Text Bool
36not500 :: ResponsePredicate Text Bool
35not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == status500)
37not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == status500)
36
38
@@ -53,6 +55,8 @@ not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == statu
53--
55--
54-- * JSON Grammar: <https://tools.ietf.org/html/rfc7159#section-2 RFC 7159 Section 2>
56-- * JSON Grammar: <https://tools.ietf.org/html/rfc7159#section-2 RFC 7159 Section 2>
55-- * JSON Grammar: <https://tools.ietf.org/html/rfc4627#section-2 RFC 4627 Section 2>
57-- * JSON Grammar: <https://tools.ietf.org/html/rfc4627#section-2 RFC 4627 Section 2>
58+--
59+-- /Since 0.0.0.0/
56onlyJsonObjects :: ResponsePredicate Text Bool
60onlyJsonObjects :: ResponsePredicate Text Bool
57onlyJsonObjects
61onlyJsonObjects
58 = ResponsePredicate "onlyJsonObjects" (\resp -> case decode (responseBody resp) of
62 = ResponsePredicate "onlyJsonObjects" (\resp -> case decode (responseBody resp) of
@@ -76,6 +80,8 @@ onlyJsonObjects
76--
80--
77-- * 201 Created: <https://tools.ietf.org/html/rfc7231#section-6.3.2 RFC 7231 Section 6.3.2>
81-- * 201 Created: <https://tools.ietf.org/html/rfc7231#section-6.3.2 RFC 7231 Section 6.3.2>
78-- * Location header: <https://tools.ietf.org/html/rfc7231#section-7.1.2 RFC 7231 Section 7.1.2>
82-- * Location header: <https://tools.ietf.org/html/rfc7231#section-7.1.2 RFC 7231 Section 7.1.2>
83+--
84+-- /Since 0.0.0.0/
79createContainsValidLocation :: RequestPredicate Text Bool
85createContainsValidLocation :: RequestPredicate Text Bool
80createContainsValidLocation
86createContainsValidLocation
81 = RequestPredicate
87 = RequestPredicate
@@ -114,6 +120,8 @@ getsHaveLastModifiedHeader
114--
120--
115-- * @Allow@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.7>
121-- * @Allow@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.7>
116-- * Status 405: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html RFC 2616 Section 10.4.6>
122-- * Status 405: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html RFC 2616 Section 10.4.6>
123+--
124+-- /Since 0.0.0.0/
117notAllowedContainsAllowHeader :: RequestPredicate Text Bool
125notAllowedContainsAllowHeader :: RequestPredicate Text Bool
118notAllowedContainsAllowHeader
126notAllowedContainsAllowHeader
119 = RequestPredicate
127 = RequestPredicate
@@ -144,6 +152,8 @@ notAllowedContainsAllowHeader
144-- __References__:
152-- __References__:
145--
153--
146-- * @Accept@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.1>
154-- * @Accept@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.1>
155+--
156+-- /Since 0.0.0.0/
147honoursAcceptHeader :: RequestPredicate Text Bool
157honoursAcceptHeader :: RequestPredicate Text Bool
148honoursAcceptHeader
158honoursAcceptHeader
149 = RequestPredicate
159 = RequestPredicate
@@ -171,7 +181,7 @@ honoursAcceptHeader
171--
181--
172-- * @Cache-Control@ header: <https://tools.ietf.org/html/rfc7234#section-5.2 RFC 7234 Section 5.2>
182-- * @Cache-Control@ header: <https://tools.ietf.org/html/rfc7234#section-5.2 RFC 7234 Section 5.2>
173--
183--
174−-- #SINCE#
184+-- /Since 0.0.0.0/
175getsHaveCacheControlHeader :: RequestPredicate Text Bool
185getsHaveCacheControlHeader :: RequestPredicate Text Bool
176getsHaveCacheControlHeader
186getsHaveCacheControlHeader
177 = RequestPredicate
187 = RequestPredicate
@@ -188,7 +198,7 @@ getsHaveCacheControlHeader
188--
198--
189-- Like 'getsHaveCacheControlHeader', but for @HEAD@ requests.
199-- Like 'getsHaveCacheControlHeader', but for @HEAD@ requests.
190--
200--
191−-- #SINCE#
201+-- /Since 0.0.0.0/
192headsHaveCacheControlHeader :: RequestPredicate Text Bool
202headsHaveCacheControlHeader :: RequestPredicate Text Bool
193headsHaveCacheControlHeader
203headsHaveCacheControlHeader
194 = RequestPredicate
204 = RequestPredicate
@@ -260,7 +270,7 @@ linkHeadersAreValid
260--
270--
261-- * @WWW-Authenticate@ header: <https://tools.ietf.org/html/rfc7235#section-4.1 RFC 7235 Section 4.1>
271-- * @WWW-Authenticate@ header: <https://tools.ietf.org/html/rfc7235#section-4.1 RFC 7235 Section 4.1>
262--
272--
263−-- #SINCE#
273+-- /Since 0.0.0.0/
264unauthorizedContainsWWWAuthenticate :: ResponsePredicate Text Bool
274unauthorizedContainsWWWAuthenticate :: ResponsePredicate Text Bool
265unauthorizedContainsWWWAuthenticate
275unauthorizedContainsWWWAuthenticate
266 = ResponsePredicate "unauthorizedContainsWWWAuthenticate" (\resp ->
276 = ResponsePredicate "unauthorizedContainsWWWAuthenticate" (\resp ->
@@ -276,6 +286,9 @@ unauthorizedContainsWWWAuthenticate
276--
286--
277-- Still, this is all kind of ugly.
287-- Still, this is all kind of ugly.
278
288
289+-- | A predicate that depends only on the response.
290+--
291+-- /Since 0.0.0.0/
279data ResponsePredicate n r = ResponsePredicate
292data ResponsePredicate n r = ResponsePredicate
280 { respPredName :: n
293 { respPredName :: n
281 , respPred :: Response LBS.ByteString -> r
294 , respPred :: Response LBS.ByteString -> r
@@ -292,6 +305,9 @@ instance (Monoid n, Monoid r) => Monoid (ResponsePredicate n r) where
292 , respPred = respPred a <> respPred b
305 , respPred = respPred a <> respPred b
293 }
306 }
294
307
308+-- | A predicate that depends on both the request and the response.
309+--
310+-- /Since 0.0.0.0/
295data RequestPredicate n r = RequestPredicate
311data RequestPredicate n r = RequestPredicate
296 { reqPredName :: n
312 { reqPredName :: n
297 , reqResps :: Request -> Manager -> IO (r, [Response LBS.ByteString])
313 , reqResps :: Request -> Manager -> IO (r, [Response LBS.ByteString])
@@ -309,6 +325,7 @@ instance (Monoid n, Monoid r) => Monoid (RequestPredicate n r) where
309 , reqResps = \x m -> liftM2 (<>) (reqResps a x m) (reqResps b x m)
325 , reqResps = \x m -> liftM2 (<>) (reqResps a x m) (reqResps b x m)
310 }
326 }
311
327
328+-- | A set of predicates. Construct one with 'mempty' and '<%>'.
312data Predicates n r = Predicates
329data Predicates n r = Predicates
313 { reqPreds :: RequestPredicate n r
330 { reqPreds :: RequestPredicate n r
314 , respPreds :: ResponsePredicate n r
331 , respPreds :: ResponsePredicate n r
@@ -339,7 +356,7 @@ instance JoinPreds (ResponsePredicate Text Bool) where
339--
356--
340-- > not500 <%> onlyJsonObjects <%> empty
357-- > not500 <%> onlyJsonObjects <%> empty
341--
358--
342−-- #SINCE#
359+-- /Since 0.0.0.0/
343(<%>) :: JoinPreds a => a -> Predicates [Text] [Text] -> Predicates [Text] [Text]
360(<%>) :: JoinPreds a => a -> Predicates [Text] [Text] -> Predicates [Text] [Text]
344(<%>) = joinPreds
361(<%>) = joinPreds
345infixr 6 <%>
362infixr 6 <%>
src/Servant/QuickCheck/Internal/QuickCheck.hs+4−4
@@ -25,7 +25,7 @@ import Servant.QuickCheck.Internal.Equality
25-- | Start a servant application on an open port, run the provided function,
25-- | Start a servant application on an open port, run the provided function,
26-- then stop the application.
26-- then stop the application.
27--
27--
28−-- #SINCE#
28+-- /Since 0.0.0.0/
29withServantServer :: HasServer a '[] => Proxy a -> IO (Server a)
29withServantServer :: HasServer a '[] => Proxy a -> IO (Server a)
30 -> (BaseUrl -> IO r) -> IO r
30 -> (BaseUrl -> IO r) -> IO r
31withServantServer api = withServantServerAndContext api EmptyContext
31withServantServer api = withServantServerAndContext api EmptyContext
@@ -33,7 +33,7 @@ withServantServer api = withServantServerAndContext api EmptyContext
33-- | Like 'withServantServer', but allows passing in a 'Context' to the
33-- | Like 'withServantServer', but allows passing in a 'Context' to the
34-- application.
34-- application.
35--
35--
36−-- #SINCE#
36+-- /Since 0.0.0.0/
37withServantServerAndContext :: HasServer a ctx
37withServantServerAndContext :: HasServer a ctx
38 => Proxy a -> Context ctx -> IO (Server a) -> (BaseUrl -> IO r) -> IO r
38 => Proxy a -> Context ctx -> IO (Server a) -> (BaseUrl -> IO r) -> IO r
39withServantServerAndContext api ctx server t
39withServantServerAndContext api ctx server t
@@ -52,7 +52,7 @@ withServantServerAndContext api ctx server t
52-- Evidently, if the behaviour of the server is expected to be
52-- Evidently, if the behaviour of the server is expected to be
53-- non-deterministic, this function may produce spurious failures
53-- non-deterministic, this function may produce spurious failures
54--
54--
55−-- #SINCE#
55+-- /Since 0.0.0.0/
56serversEqual :: HasGenRequest a =>
56serversEqual :: HasGenRequest a =>
57 Proxy a -> BaseUrl -> BaseUrl -> Args -> ResponseEquality LBS.ByteString -> Expectation
57 Proxy a -> BaseUrl -> BaseUrl -> Args -> ResponseEquality LBS.ByteString -> Expectation
58serversEqual api burl1 burl2 args req = do
58serversEqual api burl1 burl2 args req = do
@@ -86,7 +86,7 @@ serversEqual api burl1 burl2 args req = do
86-- > <%> notAllowedContainsAllowHeader
86-- > <%> notAllowedContainsAllowHeader
87-- > <%> mempty)
87-- > <%> mempty)
88--
88--
89−-- #SINCE#
89+-- /Since 0.0.0.0/
90serverSatisfies :: (HasGenRequest a) =>
90serverSatisfies :: (HasGenRequest a) =>
91 Proxy a -> BaseUrl -> Args -> Predicates [Text] [Text] -> Expectation
91 Proxy a -> BaseUrl -> Args -> Predicates [Text] [Text] -> Expectation
92serverSatisfies api burl args preds = do
92serverSatisfies api burl args preds = do