{-# LANGUAGE GADTs               #-}
{-# LANGUAGE OverloadedLists     #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Data.OpenApi.Schema.Generator where

import           Prelude                                 ()
import           Prelude.Compat

import           Control.Lens.Operators
import           Control.Monad                           (filterM)
import           Data.Aeson
import           Data.Aeson.Types
import qualified Data.HashMap.Strict.InsOrd              as M
import           Data.Maybe
import           Data.Proxy
import           Data.Scientific
import qualified Data.Set                                as S
import           Data.OpenApi
import           Data.OpenApi.Declare
import           Data.OpenApi.Internal.Schema.Validation (inferSchemaTypes)
import qualified Data.Text                               as T
import qualified Data.Vector                             as V
import           Test.QuickCheck                         (arbitrary)
import           Test.QuickCheck.Gen
import           Test.QuickCheck.Property

import Data.OpenApi.Aeson.Compat (fromInsOrdHashMap)

-- | Note: 'schemaGen' may 'error', if schema type is not specified,
-- and cannot be inferred.
schemaGen :: Definitions Schema -> Schema -> Gen Value
schemaGen :: Definitions Schema -> Schema -> Gen Value
schemaGen Definitions Schema
_ Schema
schema
    | Just [Value]
cases <- Schema
schema  Schema
-> Getting (Maybe [Value]) Schema (Maybe [Value]) -> Maybe [Value]
forall s a. s -> Getting a s a -> a
^. Getting (Maybe [Value]) Schema (Maybe [Value])
forall s a. HasEnum s a => Lens' s a
Lens' Schema (Maybe [Value])
enum_  = [Value] -> Gen Value
forall a. HasCallStack => [a] -> Gen a
elements [Value]
cases
schemaGen Definitions Schema
defns Schema
schema
    | Just [Referenced Schema]
variants <- Schema
schema Schema
-> Getting
     (Maybe [Referenced Schema]) Schema (Maybe [Referenced Schema])
-> Maybe [Referenced Schema]
forall s a. s -> Getting a s a -> a
^. Getting
  (Maybe [Referenced Schema]) Schema (Maybe [Referenced Schema])
forall s a. HasOneOf s a => Lens' s a
Lens' Schema (Maybe [Referenced Schema])
oneOf = Definitions Schema -> Schema -> Gen Value
schemaGen Definitions Schema
defns (Schema -> Gen Value) -> Gen Schema -> Gen Value
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [Schema] -> Gen Schema
forall a. HasCallStack => [a] -> Gen a
elements (Definitions Schema -> Referenced Schema -> Schema
forall a. Definitions a -> Referenced a -> a
dereference Definitions Schema
defns (Referenced Schema -> Schema) -> [Referenced Schema] -> [Schema]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Referenced Schema]
variants)
schemaGen Definitions Schema
defns Schema
schema =
    case Schema
schema Schema
-> Getting (Maybe OpenApiType) Schema (Maybe OpenApiType)
-> Maybe OpenApiType
forall s a. s -> Getting a s a -> a
^. Getting (Maybe OpenApiType) Schema (Maybe OpenApiType)
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ of
      Maybe OpenApiType
Nothing ->
        case Schema -> [OpenApiType]
inferSchemaTypes Schema
schema of
          [ Item [OpenApiType]
inferredType ] -> Definitions Schema -> Schema -> Gen Value
schemaGen Definitions Schema
defns (Schema
schema Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Item [OpenApiType]
OpenApiType
inferredType)
          -- Gen is not MonadFail
          [OpenApiType]
_ -> String -> Gen Value
forall a. HasCallStack => String -> a
error String
"unable to infer schema type"
      Just OpenApiType
OpenApiBoolean -> Bool -> Value
Bool (Bool -> Value) -> Gen Bool -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Bool] -> Gen Bool
forall a. HasCallStack => [a] -> Gen a
elements [Bool
Item [Bool]
True, Bool
Item [Bool]
False]
      Just OpenApiType
OpenApiNull    -> Value -> Gen Value
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
Null
      Just OpenApiType
OpenApiNumber
        | Just Scientific
min <- Schema
schema Schema
-> Getting (Maybe Scientific) Schema (Maybe Scientific)
-> Maybe Scientific
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Scientific) Schema (Maybe Scientific)
forall s a. HasMinimum s a => Lens' s a
Lens' Schema (Maybe Scientific)
minimum_
        , Just Scientific
max <- Schema
schema Schema
-> Getting (Maybe Scientific) Schema (Maybe Scientific)
-> Maybe Scientific
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Scientific) Schema (Maybe Scientific)
forall s a. HasMaximum s a => Lens' s a
Lens' Schema (Maybe Scientific)
maximum_ ->
            Scientific -> Value
