HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleservant-openapi3-2.0.1.6Haskell2010

Servant.OpenApi.Internal.Test

  • 6 values
Example7 expressions
import Control.Applicativeimport GHC.Genericsimport Test.QuickCheck:set -XDeriveGeneric:set -XGeneralizedNewtypeDeriving:set -XDataKinds:set -XTypeOperators
valuevalidateEveryToJSON
  1. :: TMap (Every '[Typeable, Show, Arbitrary, ToJSON, ToSchema]) (BodyTypes JSON api)
  2. => proxy api

    Servant API.

  3. -> 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.

Example7 expressions
data User = User { name :: String, age :: Maybe Int } deriving (Show, Generic, Typeable)newtype UserId = UserId String deriving (Show, Generic, Typeable, ToJSON, Arbitrary)instance ToJSON Userinstance ToSchema Userinstance ToSchema UserIdinstance Arbitrary User where arbitrary = User <$> arbitrary <*> arbitrarytype UserAPI = (Capture "user_id" UserId :> Get '[JSON] User) :<|> (ReqBody '[JSON] User :> Post '[JSON] UserId)
Example1 expression
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:

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

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

QuickCheck-related stuff

4 declarations
valueprops
  1. :: TMap (Every (Typeable ': Show ': Arbitrary ': cs)) xs
  2. => p cs

    A list of constraints.

  3. -> (forall x. EveryTF cs x => x -> Property)

    Property predicate.

  4. -> p'' xs

    A list of types.

  5. -> Spec
#

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

Example1 expression
:{ 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...
valueprettyValidateWith
  1. :: (ToJSON a, ToSchema a)
  2. => a -> [ValidationError]
  3. -> a
  4. -> Maybe String
#

Pretty print validation errors together with actual JSON and OpenApi Schema (using encodePretty).

Example7 expressions
import Data.Aesonimport Data.Foldable (traverse_)data Person = Person { name :: String, phone :: Integer } deriving (Generic)instance ToJSON Person where toJSON p = object [ "name" .= name p ]instance ToSchema Personlet person = Person { name = "John", phone = 123456 }traverse_ putStrLn $ prettyValidateWith validateToJSON personValidation against the schema fails:  * property "phone" is required, but not found in "{\"name\":\"John\"}"JSON value:{    "name": "John"}OpenApi Schema:{    "properties": {        "name": {            "type": "string"        },        "phone": {            "type": "integer"        }    },    "required": [        "name",        "phone"    ],    "type": "object"}

FIXME: this belongs in Data.OpenApi.Schema.Validation (in swagger2).