@@ -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,24 +18,29 @@ 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
27
28
28
29
-- | Note: 'schemaGen' may 'error', if schema type is not specified,
29
30
-- 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
32
36
| Just cases <- schema ^. enum_ = elements cases
33
- schemaGen defns schema
37
+ schemaGenWithFormats _ defns schema
34
38
| Just variants <- schema ^. oneOf = schemaGen defns =<< elements (dereference defns <$> variants)
35
- schemaGen defns schema =
39
+ schemaGenWithFormats formatGen defns schema =
36
40
case schema ^. type_ of
37
41
Nothing ->
38
42
case inferSchemaTypes schema of
39
- [ inferredType ] -> schemaGen defns (schema & type_ ?~ inferredType)
43
+ [ inferredType ] -> schemaGenWithFormats formatGen defns (schema & type_ ?~ inferredType)
40
44
-- Gen is not MonadFail
41
45
_ -> error " unable to infer schema type"
42
46
Just OpenApiBoolean -> Bool <$> elements [True , False ]
@@ -63,12 +67,16 @@ schemaGen defns schema =
63
67
minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minItems
64
68
maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxItems
65
69
arrayLength <- choose (minLength', max minLength' maxLength')
66
- generatedArray <- vectorOf arrayLength $ schemaGen defns itemSchema
70
+ generatedArray <- vectorOf arrayLength $ schemaGenWithFormats formatGen defns itemSchema
67
71
return . Array $ V. fromList generatedArray
68
72
OpenApiItemsArray refs ->
69
- let itemGens = schemaGen defns . dereference defns <$> refs
73
+ let itemGens = schemaGenWithFormats formatGen defns . dereference defns <$> refs
70
74
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
72
80
size <- getSize
73
81
let minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minLength
74
82
let maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxLength
@@ -88,11 +96,11 @@ schemaGen defns schema =
88
96
numProps <- choose (minProps', max minProps' maxProps')
89
97
let presentKeys = take numProps $ S. toList reqKeys ++ shuffledOptional
90
98
let presentProps = M. filterWithKey (\ k _ -> k `elem` presentKeys) props
91
- let gens = schemaGen defns <$> presentProps
99
+ let gens = schemaGenWithFormats formatGen defns <$> presentProps
92
100
additionalGens <- case schema ^. additionalProperties of
93
101
Just (AdditionalPropertiesSchema addlSchema) -> do
94
102
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)
96
104
_ -> return []
97
105
x <- sequence $ gens <> additionalGens
98
106
return . Object $ M. toHashMap x
0 commit comments