Number (Scientific -> Value) -> (Double -> Scientific) -> Double -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Scientific
forall a. RealFloat a => a -> Scientific
fromFloatDigits (Double -> Value) -> Gen Double -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                   (Double, Double) -> Gen Double
forall a. Random a => (a, a) -> Gen a
choose (Scientific -> Double
forall a. RealFloat a => Scientific -> a
toRealFloat Scientific
min, Scientific -> Double
forall a. RealFloat a => Scientific -> a
toRealFloat Scientific
max :: Double)
        | Bool
otherwise -> Scientific -> Value
Number (Scientific -> Value) -> (Double -> Scientific) -> Double -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Double -> Scientific
forall a. RealFloat a => a -> Scientific
fromFloatDigits (Double -> Value) -> Gen Double -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Gen Double
forall a. Arbitrary a => Gen a
arbitrary :: Gen Double)
      Just OpenApiType
OpenApiInteger
        | Just Scientific
min <- Schema
schema Schema
-> Getting (Maybe Scientific) Schema (Maybe Scientific)
-> Maybe Scientific
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Scientific) Schema (Maybe Scientific)
forall s a. HasMinimum s a => Lens' s a
Lens' Schema (Maybe Scientific)
minimum_
        , Just Scientific
max <- Schema
schema Schema
-> Getting (Maybe Scientific) Schema (Maybe Scientific)
-> Maybe Scientific
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Scientific) Schema (Maybe Scientific)
forall s a. HasMaximum s a => Lens' s a
Lens' Schema (Maybe Scientific)
maximum_ ->
            Scientific -> Value
Number (Scientific -> Value)
-> (Integer -> Scientific) -> Integer -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Scientific
forall a. Num a => Integer -> a
fromInteger (Integer -> Value) -> Gen Integer -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                   (Integer, Integer) -> Gen Integer
forall a. Random a => (a, a) -> Gen a
choose (Scientific -> Integer
forall b. Integral b => Scientific -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate Scientific
min, Scientific -> Integer
forall b. Integral b => Scientific -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate Scientific
max)
        | Bool
otherwise -> Scientific -> Value
Number (Scientific -> Value)
-> (Integer -> Scientific) -> Integer -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Scientific
forall a. Num a => Integer -> a
fromInteger (Integer -> Value) -> Gen Integer -> Gen Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
      Just OpenApiType
OpenApiArray
        | Just Integer
0 <- Schema
schema Schema
-> Getting (Maybe Integer) Schema (Maybe Integer) -> Maybe Integer
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Integer) Schema (Maybe Integer)
forall s a. HasMaxLength s a => Lens' s a
Lens' Schema (Maybe Integer)
maxLength -> Value -> Gen Value
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> Gen Value) -> Value -> Gen Value
forall a b. (a -> b) -> a -> b
$ Array -> Value
Array Array
forall a. Vector a
V.empty
        | Just OpenApiItems
items <- Schema
schema Schema
-> Getting (Maybe OpenApiItems) Schema (Maybe OpenApiItems)
-> Maybe OpenApiItems
forall s a. s -> Getting a s a -> a
^. Getting (Maybe OpenApiItems) Schema (Maybe OpenApiItems)
forall s a. HasItems s a => Lens' s a
Lens' Schema (Maybe OpenApiItems)
items ->
            case OpenApiItems
items of
              OpenApiItemsObject Referenced Schema
ref -> do
                  size <- Gen Int
getSize
                  let itemSchema = Definitions Schema -> Referenced Schema -> Schema
forall a. Definitions a -> Referenced a -> a
dereference Definitions Schema
defns Referenced Schema
ref
                      minLength' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Maybe Integer -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema
schema Schema
-> Getting (Maybe Integer) Schema (Maybe Integer) -> Maybe Integer
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Integer) Schema (Maybe Integer)
forall s a. HasMinItems s a => Lens' s a
Lens' Schema (Maybe Integer)
minItems
                      maxLength' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
