flyingmutant / rapid

Rapid is a modern Go property-based testing library
https://pkg.go.dev/pgregory.net/rapid
Mozilla Public License 2.0
579 stars 25 forks source link

Support type definitions #52

Closed hsommerlandreason closed 1 year ago

hsommerlandreason commented 1 year ago

Howdy.

First of I'd just like to flag that I am not a Go developer and there may be good reasons for why this is but I found it to be quite cumbersome and unintuitive.

As it stands right now in v0.5.5, this fails:

import (
    "fmt"

    "pgregory.net/rapid"
)

type thing struct {
    X myType
}

type myType int

func main() {
    gen := rapid.Make[thing]()

    for i := 0; i < 5; i++ {
        fmt.Println(gen.Example(i))
    }
}

With the panic:

panic: Make[main.thing]() failed to generate an example in 1000 tries: reflect.Set: value of type int is not assignable to type main.myType

The in genAnyStruct this line fails: https://github.com/flyingmutant/rapid/blob/b5610200ba390193a9dd903256bcd73a66183a10/make.go#L167 as the generator created for the field x is based on the kind of x which is reflect.Int and since the type of x is not int the generated value cannot be assigned. Changing: https://github.com/flyingmutant/rapid/blob/b5610200ba390193a9dd903256bcd73a66183a10/make.go#L166 to: f := reflect.ValueOf(fieldGens[i].value(t)).Convert(s.Field(i).Type()) Solves this.

I I could try to address this in a PR but as i said, I am not a Go developer and I don't really get it's type system and there are probably some very good reasons to keep things the way they are.

flyingmutant commented 1 year ago

Thanks for reporting, this looks like a bug in Make. I'll try to fix this shortly, most probably by reworking newMakeGen so that it returns generators of requested types and not the "base" types.