github.com/leanovate/gopter@v0.2.9/gen_test.go (about) 1 package gopter_test 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/leanovate/gopter" 8 ) 9 10 func constGen(value interface{}) gopter.Gen { 11 return func(*gopter.GenParameters) *gopter.GenResult { 12 return gopter.NewGenResult(value, gopter.NoShrinker) 13 } 14 } 15 16 func TestGenSample(t *testing.T) { 17 gen := constGen("sample") 18 19 value, ok := gen.Sample() 20 if !ok || value != "sample" { 21 t.Errorf("Invalid gen sample: %#v", value) 22 } 23 } 24 25 func BenchmarkMap(b *testing.B) { 26 for i := 0; i < b.N; i++ { 27 gen := constGen("sample") 28 var mappedWith string 29 mapper := func(v string) string { 30 mappedWith = v 31 return "other" 32 } 33 value, ok := gen.Map(mapper).Sample() 34 if !ok || value != "other" { 35 b.Errorf("Invalid gen sample: %#v", value) 36 } 37 if mappedWith != "sample" { 38 b.Errorf("Invalid mapped with: %#v", mappedWith) 39 } 40 41 gen = gen.SuchThat(func(interface{}) bool { 42 return false 43 }) 44 value, ok = gen.Map(mapper).Sample() 45 if ok { 46 b.Errorf("Invalid gen sample: %#v", value) 47 } 48 } 49 } 50 51 func TestGenMap(t *testing.T) { 52 gen := constGen("sample") 53 var mappedWith string 54 mapper := func(v string) string { 55 mappedWith = v 56 return "other" 57 } 58 value, ok := gen.Map(mapper).Sample() 59 if !ok || value != "other" { 60 t.Errorf("Invalid gen sample: %#v", value) 61 } 62 if mappedWith != "sample" { 63 t.Errorf("Invalid mapped with: %#v", mappedWith) 64 } 65 66 gen = gen.SuchThat(func(interface{}) bool { 67 return false 68 }) 69 value, ok = gen.Map(mapper).Sample() 70 if ok { 71 t.Errorf("Invalid gen sample: %#v", value) 72 } 73 } 74 75 func TestGenMapWithParams(t *testing.T) { 76 gen := constGen("sample") 77 var mappedWith string 78 var mappedWithParams *gopter.GenParameters 79 mapper := func(v string, params *gopter.GenParameters) string { 80 mappedWith = v 81 mappedWithParams = params 82 return "other" 83 } 84 value, ok := gen.Map(mapper).Sample() 85 if !ok || value != "other" { 86 t.Errorf("Invalid gen sample: %#v", value) 87 } 88 if mappedWith != "sample" { 89 t.Errorf("Invalid mapped with: %#v", mappedWith) 90 } 91 if mappedWithParams == nil || mappedWithParams.MaxSize != 100 { 92 t.Error("Mapper not called with currect parameters") 93 } 94 95 gen = gen.SuchThat(func(interface{}) bool { 96 return false 97 }) 98 value, ok = gen.Map(mapper).Sample() 99 if ok { 100 t.Errorf("Invalid gen sample: %#v", value) 101 } 102 } 103 104 func TestGenMapNoFunc(t *testing.T) { 105 defer expectPanic(t, "Param of Map has to be a func, but is string") 106 constGen("sample").Map("not a function") 107 } 108 109 func TestGenMapTooManyParams(t *testing.T) { 110 defer expectPanic(t, "Param of Map has to be a func with one or two params, but is 3") 111 constGen("sample").Map(func(a, b, C string) string { 112 return "" 113 }) 114 } 115 116 func TestGenMapInvalidSecondParam(t *testing.T) { 117 defer expectPanic(t, "Second parameter of mapper function has to be a *GenParameters") 118 constGen("sample").Map(func(a, b string) string { 119 return "" 120 }) 121 } 122 123 func TestGenMapToInvalidParamtype(t *testing.T) { 124 defer expectPanic(t, "Param of Map has to be a func with one param assignable to string, but is int") 125 constGen("sample").Map(func(a int) string { 126 return "" 127 }) 128 } 129 130 func TestGenMapToManyReturns(t *testing.T) { 131 defer expectPanic(t, "Param of Map has to be a func with one return value, but is 2") 132 constGen("sample").Map(func(a string) (string, bool) { 133 return "", false 134 }) 135 } 136 137 func TestGenMapResultIn(t *testing.T) { 138 gen := constGen("sample") 139 var mappedWith *gopter.GenResult 140 mapper := func(result *gopter.GenResult) string { 141 mappedWith = result 142 return "other" 143 } 144 145 value, ok := gen.Map(mapper).Sample() 146 if !ok || value != "other" { 147 t.Errorf("Invalid gen sample: %#v", value) 148 } 149 if mappedWith == nil { 150 t.Error("Mapper not called") 151 } 152 if mapperValue, ok := mappedWith.Retrieve(); !ok || mapperValue != "sample" { 153 t.Errorf("Mapper was called with invalid value: %#v", mapperValue) 154 } 155 } 156 157 func TestGenMapResultInWithParams(t *testing.T) { 158 gen := constGen("sample") 159 var mappedWith *gopter.GenResult 160 var mappedWithParams *gopter.GenParameters 161 mapper := func(result *gopter.GenResult, params *gopter.GenParameters) string { 162 mappedWith = result 163 mappedWithParams = params 164 return "other" 165 } 166 167 value, ok := gen.Map(mapper).Sample() 168 if !ok || value != "other" { 169 t.Errorf("Invalid gen sample: %#v", value) 170 } 171 if mappedWith == nil { 172 t.Error("Mapper not called") 173 } 174 if mappedWithParams == nil || mappedWithParams.MaxSize != 100 { 175 t.Error("Mapper not called with currect parameters") 176 } 177 if mapperValue, ok := mappedWith.Retrieve(); !ok || mapperValue != "sample" { 178 t.Errorf("Mapper was called with invalid value: %#v", mapperValue) 179 } 180 } 181 182 func TestGenMapResultOut(t *testing.T) { 183 gen := constGen("sample") 184 var mappedWith string 185 mapper := func(v string) *gopter.GenResult { 186 mappedWith = v 187 return gopter.NewGenResult("other", gopter.NoShrinker) 188 } 189 value, ok := gen.Map(mapper).Sample() 190 if !ok || value != "other" { 191 t.Errorf("Invalid gen sample: %#v", value) 192 } 193 if mappedWith != "sample" { 194 t.Errorf("Invalid mapped with: %#v", mappedWith) 195 } 196 197 gen = gen.SuchThat(func(interface{}) bool { 198 return false 199 }) 200 value, ok = gen.Map(mapper).Sample() 201 if ok { 202 t.Errorf("Invalid gen sample: %#v", value) 203 } 204 } 205 206 func TestGenMapResultInOut(t *testing.T) { 207 gen := constGen("sample") 208 var mappedWith *gopter.GenResult 209 mapper := func(result *gopter.GenResult) *gopter.GenResult { 210 mappedWith = result 211 return gopter.NewGenResult("other", gopter.NoShrinker) 212 } 213 214 value, ok := gen.Map(mapper).Sample() 215 if !ok || value != "other" { 216 t.Errorf("Invalid gen sample: %#v", value) 217 } 218 if mappedWith == nil { 219 t.Error("Mapper not called") 220 } 221 if mapperValue, ok := mappedWith.Retrieve(); !ok || mapperValue != "sample" { 222 t.Errorf("Mapper was called with invalid value: %#v", mapperValue) 223 } 224 } 225 226 func TestGenFlatMap(t *testing.T) { 227 gen := constGen("sample") 228 var mappedWith interface{} 229 mapper := func(v interface{}) gopter.Gen { 230 mappedWith = v 231 return constGen("other") 232 } 233 value, ok := gen.FlatMap(mapper, reflect.TypeOf("")).Sample() 234 if !ok || value != "other" { 235 t.Errorf("Invalid gen sample: %#v", value) 236 } 237 if mappedWith.(string) != "sample" { 238 t.Errorf("Invalid mapped with: %#v", mappedWith) 239 } 240 241 gen = gen.SuchThat(func(interface{}) bool { 242 return false 243 }) 244 value, ok = gen.FlatMap(mapper, reflect.TypeOf("")).Sample() 245 if ok { 246 t.Errorf("Invalid gen sample: %#v", value) 247 } 248 } 249 250 func TestGenMapResult(t *testing.T) { 251 gen := constGen("sample") 252 var mappedWith *gopter.GenResult 253 mapper := func(result *gopter.GenResult) *gopter.GenResult { 254 mappedWith = result 255 return gopter.NewGenResult("other", gopter.NoShrinker) 256 } 257 258 value, ok := gen.MapResult(mapper).Sample() 259 if !ok || value != "other" { 260 t.Errorf("Invalid gen sample: %#v", value) 261 } 262 if mappedWith == nil { 263 t.Error("Mapper not called") 264 } 265 if mapperValue, ok := mappedWith.Retrieve(); !ok || mapperValue != "sample" { 266 t.Errorf("Mapper was called with invalid value: %#v", mapperValue) 267 } 268 } 269 270 func TestCombineGens(t *testing.T) { 271 gens := make([]gopter.Gen, 0, 20) 272 for i := 0; i < 20; i++ { 273 gens = append(gens, constGen(i)) 274 } 275 gen := gopter.CombineGens(gens...) 276 raw, ok := gen.Sample() 277 if !ok { 278 t.Errorf("Invalid combined gen: %#v", raw) 279 } 280 values, ok := raw.([]interface{}) 281 if !ok || !reflect.DeepEqual(values, []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}) { 282 t.Errorf("Invalid combined gen: %#v", raw) 283 } 284 285 gens[0] = gens[0].SuchThat(func(interface{}) bool { 286 return false 287 }) 288 gen = gopter.CombineGens(gens...) 289 raw, ok = gen.Sample() 290 if ok { 291 t.Errorf("Invalid combined gen: %#v", raw) 292 } 293 } 294 295 func TestSuchThat(t *testing.T) { 296 var sieveArg string 297 sieve := func(v string) bool { 298 sieveArg = v 299 return true 300 } 301 gen := constGen("sample").SuchThat(sieve) 302 value, ok := gen.Sample() 303 if !ok || value != "sample" { 304 t.Errorf("Invalid result: %#v", value) 305 } 306 if sieveArg != "sample" { 307 t.Errorf("Invalid sieveArg: %#v", sieveArg) 308 } 309 310 sieveArg = "" 311 var sieve2Arg string 312 sieve2 := func(v string) bool { 313 sieve2Arg = v 314 return false 315 } 316 gen = gen.SuchThat(sieve2) 317 _, ok = gen.Sample() 318 if ok { 319 t.Error("Did not expect a result") 320 } 321 if sieveArg != "sample" { 322 t.Errorf("Invalid sieveArg: %#v", sieveArg) 323 } 324 if sieve2Arg != "sample" { 325 t.Errorf("Invalid sieve2Arg: %#v", sieve2Arg) 326 } 327 } 328 329 func TestGenSuchThatNoFunc(t *testing.T) { 330 defer expectPanic(t, "Param of SuchThat has to be a func, but is string") 331 constGen("sample").SuchThat("not a function") 332 } 333 334 func TestGenSuchTooManyParams(t *testing.T) { 335 defer expectPanic(t, "Param of SuchThat has to be a func with one param, but is 2") 336 constGen("sample").SuchThat(func(a, b string) bool { 337 return false 338 }) 339 } 340 341 func TestGenSuchThatToInvalidParamtype(t *testing.T) { 342 defer expectPanic(t, "Param of SuchThat has to be a func with one param assignable to string, but is int") 343 constGen("sample").SuchThat(func(a int) bool { 344 return false 345 }) 346 } 347 348 func TestGenSuchToManyReturns(t *testing.T) { 349 defer expectPanic(t, "Param of SuchThat has to be a func with one return value, but is 2") 350 constGen("sample").SuchThat(func(a string) (string, bool) { 351 return "", false 352 }) 353 } 354 355 func TestGenSuchToInvalidReturns(t *testing.T) { 356 defer expectPanic(t, "Param of SuchThat has to be a func with one return value of bool, but is string") 357 constGen("sample").SuchThat(func(a string) string { 358 return "" 359 }) 360 } 361 362 func TestWithShrinker(t *testing.T) { 363 var shrinkerArg interface{} 364 shrinker := func(v interface{}) gopter.Shrink { 365 shrinkerArg = v 366 return gopter.NoShrink 367 } 368 gen := constGen("sample").WithShrinker(shrinker) 369 result := gen(gopter.DefaultGenParameters()) 370 value, ok := result.Retrieve() 371 if !ok { 372 t.Errorf("Invalid combined value: %#v", value) 373 } 374 result.Shrinker(value) 375 if shrinkerArg != "sample" { 376 t.Errorf("Invalid shrinkerArg: %#v", shrinkerArg) 377 } 378 379 mapper := func(v string) string { 380 return "other" 381 } 382 result = gen.Map(mapper)(gopter.DefaultGenParameters()) 383 value, ok = result.Retrieve() 384 if !ok { 385 t.Errorf("Invalid combined value: %#v", value) 386 } 387 result.Shrinker(value) 388 if shrinkerArg != "other" { 389 t.Errorf("Shrinker was lost during Map when the in and out types were the same") 390 } 391 } 392 393 func expectPanic(t *testing.T, expected string) { 394 r := recover() 395 if r == nil { 396 t.Errorf("The code did not panic") 397 } else if r.(string) != expected { 398 t.Errorf("Panic does not match: '%#v' != '%#v'", r, expected) 399 } 400 }