size (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Maybe Integer -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema
schema Schema
-> Getting (Maybe Integer) Schema (Maybe Integer) -> Maybe Integer
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Integer) Schema (Maybe Integer)
forall s a. HasMaxItems s a => Lens' s a
Lens' Schema (Maybe Integer)
maxItems
                  arrayLength <- choose (minLength', max minLength' maxLength')
                  generatedArray <- vectorOf arrayLength $ schemaGen defns itemSchema
                  return . Array $ V.fromList generatedArray
              OpenApiItemsArray [Referenced Schema]
refs ->
                  let itemGens :: [Gen Value]
itemGens = Definitions Schema -> Schema -> Gen Value
schemaGen Definitions Schema
defns (Schema -> Gen Value)
-> (Referenced Schema -> Schema) -> Referenced Schema -> Gen Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Definitions Schema -> Referenced Schema -> Schema
forall a. Definitions a -> Referenced a -> a
dereference Definitions Schema
defns (Referenced Schema -> Gen Value)
-> [Referenced Schema] -> [Gen Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Referenced Schema]
refs
                  in ([Value] -> Value) -> Gen [Value] -> Gen Value
forall a b. (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Array -> Value
Array (Array -> Value) -> ([Value] -> Array) -> [Value] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Value] -> Array
forall a. [a] -> Vector a
V.fromList) (Gen [Value] -> Gen Value) -> Gen [Value] -> Gen Value
forall a b. (a -> b) -> a -> b
$ [Gen Value] -> Gen [Value]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [Gen Value]
itemGens
      Just OpenApiType
OpenApiString -> do
        size <- Gen Int
getSize
        let minLength' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Maybe Integer -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema
schema Schema
-> Getting (Maybe Integer) Schema (Maybe Integer) -> Maybe Integer
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Integer) Schema (Maybe Integer)
forall s a. HasMinLength s a => Lens' s a
Lens' Schema (Maybe Integer)
minLength
        let maxLength' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
size (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Maybe Integer -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema
schema Schema
-> Getting (Maybe Integer) Schema (Maybe Integer) -> Maybe Integer
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Integer) Schema (Maybe Integer)
forall s a. HasMaxLength s a => Lens' s a
Lens' Schema (Maybe Integer)
maxLength
        length <- choose (minLength', max minLength' maxLength')
        str <- vectorOf length arbitrary
        return . String $ T.pack str
      Just OpenApiType
OpenApiObject -> do
          size <- Gen Int
getSize
          let props = Definitions Schema -> Referenced Schema -> Schema
forall a. Definitions a -> Referenced a -> a
dereference Definitions Schema
defns (Referenced Schema -> Schema)
-> InsOrdHashMap Text (Referenced Schema) -> Definitions Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema
schema Schema
-> Getting
     (InsOrdHashMap Text (Referenced Schema))
     Schema
     (InsOrdHashMap Text (Referenced Schema))
-> InsOrdHashMap Text (Referenced Schema)
forall s a. s -> Getting a s a -> a
^. Getting
  (InsOrdHashMap Text (Referenced Schema))
  Schema
  (InsOrdHashMap Text (Referenced Schema))
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
properties
              reqKeys = [Text] -> Set Text
forall a. Ord a => [a] -> Set a
S.fromList ([Text] -> Set Text) -> [Text] -> Set Text
forall a b. (a -> b) -> a -> b
$ Schema
schema Schema -> Getting [Text] Schema [Text] -> [Text]
forall s a. s -> Getting a s a -> a
^. Getting [Text] Schema [Text]
forall s a. HasRequired s a => Lens' s a
Lens' Schema [Text]
required
              allKeys = [Text] -> Set Text
forall a. Ord a => [a] -> Set a
S.fromList ([Text] -> Set Text)
-> (InsOrdHashMap Text (Referenced Schema) -> [Text])
-> InsOrdHashMap Text (Referenced Schema)
-> Set Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsOrdHashMap Text (Referenced Schema) -> [Text]
forall k v. InsOrdHashMap k v -> [k]
M.keys (InsOrdHashMap Text (Referenced Schema) -> Set Text)
-> InsOrdHashMap Text (Referenced Schema) -> Set Text
forall a b. (a -> b) -> a -> b
$ Schema
schema Schema
-> Getting
     (InsOrdHashMap Text (Referenced Schema))
     Schema
     (InsOrdHashMap Text (Referenced Schema))
-> InsOrdHashMap Text (Referenced Schema)
forall s a. s -> Getting a s a -> a
^. Getting
  (InsOrdHashMap Text (Referenced Schema))
  Schema
  (InsOrdHashMap Text (Referenced Schema))
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
properties
              optionalKeys = Set Text
allKeys Set Text -> Set Text -> Set Text
forall a. Ord a => Set a -> Set a -> Set a
S.\\ Set Text
reqKeys
              minProps' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (Set Text -> Int
forall a. Set a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Set Text
reqKeys) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$
                            Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Maybe Integer -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema
schema Schema
-> Getting (Maybe Integer) Schema (Maybe Integer) -> Maybe Integer
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Integer) Schema (Maybe Integer)
forall s a. HasMinProperties s a => Lens' s a
Lens' Schema (Maybe Integer)
minProperties
              maxProps' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
