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  }