@@ -1001,6 +1001,70 @@ object Gen extends GenArities with GenVersionSpecific {
1001
1001
}
1002
1002
}
1003
1003
1004
+ /** Generates a container of any Traversable type for which there exists an
1005
+ * implicit [[org.scalacheck.util.Buildable ]] instance. The elements in the
1006
+ * container will be generated by the given generator. The generated container
1007
+ * will continuously grow in size until the `fillCondition` returns true.
1008
+ * If the given generator fails generating a value, the
1009
+ * complete container generator will also fail. */
1010
+ def buildableOfCond [C ,T ](fillCondition : C => Boolean , g : Gen [T ], failureHint : Int = Integer .MAX_VALUE )(implicit
1011
+ evb : Buildable [T ,C ], evt : C => Traversable [T ]
1012
+ ): Gen [C ] = {
1013
+ new Gen [C ] {
1014
+ def doApply (p : P , seed0 : Seed ): R [C ] = {
1015
+ var seed : Seed = p.initialSeed.getOrElse(seed0)
1016
+ val bldr = evb.builder
1017
+ val allowedFailures = Gen .collectionRetries(failureHint)
1018
+ var failures = 0
1019
+ while (! fillCondition(bldr.result)) {
1020
+ val res = g.doApply(p, seed)
1021
+ res.retrieve match {
1022
+ case Some (t) =>
1023
+ bldr += t
1024
+ case None =>
1025
+ failures += 1
1026
+ if (failures >= allowedFailures) return r(None , res.seed)
1027
+ }
1028
+ seed = res.seed
1029
+ }
1030
+ r(Some (bldr.result), seed)
1031
+ }
1032
+ }
1033
+ }
1034
+
1035
+ /** Generates a container of any Traversable type for which there exists an
1036
+ * implicit [[org.scalacheck.util.Buildable ]] instance. The elements in the
1037
+ * container will be generated by the given generator. The generated container
1038
+ * will continuously frow in size until the `fillCondition` returns true.
1039
+ * Unlike `buildableOfCond`, this version of the method lets you specify another
1040
+ * collection Gen which helps in speeding up the process of growing the collection.
1041
+ * If the given generator fails generating a value, the
1042
+ * complete container generator will also fail. */
1043
+ def buildableOfCollCond [C <: Traversable [T ],T ](cond : C => Boolean , g : Gen [C ], failureHint : Int = Integer .MAX_VALUE )(implicit
1044
+ evb : Buildable [T ,C ], evt : C => Traversable [T ]
1045
+ ): Gen [C ] = {
1046
+ new Gen [C ] {
1047
+ def doApply (p : P , seed0 : Seed ): R [C ] = {
1048
+ var seed : Seed = p.initialSeed.getOrElse(seed0)
1049
+ val bldr = evb.builder
1050
+ val allowedFailures = Gen .collectionRetries(failureHint)
1051
+ var failures = 0
1052
+ while (! cond(bldr.result)) {
1053
+ val res = g.doApply(p, seed)
1054
+ res.retrieve match {
1055
+ case Some (t) =>
1056
+ bldr ++= t
1057
+ case None =>
1058
+ failures += 1
1059
+ if (failures >= allowedFailures) return r(None , res.seed)
1060
+ }
1061
+ seed = res.seed
1062
+ }
1063
+ r(Some (bldr.result), seed)
1064
+ }
1065
+ }
1066
+ }
1067
+
1004
1068
/** Generates a container of any Traversable type for which there exists an
1005
1069
* implicit [[org.scalacheck.util.Buildable ]] instance. The elements in the
1006
1070
* container will be generated by the given generator. The size of the
@@ -1042,6 +1106,18 @@ object Gen extends GenArities with GenVersionSpecific {
1042
1106
* `containerOf[List,T](g)`. */
1043
1107
def listOf [T ](g : => Gen [T ]) = buildableOf[List [T ], T ](g)
1044
1108
1109
+ /** Generates a list that continuously grows in size until
1110
+ * `finishCondition` returns true. */
1111
+ def listOfCond [T ](finishCondition : List [T ] => Boolean , g : => Gen [T ], failureHint : Int = Integer .MAX_VALUE ) =
1112
+ buildableOfCond[List [T ], T ](finishCondition, g, failureHint)
1113
+
1114
+ /** Generates a list that continuously grows in size until
1115
+ * `finishCondition` returns true. Unlike `listOfCond` it
1116
+ * accepts a list generator argument which lets you generate
1117
+ * larger lists quicker */
1118
+ def listOfFillCond [T ](finishCondition : List [T ] => Boolean , g : => Gen [List [T ]], failureHint : Int = Integer .MAX_VALUE ) =
1119
+ buildableOfCollCond[List [T ], T ](finishCondition, g, failureHint)
1120
+
1045
1121
/** Generates a non-empty list of random length. The maximum length depends
1046
1122
* on the size parameter. This method is equal to calling
1047
1123
* `nonEmptyContainerOf[List,T](g)`. */
@@ -1056,6 +1132,16 @@ object Gen extends GenArities with GenVersionSpecific {
1056
1132
* <code>containerOf[Map,(T,U)](g)</code>. */
1057
1133
def mapOf [T , U ](g : => Gen [(T , U )]) = buildableOf[Map [T , U ], (T , U )](g)
1058
1134
1135
+ /** Generates a map that continuously grows in size until
1136
+ * `finishCondition` returns true. */
1137
+ def mapOfCond [T , U ](cond : Map [T ,U ] => Boolean , g : => Gen [(T , U )], failureHint : Int = Integer .MAX_VALUE ) = buildableOfCond[Map [T , U ],(T , U )](cond, g, failureHint)
1138
+
1139
+ /** Generates a map that continuously grows in size until
1140
+ * `finishCondition` returns true. Unlike `mapOfCond` it
1141
+ * accepts a map generator argument which lets you generate
1142
+ * larger maps quicker */
1143
+ def mapOfFillCond [T , U ](cond : Map [T ,U ] => Boolean , g : => Gen [Map [T , U ]], failureHint : Int = Integer .MAX_VALUE ) = buildableOfCollCond[Map [T , U ],(T , U )](cond, g, failureHint)
1144
+
1059
1145
/** Generates a non-empty map of random length. The maximum length depends
1060
1146
* on the size parameter. This method is equal to calling
1061
1147
* <code>nonEmptyContainerOf[Map,(T,U)](g)</code>. */
0 commit comments