Documentation improvements
This commit is contained in:
parent
fe1d87df85
commit
b5ee965d1c
@ -6,14 +6,37 @@
|
|||||||
-- tested itself need not be implemented with @servant-server@ (or indeed,
|
-- tested itself need not be implemented with @servant-server@ (or indeed,
|
||||||
-- written in Haskell).
|
-- written in Haskell).
|
||||||
--
|
--
|
||||||
|
-- The documentation of the <#useful-preds Useful predicates> sections is
|
||||||
|
-- meant to serve as a set of helpful pointers for learning more about best
|
||||||
|
-- practices concerning REST APIs.
|
||||||
module Servant.QuickCheck
|
module Servant.QuickCheck
|
||||||
(
|
(
|
||||||
|
|
||||||
|
-- * Property testing
|
||||||
-- * Test setup helpers
|
serverSatisfies
|
||||||
-- | Helpers to setup and teardown @servant@ servers during tests.
|
-- ** Predicates
|
||||||
withServantServer
|
-- *** #useful-preds# Useful predicates
|
||||||
|
-- | The predicates below are often useful. Some check RFC compliance; some are
|
||||||
|
-- best practice, and some are useful to check that APIs follow in-house
|
||||||
|
-- best-practices. Included in the documentation for each is a list of
|
||||||
|
-- references to any relevant RFCs and other links, as well as what type of
|
||||||
|
-- predicate it is (__RFC Compliance__, __Best Practice__, __Optional__).
|
||||||
|
--
|
||||||
|
-- RFCs distinguish between the force of requirements (e.g. __MUST__ vs.
|
||||||
|
-- __SHOULD__). __RFC Compliance__ includes any absolute requirements present
|
||||||
|
-- in RFCs. The __Best Practices__ includes, in addition to RFC
|
||||||
|
-- recommendations, recommendations found elsewhere or generally accepted.
|
||||||
|
, not500
|
||||||
|
, onlyJsonObjects
|
||||||
|
, notAllowedContainsAllowHeader
|
||||||
|
, unauthorizedContainsWWWAuthenticate
|
||||||
|
, getsHaveCacheControlHeader
|
||||||
|
, headsHaveCacheControlHeader
|
||||||
|
-- *** Predicate utilities and types
|
||||||
|
, (<%>)
|
||||||
|
, Predicates
|
||||||
|
, ResponsePredicate(..)
|
||||||
|
, RequestPredicate(..)
|
||||||
|
|
||||||
-- * Equality testing
|
-- * Equality testing
|
||||||
, serversEqual
|
, serversEqual
|
||||||
@ -28,19 +51,10 @@ module Servant.QuickCheck
|
|||||||
-- ** Response equality type
|
-- ** Response equality type
|
||||||
, ResponseEquality(..)
|
, ResponseEquality(..)
|
||||||
|
|
||||||
-- * Property testing
|
-- * Test setup helpers
|
||||||
, serverSatisfies
|
-- | Helpers to setup and teardown @servant@ servers during tests.
|
||||||
-- ** Predicates
|
, withServantServer
|
||||||
-- *** Useful predicates
|
, withServantServerAndContext
|
||||||
, not500
|
|
||||||
, onlyJsonObjects
|
|
||||||
, notAllowedContainsAllowHeader
|
|
||||||
, unauthorizedContainsWWWAuthenticate
|
|
||||||
-- *** Predicate utilities and types
|
|
||||||
, (<%>)
|
|
||||||
, Predicates
|
|
||||||
, ResponsePredicate(..)
|
|
||||||
, RequestPredicate(..)
|
|
||||||
|
|
||||||
-- ** Re-exports
|
-- ** Re-exports
|
||||||
, BaseUrl(..)
|
, BaseUrl(..)
|
||||||
|
|||||||
@ -1,22 +1,28 @@
|
|||||||
|
{-# LANGUAGE MultiWayIf #-}
|
||||||
module Servant.QuickCheck.Internal.Predicates where
|
module Servant.QuickCheck.Internal.Predicates where
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.Aeson (Object, decode)
|
import Data.Aeson (Object, decode)
|
||||||
import Data.Bifunctor (Bifunctor (..))
|
import Data.Bifunctor (Bifunctor (..))
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
import qualified Data.ByteString as SBS
|
||||||
import qualified Data.ByteString as SBS
|
|
||||||
import qualified Data.ByteString.Char8 as SBSC
|
import qualified Data.ByteString.Char8 as SBSC
|
||||||
import Data.CaseInsensitive (mk)
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
import Data.Either (isRight)
|
import Data.CaseInsensitive (mk)
|
||||||
import Data.List.Split (wordsBy)
|
import Data.Either (isRight)
|
||||||
import Data.Monoid ((<>))
|
import Data.List.Split (wordsBy)
|
||||||
import Data.Text (Text)
|
import Data.Maybe (isJust)
|
||||||
import GHC.Generics (Generic)
|
import Data.Monoid ((<>))
|
||||||
import Network.HTTP.Client (Manager, Request, Response, httpLbs,
|
import Data.Text (Text)
|
||||||
responseBody, responseStatus, responseHeaders)
|
import GHC.Generics (Generic)
|
||||||
import Network.HTTP.Types (status500, status405, status401, parseMethod)
|
import Network.HTTP.Client (Manager, Request, Response, httpLbs,
|
||||||
|
method, responseBody, responseHeaders,
|
||||||
|
responseStatus)
|
||||||
|
import Network.HTTP.Types (methodGet, methodHead, parseMethod,
|
||||||
|
status401, renderStdMethod, status405, status500)
|
||||||
|
|
||||||
-- | @500 Internal Server Error@ should be avoided - it may represent some
|
-- | [__Best Practice__]
|
||||||
|
--
|
||||||
|
-- @500 Internal Server Error@ should be avoided - it may represent some
|
||||||
-- issue with the application code, and it moreover gives the client little
|
-- issue with the application code, and it moreover gives the client little
|
||||||
-- indication of how to proceed or what went wrong.
|
-- indication of how to proceed or what went wrong.
|
||||||
--
|
--
|
||||||
@ -24,7 +30,9 @@ import Network.HTTP.Types (status500, status405, status401, parseMet
|
|||||||
not500 :: ResponsePredicate Text Bool
|
not500 :: ResponsePredicate Text Bool
|
||||||
not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == status500)
|
not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == status500)
|
||||||
|
|
||||||
-- | Returning anything other than an object when returning JSON is considered
|
-- | [__Best Practice__]
|
||||||
|
--
|
||||||
|
-- Returning anything other than an object when returning JSON is considered
|
||||||
-- bad practice, as:
|
-- bad practice, as:
|
||||||
--
|
--
|
||||||
-- (1) it is hard to modify the returned value while maintaining backwards
|
-- (1) it is hard to modify the returned value while maintaining backwards
|
||||||
@ -66,8 +74,11 @@ getsHaveLastModifiedHeader
|
|||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
-- | When an HTTP request has a method that is not allowed, a 405 response
|
-- | [__RFC Compliance__]
|
||||||
-- should be returned. Additionally, it is good practice to return an @Allow@
|
--
|
||||||
|
-- When an HTTP request has a method that is not allowed,
|
||||||
|
-- a 405 response should be returned. Additionally, it is good practice to
|
||||||
|
-- return an @Allow@
|
||||||
-- header with the list of allowed methods.
|
-- header with the list of allowed methods.
|
||||||
--
|
--
|
||||||
-- This function checks that every @405 Method Not Allowed@ response contains
|
-- This function checks that every @405 Method Not Allowed@ response contains
|
||||||
@ -163,7 +174,9 @@ linkHeadersAreValid
|
|||||||
= ResponsePredicate "linkHeadersAreValid" _
|
= ResponsePredicate "linkHeadersAreValid" _
|
||||||
|
|
||||||
-}
|
-}
|
||||||
-- | Any @401 Unauthorized@ response must include a @WWW-Authenticate@ header.
|
-- | [__RFC Compliance__]
|
||||||
|
--
|
||||||
|
-- Any @401 Unauthorized@ response must include a @WWW-Authenticate@ header.
|
||||||
--
|
--
|
||||||
-- This function checks that, if a response has status code 401, it contains a
|
-- This function checks that, if a response has status code 401, it contains a
|
||||||
-- @WWW-Authenticate@ header.
|
-- @WWW-Authenticate@ header.
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
-- | This module contains wrappers around lower-level functionality.
|
|
||||||
module Servant.QuickCheck.Internal.QuickCheck where
|
module Servant.QuickCheck.Internal.QuickCheck where
|
||||||
|
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
@ -8,13 +7,14 @@ import Network.HTTP.Client (Manager, Request, checkStatus,
|
|||||||
defaultManagerSettings, httpLbs,
|
defaultManagerSettings, httpLbs,
|
||||||
newManager)
|
newManager)
|
||||||
import Network.Wai.Handler.Warp (withApplication)
|
import Network.Wai.Handler.Warp (withApplication)
|
||||||
import Servant (HasServer, Server, serve)
|
import Servant (Context (EmptyContext), HasServer,
|
||||||
|
Server, serveWithContext)
|
||||||
import Servant.Client (BaseUrl (..), Scheme (..))
|
import Servant.Client (BaseUrl (..), Scheme (..))
|
||||||
import System.IO.Unsafe (unsafePerformIO)
|
import System.IO.Unsafe (unsafePerformIO)
|
||||||
import Test.Hspec (Expectation, expectationFailure)
|
import Test.Hspec (Expectation, expectationFailure)
|
||||||
import Test.QuickCheck (Args (..), Result (..),
|
import Test.QuickCheck (Args (..), Result (..),
|
||||||
quickCheckWithResult)
|
quickCheckWithResult)
|
||||||
import Test.QuickCheck.Monadic
|
import Test.QuickCheck.Monadic (assert, forAllM, monadicIO, run)
|
||||||
|
|
||||||
import Servant.QuickCheck.Internal.HasGenRequest
|
import Servant.QuickCheck.Internal.HasGenRequest
|
||||||
import Servant.QuickCheck.Internal.Predicates
|
import Servant.QuickCheck.Internal.Predicates
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user