@@ -8,7 +8,6 @@ import Prelude ()
8
8
import Prelude.Compat
9
9
10
10
import Control.Lens.Operators
11
- import Control.Monad (filterM )
12
11
import Data.Aeson
13
12
import Data.Aeson.Types
14
13
import qualified Data.HashMap.Strict.InsOrd as M
@@ -19,8 +18,10 @@ import qualified Data.Set as S
19
18
import Data.OpenApi
20
19
import Data.OpenApi.Declare
21
20
import Data.OpenApi.Internal.Schema.Validation (inferSchemaTypes )
21
+ import Data.Text (Text )
22
22
import qualified Data.Text as T
23
23
import qualified Data.Vector as V
24
+ import GHC.Stack (HasCallStack )
24
25
import Test.QuickCheck (arbitrary )
25
26
import Test.QuickCheck.Gen
26
27
import Test.QuickCheck.Property
@@ -29,16 +30,19 @@ import Data.OpenApi.Aeson.Compat (fromInsOrdHashMap)
29
30
30
31
-- | Note: 'schemaGen' may 'error', if schema type is not specified,
31
32
-- and cannot be inferred.
32
- schemaGen :: Definitions Schema -> Schema -> Gen Value
33
- schemaGen _ schema
33
+ schemaGen :: HasCallStack => Definitions Schema -> Schema -> Gen Value
34
+ schemaGen = schemaGenWithFormats (const Nothing )
35
+
36
+ schemaGenWithFormats :: HasCallStack => (Format -> Maybe (Gen Text )) -> Definitions Schema -> Schema -> Gen Value
37
+ schemaGenWithFormats _ _ schema
34
38
| Just cases <- schema ^. enum_ = elements cases
35
- schemaGen defns schema
39
+ schemaGenWithFormats _ defns schema
36
40
| Just variants <- schema ^. oneOf = schemaGen defns =<< elements (dereference defns <$> variants)
37
- schemaGen defns schema =
41
+ schemaGenWithFormats formatGen defns schema =
38
42
case schema ^. type_ of
39
43
Nothing ->
40
44
case inferSchemaTypes schema of
41
- [ inferredType ] -> schemaGen defns (schema & type_ ?~ inferredType)
45
+ [ inferredType ] -> schemaGenWithFormats formatGen defns (schema & type_ ?~ inferredType)
42
46
-- Gen is not MonadFail
43
47
_ -> error " unable to infer schema type"
44
48
Just OpenApiBoolean -> Bool <$> elements [True , False ]
@@ -65,12 +69,16 @@ schemaGen defns schema =
65
69
minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minItems
66
70
maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxItems
67
71
arrayLength <- choose (minLength', max minLength' maxLength')
68
- generatedArray <- vectorOf arrayLength $ schemaGen defns itemSchema
72
+ generatedArray <- vectorOf arrayLength $ schemaGenWithFormats formatGen defns itemSchema
69
73
return . Array $ V. fromList generatedArray
70
74
OpenApiItemsArray refs ->
71
- let itemGens = schemaGen defns . dereference defns <$> refs
75
+ let itemGens = schemaGenWithFormats formatGen defns . dereference defns <$> refs
72
76
in fmap (Array . V. fromList) $ sequence itemGens
73
- Just OpenApiString -> do
77
+ | otherwise -> error " invalid array"
78
+ Just OpenApiString
79
+ | Just gen <- formatGen =<< schema ^. format ->
80
+ String <$> gen
81
+ | otherwise -> do
74
82
size <- getSize
75
83
let minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minLength
76
84
let maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxLength
@@ -90,11 +98,11 @@ schemaGen defns schema =
90
98
numProps <- choose (minProps', max minProps' maxProps')
91
99
let presentKeys = take numProps $ S. toList reqKeys ++ shuffledOptional
92
100
let presentProps = M. filterWithKey (\ k _ -> k `elem` presentKeys) props
93
- let gens = schemaGen defns <$> presentProps
101
+ let gens = schemaGenWithFormats formatGen defns <$> presentProps
94
102
additionalGens <- case schema ^. additionalProperties of
95
103
Just (AdditionalPropertiesSchema addlSchema) -> do
96
104
additionalKeys <- sequence . take (numProps - length presentProps) . repeat $ T. pack <$> arbitrary
97
- return . M. fromList $ zip additionalKeys (repeat . schemaGen defns $ dereference defns addlSchema)
105
+ return . M. fromList $ zip additionalKeys (repeat . schemaGenWithFormats formatGen defns $ dereference defns addlSchema)
98
106
_ -> return []
99
107
x <- sequence $ gens <> additionalGens
100
108
return . Object $ fromInsOrdHashMap x
0 commit comments