Skip to content

Commit affa1b2

Browse files
committed
Add resize to arbitraryOfType and arbitraryOfDecl
1 parent 59ecd88 commit affa1b2

1 file changed

Lines changed: 16 additions & 9 deletions

File tree

src/Data/API/Value.hs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,16 @@ arbitrary api = do tn <- QC.elements (Map.keys api)
367367
return (TyName tn, v)
368368

369369
-- | Given a schema and a type, generate an arbitrary value of that
370-
-- type.
370+
-- type. Uses 'QC.sized' and 'QC.resize' to ensure recursive schemas
371+
-- terminate by halving the size parameter at each structural
372+
-- recursion point.
371373
arbitraryOfType :: NormAPI -> APIType -> QC.Gen Value
372-
arbitraryOfType api ty0 = case ty0 of
373-
TyName tn -> arbitraryOfDecl api (lookupTyName api tn)
374-
TyList ty -> List <$> QC.listOf (arbitraryOfType api ty)
375-
TyMaybe ty -> Maybe <$> QC.oneof [pure Nothing, Just <$> arbitraryOfType api ty]
374+
arbitraryOfType api ty0 = QC.sized $ \ size -> case ty0 of
375+
TyName tn -> QC.resize (size `div` 2) $ arbitraryOfDecl api (lookupTyName api tn)
376+
TyList ty -> List <$> QC.resize (size `div` 2) (QC.listOf (arbitraryOfType api ty))
377+
TyMaybe ty -> Maybe <$> if size <= 0
378+
then pure Nothing
379+
else QC.oneof [pure Nothing, Just <$> QC.resize (size `div` 2) (arbitraryOfType api ty)]
376380
TyJSON -> JSON <$> arbitraryJSONValue
377381
TyBasic bt -> arbitraryOfBasicType bt
378382

@@ -388,12 +392,15 @@ arbitraryOfBasicType bt = case bt of
388392
<$> QC.arbitrary
389393

390394
arbitraryOfDecl :: NormAPI -> NormTypeDecl -> QC.Gen Value
391-
arbitraryOfDecl api d = case d of
392-
NRecordType nrt -> Record <$> traverse (\ (fn, ty) -> Field fn <$> arbitraryOfType api ty) (Map.toList nrt)
395+
arbitraryOfDecl api d = QC.sized $ \size ->
396+
case d of
397+
NRecordType nrt ->
398+
let fields = Map.toList nrt
399+
in Record <$> traverse (\ (fn, ty) -> Field fn <$> QC.resize (size `div` 2) (arbitraryOfType api ty)) fields
393400
NUnionType nut -> do (fn, ty) <- QC.elements (Map.toList nut)
394-
Union fn <$> arbitraryOfType api ty
401+
Union fn <$> QC.resize (size `div` 2) (arbitraryOfType api ty)
395402
NEnumType net -> Enum <$> QC.elements (Set.toList net)
396-
NTypeSynonym ty -> arbitraryOfType api ty
403+
NTypeSynonym ty -> QC.resize (size `div` 2) (arbitraryOfType api ty)
397404
NNewtype bt -> arbitraryOfBasicType bt
398405

399406
-- | A reasonably varied generator for JSON 'JS.Value's.

0 commit comments

Comments
 (0)