Skip to content

Commit

Permalink
random.Random#Make supports type argument received as reflect.Type
Browse files Browse the repository at this point in the history
  • Loading branch information
adamluzsi committed May 11, 2024
1 parent 17b65b5 commit b6383c1
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 18 deletions.
17 changes: 10 additions & 7 deletions random/Factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ func (f *Factory) Make(rnd *Random, T any) (_T any) {
if T == nil {
return nil
}
rt := reflect.TypeOf(T)
if typeFunc, ok := f.getTypes()[rt]; ok {
typ := f.typeOf(T)
if typeFunc, ok := f.getTypes()[typ]; ok {
return typeFunc(rnd)
}
if kindFunc, ok := f.getKinds()[rt.Kind()]; ok {
return kindFunc(rnd, reflect.TypeOf(T))
if kindFunc, ok := f.getKinds()[typ.Kind()]; ok {
return kindFunc(rnd, typ)
}
return T
}

func (f *Factory) RegisterType(T any, ff typeFunc) {
f.getTypes()[reflect.TypeOf(T)] = ff
f.getTypes()[f.typeOf(T)] = ff
}

func (f *Factory) getTypes() map[reflect.Type]typeFunc {
Expand All @@ -53,8 +53,11 @@ func (f *Factory) getTypes() map[reflect.Type]typeFunc {
return f.types.mapping
}

func (f *Factory) getRandom() *Random {
return New(CryptoSeed{})
func (f *Factory) typeOf(T any) reflect.Type {
if rt, ok := T.(reflect.Type); ok {
return rt
}
return reflect.TypeOf(T)
}

func (f *Factory) int(rnd *Random, T reflect.Type) any {
Expand Down
65 changes: 54 additions & 11 deletions random/Factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -767,24 +767,67 @@ func TestFactory(t *testing.T) {
})
})
})

s.When("type is a reflect type", func(s *testcase.Spec) {
T.Let(s, func(t *testcase.T) any {
return reflect.TypeOf((*string)(nil)).Elem()
})

s.Then("it will use the reflection type to decide the type", func(t *testcase.T) {
got, ok := act(t).(string)
t.Must.True(ok, "expected that creates the type described by the reflect type input argument")
t.Must.NotEmpty(got)

})

s.Then("random values are returned", func(t *testcase.T) {
var got = make(map[string]struct{})

t.Eventually(func(it assert.It) {
got[act(t).(string)] = struct{}{}

it.Must.True(len(got) > 1)
})
})
})
})

s.Test(`.RegisterType`, func(t *testcase.T) {
type CustomType struct {
Foo int
Bar int
}
s.Describe(`.RegisterType`, func(s *testcase.Spec) {
s.Test("", func(t *testcase.T) {
type CustomType struct {
Foo int
Bar int
}

ff := factory.Get(t)
ff := factory.Get(t)

ff.RegisterType(CustomType{}, func(rnd *random.Random) any {
return CustomType{Foo: 42, Bar: rnd.Int()}
ff.RegisterType(CustomType{}, func(rnd *random.Random) any {
return CustomType{Foo: 42, Bar: rnd.Int()}
})

ct := ff.Make(rnd.Get(t), CustomType{}).(CustomType)
t.Must.Equal(42, ct.Foo)
t.Must.NotEmpty(ct.Bar)
})

ct := ff.Make(rnd.Get(t), CustomType{}).(CustomType)
t.Must.Equal(42, ct.Foo)
t.Must.NotEmpty(ct.Bar)
s.Test("accepts reflect.Type", func(t *testcase.T) {
type CustomType struct {
Foo int
Bar int
}

ff := factory.Get(t)

ff.RegisterType(reflect.TypeOf((*CustomType)(nil)).Elem(), func(rnd *random.Random) any {
return CustomType{Foo: 42, Bar: rnd.Int()}
})

ct := ff.Make(rnd.Get(t), CustomType{}).(CustomType)
t.Must.Equal(42, ct.Foo)
t.Must.NotEmpty(ct.Bar)
})
})

}

func TestFactoryMake_race(t *testing.T) {
Expand Down

0 comments on commit b6383c1

Please sign in to comment.