map generators?
andrewjstone opened this issue · 3 comments
There are generators for slices, but none for maps. What I have been doing to work around this is generating helper structs containing slices and then computing the maps after generation. This seems to work fine, but is a bit ugly.
Is there a fundamental reason why generating maps is hard, or is it just a matter of work to build it?
If I remember correctly I skipped this because until recently there have been some issues with a generic "map[interface{}]interface{}". But I think this has been fixed.
Here is an (early) example that seems to work with go 1.9:
func MapOf(keyGen, elementGen gopter.Gen) gopter.Gen {
return func(genParams *gopter.GenParameters) *gopter.GenResult {
len := 0
if genParams.MaxSize > 0 || genParams.MinSize > 0 {
if genParams.MinSize > genParams.MaxSize {
panic("GenParameters.MinSize must be <= GenParameters.MaxSize")
}
if genParams.MaxSize == genParams.MinSize {
len = genParams.MaxSize
} else {
len = genParams.Rng.Intn(genParams.MaxSize-genParams.MinSize) + genParams.MinSize
}
}
result := map[interface{}]interface{}{}
for i := 0; i < len; i++ {
element, elementOk := elementGen(genParams).Retrieve()
key, keyOk := keyGen(genParams).Retrieve()
if elementOk && keyOk {
result[key] = element
}
}
genResult := gopter.NewGenResult(result, gopter.NoShrinker)
return genResult
}
}
Of course, the shrinker will require further work.
I've added a more sophisticated MapOf version with shrinker support and better typing.
Let me know if that version meets your needs.
Looks great. I wasn't able to evaluate the shrinking code, but the interface looks like what I'd expect. Thanks!