@@ -14,7 +14,7 @@ import (
14
14
"strings"
15
15
)
16
16
17
- var defaultMaxCount * int = flag .Int ("quickchecks" , 100 , "The default number of iterations for each check" )
17
+ var defaultMaxCount = flag .Int ("quickchecks" , 100 , "The default number of iterations for each check" )
18
18
19
19
// A Generator can generate random values of its own type.
20
20
type Generator interface {
@@ -98,18 +98,22 @@ func sizedValue(t reflect.Type, rand *rand.Rand, size int) (value reflect.Value,
98
98
case reflect .Uintptr :
99
99
v .SetUint (uint64 (randInt64 (rand )))
100
100
case reflect .Map :
101
- numElems := rand .Intn (size )
102
- v .Set (reflect .MakeMap (concrete ))
103
- for i := 0 ; i < numElems ; i ++ {
104
- key , ok1 := sizedValue (concrete .Key (), rand , size )
105
- value , ok2 := sizedValue (concrete .Elem (), rand , size )
106
- if ! ok1 || ! ok2 {
107
- return reflect.Value {}, false
101
+ if generateNilValue (rand ) {
102
+ v .Set (reflect .Zero (concrete )) // Generate nil map.
103
+ } else {
104
+ numElems := rand .Intn (size )
105
+ v .Set (reflect .MakeMap (concrete ))
106
+ for i := 0 ; i < numElems ; i ++ {
107
+ key , ok1 := sizedValue (concrete .Key (), rand , size )
108
+ value , ok2 := sizedValue (concrete .Elem (), rand , size )
109
+ if ! ok1 || ! ok2 {
110
+ return reflect.Value {}, false
111
+ }
112
+ v .SetMapIndex (key , value )
108
113
}
109
- v .SetMapIndex (key , value )
110
114
}
111
115
case reflect .Ptr :
112
- if rand . Intn ( size ) == 0 {
116
+ if generateNilValue ( rand ) {
113
117
v .Set (reflect .Zero (concrete )) // Generate nil pointer.
114
118
} else {
115
119
elem , ok := sizedValue (concrete .Elem (), rand , size )
@@ -120,15 +124,20 @@ func sizedValue(t reflect.Type, rand *rand.Rand, size int) (value reflect.Value,
120
124
v .Elem ().Set (elem )
121
125
}
122
126
case reflect .Slice :
123
- numElems := rand .Intn (size )
124
- sizeLeft := size - numElems
125
- v .Set (reflect .MakeSlice (concrete , numElems , numElems ))
126
- for i := 0 ; i < numElems ; i ++ {
127
- elem , ok := sizedValue (concrete .Elem (), rand , sizeLeft )
128
- if ! ok {
129
- return reflect.Value {}, false
127
+ if generateNilValue (rand ) {
128
+ v .Set (reflect .Zero (concrete )) // Generate nil slice.
129
+ } else {
130
+ slCap := rand .Intn (size )
131
+ slLen := rand .Intn (slCap + 1 )
132
+ sizeLeft := size - slCap
133
+ v .Set (reflect .MakeSlice (concrete , slLen , slCap ))
134
+ for i := 0 ; i < slLen ; i ++ {
135
+ elem , ok := sizedValue (concrete .Elem (), rand , sizeLeft )
136
+ if ! ok {
137
+ return reflect.Value {}, false
138
+ }
139
+ v .Index (i ).Set (elem )
130
140
}
131
- v .Index (i ).Set (elem )
132
141
}
133
142
case reflect .Array :
134
143
for i := 0 ; i < v .Len (); i ++ {
@@ -384,3 +393,5 @@ func toString(interfaces []interface{}) string {
384
393
}
385
394
return strings .Join (s , ", " )
386
395
}
396
+
397
+ func generateNilValue (r * rand.Rand ) bool { return r .Intn (20 ) == 0 }
0 commit comments