leanovate / gopter

GOlang Property TestER
MIT License
599 stars 40 forks source link

How to generate a slice with a range as length? #61

Closed anisjonischkeit closed 4 years ago

anisjonischkeit commented 4 years ago

I have a use case where I want to generate strings with a length between n and m. Currently I am doing this:

    makeStringGen := func(min, max int) gopter.Gen {
        return gen.Sized(func(size int) gopter.Gen {
            return gen.SliceOfN(size%max+1, gen.Rune()).
                SuchThat(func(rs []rune) bool { return len(rs) >= min }).
                Map(func(v []rune) string { return string(v) })
        })
    }

but I imagine that using % would probably mess with the distribution of sizes and using SuchThat is fine in my use case since the min is generally 0 or 1 but it seems suboptimal as a general solution. What's the best way of doing this sort of thing?

anisjonischkeit commented 4 years ago

Incase anyone else comes up with this, here's what I came up with (copying the sized implementation)

func MakeStringGen(min, max int) gopter.Gen {
    return func(params *gopter.GenParameters) *gopter.GenResult {
        size := params.Rng.Intn(max-min) + min

        return gen.SliceOfN(size, gen.Rune()).
            Map(runesToString)(params)
    }