size (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Maybe Integer -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Schema
schema Schema
-> Getting (Maybe Integer) Schema (Maybe Integer) -> Maybe Integer
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Integer) Schema (Maybe Integer)
forall s a. HasMaxProperties s a => Lens' s a
Lens' Schema (Maybe Integer)
maxProperties
          shuffledOptional <- shuffle $ S.toList optionalKeys
          numProps <- choose (minProps', max minProps' maxProps')
          let presentKeys = Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
take Int
numProps ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Set Text -> [Text]
forall a. Set a -> [a]
S.toList Set Text
reqKeys [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
shuffledOptional
          let presentProps = (Text -> Schema -> Bool)
-> Definitions Schema -> Definitions Schema
forall k v.
(k -> v -> Bool) -> InsOrdHashMap k v -> InsOrdHashMap k v
M.filterWithKey (\Text
k Schema
_ -> Text
k Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
presentKeys) Definitions Schema
props
          let gens = Definitions Schema -> Schema -> Gen Value
schemaGen Definitions Schema
defns (Schema -> Gen Value)
-> Definitions Schema -> InsOrdHashMap Text (Gen Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Definitions Schema
presentProps
          additionalGens <- case schema ^. additionalProperties of
            Just (AdditionalPropertiesSchema Referenced Schema
addlSchema) -> do
              additionalKeys <- [Gen Text] -> Gen [Text]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ([Gen Text] -> Gen [Text])
-> (Gen Text -> [Gen Text]) -> Gen Text -> Gen [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Gen Text] -> [Gen Text]
forall a. Int -> [a] -> [a]
take (Int
numProps Int -> Int -> Int
forall a. Num a => a -> a -> a
- Definitions Schema -> Int
forall a. InsOrdHashMap Text a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Definitions Schema
presentProps) ([Gen Text] -> [Gen Text])
-> (Gen Text -> [Gen Text]) -> Gen Text -> [Gen Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Gen Text -> [Gen Text]
forall a. a -> [a]
repeat (Gen Text -> Gen [Text]) -> Gen Text -> Gen [Text]
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> Gen String -> Gen Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
forall a. Arbitrary a => Gen a
arbitrary
              return . M.fromList $ zip additionalKeys (repeat . schemaGen defns $ dereference defns addlSchema)
            Maybe AdditionalProperties
_                                      -> InsOrdHashMap Text (Gen Value)
-> Gen (InsOrdHashMap Text (Gen Value))
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return []
          x <- sequence $ gens <> additionalGens
          return . Object $ fromInsOrdHashMap x

dereference :: Definitions a -> Referenced a -> a
dereference :: forall a. Definitions a -> Referenced a -> a
dereference Definitions a
_ (Inline a
a)               = a
a
dereference Definitions a
defs (Ref (Reference Text
ref)) = Maybe a -> a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe a -> a) -> Maybe a -> a
forall a b. (a -> b) -> a -> b
$ Text -> Definitions a -> Maybe a
forall k v. (Eq k, Hashable k) => k -> InsOrdHashMap k v -> Maybe v
M.lookup Text
ref Definitions a
defs

genValue :: (ToSchema a) => Proxy a -> Gen Value
genValue :: forall a. ToSchema a => Proxy a -> Gen Value
genValue Proxy a
p =
 let (Definitions Schema
defs, NamedSchema Maybe Text
_ Schema
schema) = Declare (Definitions Schema) NamedSchema
-> Definitions Schema -> (Definitions Schema, NamedSchema)
forall d a. Declare d a -> d -> (d, a)
runDeclare (Proxy a -> Declare (Definitions Schema) NamedSchema
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy a
p) Definitions Schema
forall k v. InsOrdHashMap k v
M.empty
 in Definitions Schema -> Schema -> Gen Value
schemaGen Definitions Schema
defs Schema
schema

validateFromJSON :: forall a . (ToSchema a, FromJSON a) => Proxy a -> Property
validateFromJSON :: forall a. (ToSchema a, FromJSON a) => Proxy a -> Property
validateFromJSON Proxy a
p = Gen Value -> (Value -> Result) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll (Proxy a -> Gen Value
forall a. ToSchema a => Proxy a -> Gen Value
genValue Proxy a
p) ((Value -> Result) -> Property) -> (Value -> Result) -> Property
forall a b. (a -> b) -> a -> b
$
                       \Value
val -> case (Value -> Parser a) -> Value -> Either String a
forall a b. (a -> Parser b) -> a -> Either String b
parseEither Value -> Parser a
forall a. FromJSON a => Value -> Parser a
parseJSON Value
val of
                                 Right (a
_ :: a) -> Result
succeeded
                                 Left String
err -> Result
failed
                                               { reason = err
                                               }