@@ -8,7 +8,6 @@ import Prelude ()
88import Prelude.Compat
99
1010import Control.Lens.Operators
11- import Control.Monad (filterM )
1211import Data.Aeson
1312import Data.Aeson.Types
1413import qualified Data.HashMap.Strict.InsOrd as M
@@ -19,24 +18,29 @@ import qualified Data.Set as S
1918import Data.OpenApi
2019import Data.OpenApi.Declare
2120import Data.OpenApi.Internal.Schema.Validation (inferSchemaTypes )
21+ import Data.Text (Text )
2222import qualified Data.Text as T
2323import qualified Data.Vector as V
24+ import GHC.Stack (HasCallStack )
2425import Test.QuickCheck (arbitrary )
2526import Test.QuickCheck.Gen
2627import Test.QuickCheck.Property
2728
2829-- | Note: 'schemaGen' may 'error', if schema type is not specified,
2930-- and cannot be inferred.
30- schemaGen :: Definitions Schema -> Schema -> Gen Value
31- schemaGen _ schema
31+ schemaGen :: HasCallStack => Definitions Schema -> Schema -> Gen Value
32+ schemaGen = schemaGenWithFormats (const Nothing )
33+
34+ schemaGenWithFormats :: HasCallStack => (Format -> Maybe (Gen Text )) -> Definitions Schema -> Schema -> Gen Value
35+ schemaGenWithFormats _ _ schema
3236 | Just cases <- schema ^. enum_ = elements cases
33- schemaGen defns schema
37+ schemaGenWithFormats _ defns schema
3438 | Just variants <- schema ^. oneOf = schemaGen defns =<< elements (dereference defns <$> variants)
35- schemaGen defns schema =
39+ schemaGenWithFormats formatGen defns schema =
3640 case schema ^. type_ of
3741 Nothing ->
3842 case inferSchemaTypes schema of
39- [ inferredType ] -> schemaGen defns (schema & type_ ?~ inferredType)
43+ [ inferredType ] -> schemaGenWithFormats formatGen defns (schema & type_ ?~ inferredType)
4044 -- Gen is not MonadFail
4145 _ -> error " unable to infer schema type"
4246 Just OpenApiBoolean -> Bool <$> elements [True , False ]
@@ -63,12 +67,16 @@ schemaGen defns schema =
6367 minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minItems
6468 maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxItems
6569 arrayLength <- choose (minLength', max minLength' maxLength')
66- generatedArray <- vectorOf arrayLength $ schemaGen defns itemSchema
70+ generatedArray <- vectorOf arrayLength $ schemaGenWithFormats formatGen defns itemSchema
6771 return . Array $ V. fromList generatedArray
6872 OpenApiItemsArray refs ->
69- let itemGens = schemaGen defns . dereference defns <$> refs
73+ let itemGens = schemaGenWithFormats formatGen defns . dereference defns <$> refs
7074 in fmap (Array . V. fromList) $ sequence itemGens
71- Just OpenApiString -> do
75+ | otherwise -> error " invalid array"
76+ Just OpenApiString
77+ | Just gen <- formatGen =<< schema ^. format ->
78+ String <$> gen
79+ | otherwise -> do
7280 size <- getSize
7381 let minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minLength
7482 let maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxLength
@@ -88,11 +96,11 @@ schemaGen defns schema =
8896 numProps <- choose (minProps', max minProps' maxProps')
8997 let presentKeys = take numProps $ S. toList reqKeys ++ shuffledOptional
9098 let presentProps = M. filterWithKey (\ k _ -> k `elem` presentKeys) props
91- let gens = schemaGen defns <$> presentProps
99+ let gens = schemaGenWithFormats formatGen defns <$> presentProps
92100 additionalGens <- case schema ^. additionalProperties of
93101 Just (AdditionalPropertiesSchema addlSchema) -> do
94102 additionalKeys <- sequence . take (numProps - length presentProps) . repeat $ T. pack <$> arbitrary
95- return . M. fromList $ zip additionalKeys (repeat . schemaGen defns $ dereference defns addlSchema)
103+ return . M. fromList $ zip additionalKeys (repeat . schemaGenWithFormats formatGen defns $ dereference defns addlSchema)
96104 _ -> return []
97105 x <- sequence $ gens <> additionalGens
98106 return . Object $ M. toHashMap x
0 commit comments