@@ -20,51 +20,54 @@ import (
20
20
"testing"
21
21
)
22
22
23
+ type OverrideFiller func (t * testing.T , fieldName string , field reflect.Value )
23
24
type RandomFiller struct {
24
25
randStream * rand.Rand
25
26
26
- // for iota based enums, defines the upper bound for a named enum type
27
- intEnumAllowableValues map [string ]int64
28
- // for non iota based enums, holds the set of allowable values for a named enum type
29
- stringEnumAllowableValues map [string ][]interface {}
27
+ fieldOverrides map [string ]OverrideFiller
30
28
}
31
29
32
- func NewRandomFiller (seed int64 , enumBoundsMap map [string ]int64 , enumValuesMap map [string ][]interface {}) * RandomFiller {
30
+ type FillerConfig struct {
31
+ Stream * rand.Rand
32
+ FieldOverrides map [string ]OverrideFiller
33
+ }
34
+
35
+ func NewRandomFiller (fc * FillerConfig ) * RandomFiller {
33
36
return & RandomFiller {
34
- randStream : rand .New (rand .NewSource (seed )),
35
- intEnumAllowableValues : enumBoundsMap ,
36
- stringEnumAllowableValues : enumValuesMap ,
37
+ randStream : fc .Stream ,
38
+ fieldOverrides : fc .FieldOverrides ,
37
39
}
38
40
}
39
41
40
42
// Fill populates the fields of a struct with random values. Enums are handled separately in the
41
43
// two maps passed to the RandomFiller.
42
44
func (rf * RandomFiller ) Fill (t * testing.T , obj interface {}) {
43
- rf .fillWithRandom (t , reflect .ValueOf (obj ).Elem ())
45
+ rf .fillWithRandom (t , "" , reflect .ValueOf (obj ).Elem ())
46
+ rf .fillWithRandom (t , "" , reflect .ValueOf (obj ).Elem ())
44
47
}
45
48
46
- func (rf * RandomFiller ) fillWithRandom (t * testing.T , field reflect.Value ) {
49
+ func (rf * RandomFiller ) fillWithRandom (t * testing.T , fieldName string , field reflect.Value ) {
47
50
if field .Kind () == reflect .Ptr {
48
51
if field .IsNil () {
49
52
field .Set (reflect .New (field .Type ().Elem ()))
50
53
}
51
- rf .fillWithRandom (t , field .Elem ())
54
+ rf .fillWithRandom (t , fieldName , field .Elem ())
52
55
return
53
56
}
54
57
58
+ if rf .fieldOverrides != nil {
59
+ if override , ok := rf .fieldOverrides [fieldName ]; ok {
60
+ override (t , fieldName , field )
61
+ return
62
+ }
63
+ }
64
+
55
65
switch field .Kind () {
56
66
case reflect .Bool :
57
67
field .SetBool (rf .randStream .Intn (2 ) == 1 )
58
68
59
69
case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
60
- // if this field is an iota enum field with a set of allowable values
61
- if upperBound , ok := rf .intEnumAllowableValues [field .Type ().Name ()]; ok {
62
- // Select a random integer value within the range [0, upperBound] for integer enums
63
- field .SetInt (rf .randStream .Int63n (upperBound + 1 ))
64
- } else {
65
- // Otherwise, fill with a generic random integer
66
- field .SetInt (rf .randStream .Int63 ())
67
- }
70
+ field .SetInt (rf .randStream .Int63 ())
68
71
69
72
case reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 :
70
73
field .SetUint (rf .randStream .Uint64 ())
@@ -73,22 +76,14 @@ func (rf *RandomFiller) fillWithRandom(t *testing.T, field reflect.Value) {
73
76
field .SetFloat (rf .randStream .Float64 ())
74
77
75
78
case reflect .String :
76
- // if this field is a enum field with a set of allowable values
77
- if values , ok := rf .stringEnumAllowableValues [field .Type ().Name ()]; ok {
78
- // Select a random string from predefined values in enumValuesMap
79
- selectedValue := values [rf .randStream .Intn (len (values ))]
80
- field .SetString (selectedValue .(string ))
81
- } else {
82
- // Otherwise, fill with a generic random string
83
- field .SetString (randomString (rf .randStream ))
84
- }
79
+ field .SetString (randomString (rf .randStream ))
85
80
86
81
case reflect .Slice :
87
82
count := rf .randStream .Intn (10 ) + 1
88
83
slice := reflect .MakeSlice (field .Type (), count , count )
89
84
for j := 0 ; j < count ; j ++ {
90
85
element := reflect .New (field .Type ().Elem ()).Elem ()
91
- rf .fillWithRandom (t , element )
86
+ rf .fillWithRandom (t , "" , element ) // don't need to pass in a field name for slice elements
92
87
slice .Index (j ).Set (element )
93
88
}
94
89
field .Set (slice )
@@ -99,15 +94,18 @@ func (rf *RandomFiller) fillWithRandom(t *testing.T, field reflect.Value) {
99
94
for j := 0 ; j < count ; j ++ {
100
95
key := reflect .New (field .Type ().Key ()).Elem ()
101
96
value := reflect .New (field .Type ().Elem ()).Elem ()
102
- rf .fillWithRandom (t , key )
103
- rf .fillWithRandom (t , value )
97
+ rf .fillWithRandom (t , "" , key ) // no need to pass in a field name for keys
98
+ rf .fillWithRandom (t , "" , value ) // no need to pass in a field name for values
104
99
mapType .SetMapIndex (key , value )
105
100
}
106
101
field .Set (mapType )
107
102
108
103
case reflect .Struct :
109
104
for i := 0 ; i < field .NumField (); i ++ {
110
- rf .fillWithRandom (t , field .Field (i ))
105
+ structFieldName := field .Type ().Field (i ).Name
106
+ nestedStructFieldname := fieldName + "." + structFieldName
107
+
108
+ rf .fillWithRandom (t , nestedStructFieldname , field .Field (i ))
111
109
}
112
110
113
111
default :
0 commit comments