git.iko.soy/servant-quickcheck
on master help sign in
Documentation improvements
commitb5ee965d1c97315f86bbd3bad065fabfa09828a5 authorJulian K. Arni <jkarni@gmail.com> dateMon 25 Apr 2016, 12:31 (11 years ago) parentfe1d87d
3 files changed+67−40
src/Servant/QuickCheck.hs+32−18 src/Servant/QuickCheck/Internal/Predicates.hs+32−19 src/Servant/QuickCheck/Internal/QuickCheck.hs+3−3
src/Servant/QuickCheck.hs+32−18
@@ -6,14 +6,37 @@
66-- tested itself need not be implemented with @servant-server@ (or indeed,
77-- written in Haskell).
88--
9+-- The documentation of the <#useful-preds Useful predicates> sections is
10+-- meant to serve as a set of helpful pointers for learning more about best
11+-- practices concerning REST APIs.
912module Servant.QuickCheck
1013 (
1114
12−
13− -- * Test setup helpers
14− -- | Helpers to setup and teardown @servant@ servers during tests.
15− withServantServer
16−
15+ -- * Property testing
16+ serverSatisfies
17+ -- ** Predicates
18+ -- *** #useful-preds# Useful predicates
19+ -- | The predicates below are often useful. Some check RFC compliance; some are
20+ -- best practice, and some are useful to check that APIs follow in-house
21+ -- best-practices. Included in the documentation for each is a list of
22+ -- references to any relevant RFCs and other links, as well as what type of
23+ -- predicate it is (__RFC Compliance__, __Best Practice__, __Optional__).
24+ --
25+ -- RFCs distinguish between the force of requirements (e.g. __MUST__ vs.
26+ -- __SHOULD__). __RFC Compliance__ includes any absolute requirements present
27+ -- in RFCs. The __Best Practices__ includes, in addition to RFC
28+ -- recommendations, recommendations found elsewhere or generally accepted.
29+ , not500
30+ , onlyJsonObjects
31+ , notAllowedContainsAllowHeader
32+ , unauthorizedContainsWWWAuthenticate
33+ , getsHaveCacheControlHeader
34+ , headsHaveCacheControlHeader
35+ -- *** Predicate utilities and types
36+ , (<%>)
37+ , Predicates
38+ , ResponsePredicate(..)
39+ , RequestPredicate(..)
1740
1841 -- * Equality testing
1942 , serversEqual
@@ -28,19 +51,10 @@ module Servant.QuickCheck
2851 -- ** Response equality type
2952 , ResponseEquality(..)
3053
31− -- * Property testing
32− , serverSatisfies
33− -- ** Predicates
34− -- *** Useful predicates
35− , not500
36− , onlyJsonObjects
37− , notAllowedContainsAllowHeader
38− , unauthorizedContainsWWWAuthenticate
39− -- *** Predicate utilities and types
40− , (<%>)
41− , Predicates
42− , ResponsePredicate(..)
43− , RequestPredicate(..)
54+ -- * Test setup helpers
55+ -- | Helpers to setup and teardown @servant@ servers during tests.
56+ , withServantServer
57+ , withServantServerAndContext
4458
4559 -- ** Re-exports
4660 , BaseUrl(..)
src/Servant/QuickCheck/Internal/Predicates.hs+32−19
@@ -1,22 +1,28 @@
1+{-# LANGUAGE MultiWayIf #-}
12module Servant.QuickCheck.Internal.Predicates where
23
34import Control.Monad
4−import Data.Aeson (Object, decode)
5−import Data.Bifunctor (Bifunctor (..))
6−import qualified Data.ByteString.Lazy as LBS
7−import qualified Data.ByteString as SBS
5+import Data.Aeson (Object, decode)
6+import Data.Bifunctor (Bifunctor (..))
7+import qualified Data.ByteString as SBS
88import qualified Data.ByteString.Char8 as SBSC
9−import Data.CaseInsensitive (mk)
10−import Data.Either (isRight)
11−import Data.List.Split (wordsBy)
12−import Data.Monoid ((<>))
13−import Data.Text (Text)
14−import GHC.Generics (Generic)
15−import Network.HTTP.Client (Manager, Request, Response, httpLbs,
16− responseBody, responseStatus, responseHeaders)
17−import Network.HTTP.Types (status500, status405, status401, parseMethod)
18−
19−-- | @500 Internal Server Error@ should be avoided - it may represent some
9+import qualified Data.ByteString.Lazy as LBS
10+import Data.CaseInsensitive (mk)
11+import Data.Either (isRight)
12+import Data.List.Split (wordsBy)
13+import Data.Maybe (isJust)
14+import Data.Monoid ((<>))
15+import Data.Text (Text)
16+import GHC.Generics (Generic)
17+import Network.HTTP.Client (Manager, Request, Response, httpLbs,
18+ method, responseBody, responseHeaders,
19+ responseStatus)
20+import Network.HTTP.Types (methodGet, methodHead, parseMethod,
21+ status401, renderStdMethod, status405, status500)
22+
23+-- | [__Best Practice__]
24+--
25+-- @500 Internal Server Error@ should be avoided - it may represent some
2026-- issue with the application code, and it moreover gives the client little
2127-- indication of how to proceed or what went wrong.
2228--
@@ -24,7 +30,9 @@ import Network.HTTP.Types (status500, status405, status401, parseMet
2430not500 :: ResponsePredicate Text Bool
2531not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == status500)
2632
27−-- | Returning anything other than an object when returning JSON is considered
33+-- | [__Best Practice__]
34+--
35+-- Returning anything other than an object when returning JSON is considered
2836-- bad practice, as:
2937--
3038-- (1) it is hard to modify the returned value while maintaining backwards
@@ -66,8 +74,11 @@ getsHaveLastModifiedHeader
6674
6775-}
6876
69−-- | When an HTTP request has a method that is not allowed, a 405 response
70−-- should be returned. Additionally, it is good practice to return an @Allow@
77+-- | [__RFC Compliance__]
78+--
79+-- When an HTTP request has a method that is not allowed,
80+-- a 405 response should be returned. Additionally, it is good practice to
81+-- return an @Allow@
7182-- header with the list of allowed methods.
7283--
7384-- This function checks that every @405 Method Not Allowed@ response contains
@@ -163,7 +174,9 @@ linkHeadersAreValid
163174 = ResponsePredicate "linkHeadersAreValid" _
164175
165176-}
166−-- | Any @401 Unauthorized@ response must include a @WWW-Authenticate@ header.
177+-- | [__RFC Compliance__]
178+--
179+-- Any @401 Unauthorized@ response must include a @WWW-Authenticate@ header.
167180--
168181-- This function checks that, if a response has status code 401, it contains a
169182-- @WWW-Authenticate@ header.
src/Servant/QuickCheck/Internal/QuickCheck.hs+3−3
@@ -1,4 +1,3 @@
1−-- | This module contains wrappers around lower-level functionality.
21module Servant.QuickCheck.Internal.QuickCheck where
32
43import qualified Data.ByteString.Lazy as LBS
@@ -8,13 +7,14 @@ import Network.HTTP.Client (Manager, Request, checkStatus,
87 defaultManagerSettings, httpLbs,
98 newManager)
109import Network.Wai.Handler.Warp (withApplication)
11−import Servant (HasServer, Server, serve)
10+import Servant (Context (EmptyContext), HasServer,
11+ Server, serveWithContext)
1212import Servant.Client (BaseUrl (..), Scheme (..))
1313import System.IO.Unsafe (unsafePerformIO)
1414import Test.Hspec (Expectation, expectationFailure)
1515import Test.QuickCheck (Args (..), Result (..),
1616 quickCheckWithResult)
17−import Test.QuickCheck.Monadic
17+import Test.QuickCheck.Monadic (assert, forAllM, monadicIO, run)
1818
1919import Servant.QuickCheck.Internal.HasGenRequest
2020import Servant.QuickCheck.Internal.Predicates