Closed elfrucool closed 1 year ago
I don't undestand why a special combinator is required for flatmap in rapid. For example, here is jqwik user guide for flatmap, here is the same thing expressed in rapid:
func stringsOfSameLength(t *rapid.T) []string {
n := rapid.IntRange(0, 10).Draw(t, "len")
runes := rapid.RuneFrom(nil, unicode.ASCII_Hex_Digit)
return rapid.SliceOf(rapid.StringOfN(runes, n, n, n)).Draw(t, "strings")
}
func ExampleFlatMap() {
gen := rapid.Custom(stringsOfSameLength)
for i := 0; i < 10; i++ {
fmt.Println(gen.Example(i))
}
// Output:
// [ ]
// [102e 2314 1283]
// []
// [2 6 0 B 2 6 d 0 8 0 6]
// [ ]
// []
// []
// [e3 6A eC]
// [0e02f8fE02 49338f7119 16080D8007 3Ecbb200d3 E20Fc0B111 bAAA07baAd 6c6051eA2f d770aCB30C 18260E21B5 3b619d9102 251F83b232 1483E0e018 10B0c0e45f 0f23AE9026]
// [24f 0C7]
}
The issue I'm facing is the need to create a generator based on the output of another generator.
To illustrate, consider a situation where we have four or six potential scenarios. Each scenario produces arbitrary data but with different combinations. Additionally, all subsequent generators depend on the first one or between each other.
Please note:
The
rapid.Map
function isn't sufficient in this case because sometimes we need to transform a value into another value that is not fixed.The
rapid.Custom
function also isn't enough because we need to track original values without keeping them fixed.By using
rapid.FlatMap
, it's straightforward to create another combinator,rapid.Map2
. This combinator takes two generators and a function. The function combines the two generated values, producing another generator that depends on the first two.Consider the following use case, which is similar to a project I'm currently working on:
To address this issue, I propose an implementation using only exported symbols. This is the approach I'm currently using in a project: