Servant.Swagger.Internal.Test

servant-swagger-1.1.3.1: Generate Swagger specification for your servant API.

Safe Haskell | None
Language | Haskell2010

Servant.Swagger.Internal.Test

Contents

- QuickCheck-related stuff

Synopsis

- validateEveryToJSON :: forall proxy api. TMap (Every '[Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => proxy api -> Spec
- validateEveryToJSONWithPatternChecker :: forall proxy api. TMap (Every '[Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) => (Pattern -> Text -> Bool) -> proxy api -> Spec
- props :: forall p p'' cs xs. TMap (Every (Typeable ': (Show ': (Arbitrary ': cs)))) xs => p cs -> (forall x. EveryTF cs x => x -> Bool) -> p'' xs -> Spec

# Documentation

    >>> import Control.Applicative
    >>> import GHC.Generics
    >>> import Test.QuickCheck
    >>> :set -XDeriveGeneric
    >>> :set -XGeneralizedNewtypeDeriving
    >>> :set -XDataKinds
    >>> :set -XTypeOperators

validateEveryToJSON #

Arguments

:: TMap (Every '[Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) |
=> proxy api | Servant API.
-> Spec |

Verify that every type used with ``JSON`` content type in a servant API has compatible ``ToJSON`` and ``ToSchema`` instances using ``validateToJSON``.

NOTE: ``validateEveryToJSON`` does not perform string pattern validation. See ``validateEveryToJSONWithPatternChecker``.

``validateEveryToJSON`` will produce one ``prop`` specification for every type in the API. Each type only gets one test, even if it occurs multiple times in the API.

    >>> data User = User { name :: String, age :: Maybe Int } deriving (Show, Generic, Typeable)
    >>> newtype UserId = UserId String deriving (Show, Generic, Typeable, ToJSON, Arbitrary)
    >>> instance ToJSON User
    >>> instance ToSchema User
    >>> instance ToSchema UserId
    >>> instance Arbitrary User where arbitrary = User <$> arbitrary <*> arbitrary
    >>> type UserAPI = (Capture "user_id" UserId :> Get '[JSON] User) :<|> (ReqBody '[JSON] User :> Post '[JSON] UserId)

    >>> hspec $ context "ToJSON matches ToSchema" $ validateEveryToJSON (Proxy :: Proxy UserAPI)

    ToJSON matches ToSchema
      User
      UserId

    Finished in ... seconds
    2 examples, 0 failures

For the test to compile all body types should have the following instances:

- ``ToJSON`` and ``ToSchema`` are used to perform the validation;
- ``Typeable`` is used to name the test for each type;
- ``Show`` is used to display value for which ``ToJSON`` does not satisfy ``ToSchema``.
- ``Arbitrary`` is used to arbitrarily generate values.

If any of the instances is missing, you'll get a descriptive type error:

    >>> data Contact = Contact { fullname :: String, phone :: Integer } deriving (Show, Generic)
    >>> instance ToJSON Contact
    >>> instance ToSchema Contact
    >>> type ContactAPI = Get '[JSON] Contact
    >>> hspec $ validateEveryToJSON (Proxy :: Proxy ContactAPI)
    ...
    ...No instance for (Arbitrary Contact)
    ...  arising from a use of ‘validateEveryToJSON’
    ...

validateEveryToJSONWithPatternChecker #

Arguments

:: TMap (Every '[Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api) |
=> (Pattern -> Text -> Bool) | ``Pattern`` checker.
-> proxy api | Servant API.
-> Spec |

Verify that every type used with ``JSON`` content type in a servant API has compatible ``ToJSON`` and ``ToSchema`` instances using ``validateToJSONWithPatternChecker``.

For validation without patterns see ``validateEveryToJSON``.

# QuickCheck-related stuff

props #

Arguments

:: TMap (Every (Typeable ': (Show ': (Arbitrary ': cs)))) xs |
=> p cs | A list of constraints.
-> (forall x. EveryTF cs x => x -> Bool) | Property predicate.
-> p'' xs | A list of types.
-> Spec |

Construct property tests for each type in a list. The name for each property is the name of the corresponding type.

    >>> :{
     hspec $
       context "read . show == id" $
         props
           (Proxy :: Proxy [Eq, Show, Read])
           (\x -> read (show x) == x)
           (Proxy :: Proxy [Bool, Int, String])
    :}

    read . show == id
      Bool
      Int
      [Char]

    Finished in ... seconds
    3 examples, 0 failures