bxcodec / faker

Go (Golang) Fake Data Generator for Struct. [Notes]This repository is archived, moved to the new repository https://github.com/go-faker/faker
https://pkg.go.dev/github.com/bxcodec/faker/v4
MIT License
2.08k stars 148 forks source link

support the array of custom type #72

Open tokubass opened 5 years ago

tokubass commented 5 years ago

I want to get this sample code supported.

func TestArrayOfCustomType(t *testing.T) {
        type MyInt int
        type Sample struct {
                Value  []MyInt
        }

        val := Sample{}

        err := FakeData(&val)
        if err != nil {
                t.Errorf("%v", err)
        }
}
 $ go test -v ./... -run TestArrayOfCustomType
=== RUN   TestArrayOfCustomType
--- FAIL: TestArrayOfCustomType (0.00s)
panic: reflect.Set: value of type int is not assignable to type faker.MyInt [recovered]
    panic: reflect.Set: value of type int is not assignable to type faker.MyInt

goroutine 34 [running]:
testing.tRunner.func1(0xc00011c100)
    /Users/user/.goenv/versions/1.12beta1/src/testing/testing.go:827 +0x387
panic(0x1151620, 0xc000090780)
    /Users/user/.goenv/versions/1.12beta1/src/runtime/panic.go:522 +0x1b7
reflect.Value.assignTo(0x1150be0, 0xc0000982a0, 0x82, 0x1193bf5, 0xb, 0x1150ba0, 0x0, 0x58, 0xc000124000, 0x17)
    /Users/user/.goenv/versions/1.12beta1/src/reflect/value.go:2338 +0x425
reflect.Value.Set(0x1150ba0, 0xc000124000, 0x182, 0x1150be0, 0xc0000982a0, 0x82)
    /Users/user/.goenv/versions/1.12beta1/src/reflect/value.go:1472 +0xa7
github.com/bxcodec/faker/v3.getValue(0x114e220, 0xc0000a6720, 0x197, 0x1, 0x114e220, 0xc0000a6720, 0x197)
    /Users/user/git/faker/faker.go:411 +0xd92
github.com/bxcodec/faker/v3.getValue(0x1163780, 0xc0000a66e0, 0x199, 0x1163701, 0x1163780, 0xc0000a66e0, 0x135b5f0)
    /Users/user/git/faker/faker.go:375 +0x1eef
github.com/bxcodec/faker/v3.getValue(0x1148840, 0xc0000a66a0, 0x0, 0xc000098288, 0x1, 0xc0000386f8, 0x100bdf4)
    /Users/user/git/faker/faker.go:335 +0x16a1
github.com/bxcodec/faker/v3.FakeData(0x1148840, 0xc0000a66a0, 0x1049128, 0x28dc6f6812e)
    /Users/user/git/faker/faker.go:260 +0x1c5
github.com/bxcodec/faker/v3.TestArrayOfCustomType(0xc00011c100)
    /Users/user/git/faker/faker_test.go:934 +0x4b
testing.tRunner(0xc00011c100, 0x119fb30)
    /Users/user/.goenv/versions/1.12beta1/src/testing/testing.go:862 +0xbf
created by testing.(*T).Run
    /Users/user/.goenv/versions/1.12beta1/src/testing/testing.go:913 +0x356
FAIL    github.com/bxcodec/faker/v3 0.013s
?       github.com/bxcodec/faker/v3/support/slice   [no test files]
bxcodec commented 4 years ago

I'm afraid this feature is a bit impossible, as I stated here: https://github.com/bxcodec/faker#limitation

I will grateful if someone can give solutions for this issue.

andrew-werdna commented 4 years ago

So due to a recent PR that was merged, what you are asking is now possible as long as you add a custom tag to your struct and use AddProvider() to implement what happens when you use that tag. @bxcodec & @tokubass

Example:

type MyInt int
type Sample struct {
    Value  []MyInt `faker:"myint"` // <- the custom tag
}
func TestArrayOfCustomType(t *testing.T) {
        a := Sample{}
        sliceLen := 10
        err := AddProvider("myint", func(v reflect.Value) (interface{}, error) { 
            s1 := rand.NewSource(time.Now().UnixNano())
            r1 := rand.New(s1)
            r := make([]MyInt, sliceLen)
            for i := range r {
                r[i] = MyInt(r1.Intn(100))
            }
            return r, nil
        })
                /** ^ above is the AddProvider for the tag "myint".  
                  * It simply makes a slice of length 10 and fills it with random numbers. 
                  * That is the implementation for what happens when you use the tag.
                  */
        if err != nil {
            t.Error("Expected Not Error, But Got: ", err)
        }

        err = FakeData(&a)

        if err != nil {
            t.Error("Expected Not Error, But Got: ", err)
        }

        if len(a.Value) != sliceLen {
            t.Errorf("Expected a slice of length %v but got %v", sliceLen, len(a.Value))
        }

    }
andrew-werdna commented 4 years ago

~This fix currently only works for types of array & slice. I can submit a PR that will extend this behavior to more types shortly (aliasing an existing built-in type to a user defined type).~ Edited: ^ I was ignorant of some existing code. I have added a unit test for the OP's situation, but as explained in the previous comment, just use AddProvider() to ensure it's created properly

andrew-werdna commented 4 years ago

@bxcodec I think you can close this issue as the OP's desire is now supported with the caveat of using AddProvider() to make sure the custom type gets created properly.