@@ -43,6 +43,7 @@ import io.kotest.property.arbitrary.string
4343import io.kotest.property.asSample
4444import io.kotest.property.exhaustive.constant
4545import io.kotest.property.exhaustive.of
46+ import kotlin.random.Random
4647import kotlin.random.nextInt
4748
4849object ProtoArb {
@@ -251,11 +252,7 @@ private typealias GenerateCompositeValueFunc<V> =
251252 path: DataConnectPath ,
252253 depth: Int ,
253254 descendants: MutableList <DataConnectPathValuePair >,
254- structSizeEdgeCaseProbability: Float ,
255- listSizeEdgeCaseProbability: Float ,
256- structKeyEdgeCaseProbability: Float ,
257- scalarValueEdgeCaseProbability: Float ,
258- nestedProbability: Float ,
255+ probabilities: GenerateCompositeValueProbabilities ,
259256 ) -> V
260257
261258private abstract class CompositeValueArb <V , I >(
@@ -281,11 +278,7 @@ private abstract class CompositeValueArb<V, I>(
281278 generate(
282279 rs,
283280 depthEdgeCaseProbability = rs.random.nextFloat(),
284- structSizeEdgeCaseProbability = rs.random.nextFloat(),
285- listSizeEdgeCaseProbability = rs.random.nextFloat(),
286- structKeyEdgeCaseProbability = rs.random.nextFloat(),
287- scalarValueEdgeCaseProbability = rs.random.nextFloat(),
288- nestedProbability = rs.random.nextFloat(),
281+ GenerateCompositeValueProbabilities (rs)
289282 )
290283 .asSample()
291284
@@ -305,22 +298,20 @@ private abstract class CompositeValueArb<V, I>(
305298 return generate(
306299 rs,
307300 depthEdgeCaseProbability = depthEdgeCaseProbability,
308- structSizeEdgeCaseProbability = structSizeEdgeCaseProbability,
309- listSizeEdgeCaseProbability = listSizeEdgeCaseProbability,
310- structKeyEdgeCaseProbability = structKeyEdgeCaseProbability,
311- scalarValueEdgeCaseProbability = scalarValueEdgeCaseProbability,
312- nestedProbability = nestedProbability,
301+ GenerateCompositeValueProbabilities (
302+ structSizeEdgeCase = structSizeEdgeCaseProbability,
303+ listSizeEdgeCase = listSizeEdgeCaseProbability,
304+ structKeyEdgeCase = structKeyEdgeCaseProbability,
305+ scalarValueEdgeCase = scalarValueEdgeCaseProbability,
306+ nested = nestedProbability,
307+ ),
313308 )
314309 }
315310
316311 private fun generate (
317312 rs : RandomSource ,
318313 depthEdgeCaseProbability : Float ,
319- structSizeEdgeCaseProbability : Float ,
320- listSizeEdgeCaseProbability : Float ,
321- structKeyEdgeCaseProbability : Float ,
322- scalarValueEdgeCaseProbability : Float ,
323- nestedProbability : Float ,
314+ probabilities : GenerateCompositeValueProbabilities ,
324315 ): I {
325316 val depth = depthArb.next(rs, depthEdgeCaseProbability)
326317 val descendants: MutableList <DataConnectPathValuePair > = mutableListOf ()
@@ -330,11 +321,7 @@ private abstract class CompositeValueArb<V, I>(
330321 emptyList(),
331322 depth,
332323 descendants,
333- structSizeEdgeCaseProbability,
334- listSizeEdgeCaseProbability,
335- structKeyEdgeCaseProbability,
336- scalarValueEdgeCaseProbability,
337- nestedProbability,
324+ probabilities,
338325 )
339326 return sampleFromValue(generatedValue, depth, descendants.toList())
340327 }
@@ -450,6 +437,26 @@ fun Value.maxDepth(): Int =
450437 else -> 1
451438 }
452439
440+ private data class GenerateCompositeValueProbabilities (
441+ val structSizeEdgeCase : Float ,
442+ val listSizeEdgeCase : Float ,
443+ val structKeyEdgeCase : Float ,
444+ val scalarValueEdgeCase : Float ,
445+ val nested : Float ,
446+ ) {
447+ constructor (
448+ random: Random
449+ ) : this (
450+ random.nextFloat(),
451+ random.nextFloat(),
452+ random.nextFloat(),
453+ random.nextFloat(),
454+ random.nextFloat(),
455+ )
456+
457+ constructor (rs: RandomSource ) : this (rs.random)
458+ }
459+
453460private class StructOrListValueGenerator (
454461 private val scalarValue : Arb <Value >,
455462 private val structKey : Arb <String >,
@@ -461,18 +468,14 @@ private class StructOrListValueGenerator(
461468 path : DataConnectPath ,
462469 depth : Int ,
463470 descendants : MutableList <DataConnectPathValuePair >,
464- structSizeEdgeCaseProbability : Float ,
465- listSizeEdgeCaseProbability : Float ,
466- structKeyEdgeCaseProbability : Float ,
467- scalarValueEdgeCaseProbability : Float ,
468- nestedProbability : Float ,
471+ probabilities : GenerateCompositeValueProbabilities ,
469472 ): Struct {
470473 require(depth > 0 ) { " invalid depth: $depth (must be greater than zero)" }
471474
472475 val structBuilder = Struct .newBuilder()
473476
474477 val childPathSegmentGenerator =
475- generateSequence { structKey.next(rs, structKeyEdgeCaseProbability ) }
478+ generateSequence { structKey.next(rs, probabilities.structKeyEdgeCase ) }
476479 .filterNot { structBuilder.containsFields(it) }
477480 .map(DataConnectPathSegment ::Field )
478481 .iterator()
@@ -482,13 +485,9 @@ private class StructOrListValueGenerator(
482485 path = path,
483486 depth = depth,
484487 sizeRange = structSize,
485- sizeEdgeCaseProbability = structSizeEdgeCaseProbability ,
488+ sizeEdgeCaseProbability = probabilities.structSizeEdgeCase ,
486489 descendants = descendants,
487- structSizeEdgeCaseProbability = structSizeEdgeCaseProbability,
488- listSizeEdgeCaseProbability = listSizeEdgeCaseProbability,
489- structKeyEdgeCaseProbability = structKeyEdgeCaseProbability,
490- scalarValueEdgeCaseProbability = scalarValueEdgeCaseProbability,
491- nestedProbability = nestedProbability,
490+ probabilities = probabilities,
492491 childPathSegmentForIndex = { childPathSegmentGenerator.next() },
493492 onChildGenerated = { childPathSegment, value ->
494493 structBuilder.putFields(childPathSegment.field, value)
@@ -503,11 +502,7 @@ private class StructOrListValueGenerator(
503502 path : DataConnectPath ,
504503 depth : Int ,
505504 descendants : MutableList <DataConnectPathValuePair >,
506- structSizeEdgeCaseProbability : Float ,
507- listSizeEdgeCaseProbability : Float ,
508- structKeyEdgeCaseProbability : Float ,
509- scalarValueEdgeCaseProbability : Float ,
510- nestedProbability : Float ,
505+ probabilities : GenerateCompositeValueProbabilities ,
511506 ): ListValue {
512507 require(depth > 0 ) { " invalid depth: $depth (must be greater than zero)" }
513508
@@ -518,13 +513,9 @@ private class StructOrListValueGenerator(
518513 path = path,
519514 depth = depth,
520515 sizeRange = listSize,
521- sizeEdgeCaseProbability = listSizeEdgeCaseProbability ,
516+ sizeEdgeCaseProbability = probabilities.listSizeEdgeCase ,
522517 descendants = descendants,
523- structSizeEdgeCaseProbability = structSizeEdgeCaseProbability,
524- listSizeEdgeCaseProbability = listSizeEdgeCaseProbability,
525- structKeyEdgeCaseProbability = structKeyEdgeCaseProbability,
526- scalarValueEdgeCaseProbability = scalarValueEdgeCaseProbability,
527- nestedProbability = nestedProbability,
518+ probabilities = probabilities,
528519 childPathSegmentForIndex = DataConnectPathSegment ::ListIndex ,
529520 onChildGenerated = { _, value -> listValueBuilder.addValues(value) },
530521 )
@@ -539,11 +530,7 @@ private class StructOrListValueGenerator(
539530 sizeRange : IntRange ,
540531 sizeEdgeCaseProbability : Float ,
541532 descendants : MutableList <DataConnectPathValuePair >,
542- structSizeEdgeCaseProbability : Float ,
543- listSizeEdgeCaseProbability : Float ,
544- structKeyEdgeCaseProbability : Float ,
545- scalarValueEdgeCaseProbability : Float ,
546- nestedProbability : Float ,
533+ probabilities : GenerateCompositeValueProbabilities ,
547534 childPathSegmentForIndex : (index: Int ) -> P ,
548535 onChildGenerated : (pathSegment: P , value: Value ) -> Unit ,
549536 ) {
@@ -567,7 +554,7 @@ private class StructOrListValueGenerator(
567554 parentDepth = depth,
568555 index = valueIndex,
569556 maxDepthIndex = maxDepthIndex,
570- nestedProbability = nestedProbability ,
557+ nestedProbability = probabilities.nested ,
571558 )
572559 check(childDepth < depth) // avoid infinite recursion
573560
@@ -577,11 +564,7 @@ private class StructOrListValueGenerator(
577564 path = childPath,
578565 depth = childDepth,
579566 descendants = descendants,
580- structSizeEdgeCaseProbability = structSizeEdgeCaseProbability,
581- listSizeEdgeCaseProbability = listSizeEdgeCaseProbability,
582- structKeyEdgeCaseProbability = structKeyEdgeCaseProbability,
583- scalarValueEdgeCaseProbability = scalarValueEdgeCaseProbability,
584- nestedProbability = nestedProbability,
567+ probabilities = probabilities,
585568 )
586569
587570 descendants.add(DataConnectPathValuePair (childPath, value))
@@ -594,14 +577,10 @@ private class StructOrListValueGenerator(
594577 path : DataConnectPath ,
595578 depth : Int ,
596579 descendants : MutableList <DataConnectPathValuePair >,
597- structSizeEdgeCaseProbability : Float ,
598- listSizeEdgeCaseProbability : Float ,
599- structKeyEdgeCaseProbability : Float ,
600- scalarValueEdgeCaseProbability : Float ,
601- nestedProbability : Float ,
580+ probabilities : GenerateCompositeValueProbabilities ,
602581 ): Value {
603582 if (depth == 0 ) {
604- return scalarValue.next(rs, scalarValueEdgeCaseProbability )
583+ return scalarValue.next(rs, probabilities.scalarValueEdgeCase )
605584 }
606585
607586 val childCanBeStruct = structSize.isNonEmptyExcluding(0 )
@@ -626,11 +605,7 @@ private class StructOrListValueGenerator(
626605 path = path,
627606 depth = depth,
628607 descendants = descendants,
629- structSizeEdgeCaseProbability = structSizeEdgeCaseProbability,
630- listSizeEdgeCaseProbability = listSizeEdgeCaseProbability,
631- structKeyEdgeCaseProbability = structKeyEdgeCaseProbability,
632- scalarValueEdgeCaseProbability = scalarValueEdgeCaseProbability,
633- nestedProbability = nestedProbability,
608+ probabilities = probabilities,
634609 )
635610 .toValueProto()
636611 } else {
@@ -639,11 +614,7 @@ private class StructOrListValueGenerator(
639614 path = path,
640615 depth = depth,
641616 descendants = descendants,
642- structSizeEdgeCaseProbability = structSizeEdgeCaseProbability,
643- listSizeEdgeCaseProbability = listSizeEdgeCaseProbability,
644- structKeyEdgeCaseProbability = structKeyEdgeCaseProbability,
645- scalarValueEdgeCaseProbability = scalarValueEdgeCaseProbability,
646- nestedProbability = nestedProbability,
617+ probabilities = probabilities,
647618 )
648619 .toValueProto()
649620 }
0 commit comments