@@ -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.
371373arbitraryOfType :: 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
390394arbitraryOfDecl :: 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