github.com/leanovate/gopter@v0.2.9/arbitrary/gen_for_kind.go (about)

     1  package arbitrary
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/leanovate/gopter"
     7  	"github.com/leanovate/gopter/gen"
     8  )
     9  
    10  func mapBoolish(to reflect.Type, v interface{}) interface{} {
    11  	value := reflect.ValueOf(v)
    12  	result := reflect.New(to).Elem()
    13  	result.SetBool(value.Bool())
    14  	return result.Interface()
    15  }
    16  
    17  func mapIntish(to reflect.Type, v interface{}) interface{} {
    18  	value := reflect.ValueOf(v)
    19  	result := reflect.New(to).Elem()
    20  	result.SetInt(value.Int())
    21  	return result.Interface()
    22  }
    23  
    24  func mapUintish(to reflect.Type, v interface{}) interface{} {
    25  	value := reflect.ValueOf(v)
    26  	result := reflect.New(to).Elem()
    27  	result.SetUint(value.Uint())
    28  	return result.Interface()
    29  }
    30  
    31  func mapFloatish(to reflect.Type, v interface{}) interface{} {
    32  	value := reflect.ValueOf(v)
    33  	result := reflect.New(to).Elem()
    34  	result.SetFloat(value.Float())
    35  	return result.Interface()
    36  }
    37  
    38  func mapComplexish(to reflect.Type, v interface{}) interface{} {
    39  	value := reflect.ValueOf(v)
    40  	result := reflect.New(to).Elem()
    41  	result.SetComplex(value.Complex())
    42  	return result.Interface()
    43  }
    44  
    45  func mapStringish(to reflect.Type, v interface{}) interface{} {
    46  	value := reflect.ValueOf(v)
    47  	result := reflect.New(to).Elem()
    48  	result.SetString(value.String())
    49  	return result.Interface()
    50  }
    51  
    52  func (a *Arbitraries) genForKind(rt reflect.Type) gopter.Gen {
    53  	switch rt.Kind() {
    54  	case reflect.Bool:
    55  		return gen.Bool().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
    56  			return &gopter.GenResult{
    57  				Labels:     result.Labels,
    58  				ResultType: rt,
    59  				Result:     mapBoolish(rt, result.Result),
    60  				Sieve: func(v interface{}) bool {
    61  					return result.Sieve == nil || result.Sieve(mapBoolish(reflect.TypeOf(bool(false)), v))
    62  				},
    63  				Shrinker: gopter.NoShrinker,
    64  			}
    65  		})
    66  	case reflect.Int:
    67  		return gen.Int().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
    68  			return &gopter.GenResult{
    69  				Labels:     result.Labels,
    70  				ResultType: rt,
    71  				Result:     mapIntish(rt, result.Result),
    72  				Sieve: func(v interface{}) bool {
    73  					return result.Sieve == nil || result.Sieve(mapIntish(reflect.TypeOf(int(0)), v))
    74  				},
    75  				Shrinker: func(v interface{}) gopter.Shrink {
    76  					return result.Shrinker(mapIntish(reflect.TypeOf(int(0)), v)).Map(func(s interface{}) interface{} {
    77  						return mapIntish(rt, s)
    78  					})
    79  				},
    80  			}
    81  		})
    82  	case reflect.Uint:
    83  		return gen.UInt().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
    84  			return &gopter.GenResult{
    85  				Labels:     result.Labels,
    86  				ResultType: rt,
    87  				Result:     mapUintish(rt, result.Result),
    88  				Sieve: func(v interface{}) bool {
    89  					return result.Sieve == nil || result.Sieve(mapUintish(reflect.TypeOf(uint(0)), v))
    90  				},
    91  				Shrinker: func(v interface{}) gopter.Shrink {
    92  					return result.Shrinker(mapUintish(reflect.TypeOf(uint(0)), v)).Map(func(s interface{}) interface{} {
    93  						return mapUintish(rt, s)
    94  					})
    95  				},
    96  			}
    97  		})
    98  	case reflect.Int8:
    99  		return gen.Int8().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   100  			return &gopter.GenResult{
   101  				Labels:     result.Labels,
   102  				ResultType: rt,
   103  				Result:     mapIntish(rt, result.Result),
   104  				Sieve: func(v interface{}) bool {
   105  					return result.Sieve == nil || result.Sieve(mapIntish(reflect.TypeOf(int8(0)), v))
   106  				},
   107  				Shrinker: func(v interface{}) gopter.Shrink {
   108  					return result.Shrinker(mapIntish(reflect.TypeOf(int8(0)), v)).Map(func(s interface{}) interface{} {
   109  						return mapIntish(rt, s)
   110  					})
   111  				},
   112  			}
   113  		})
   114  	case reflect.Uint8:
   115  		return gen.UInt8().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   116  			return &gopter.GenResult{
   117  				Labels:     result.Labels,
   118  				ResultType: rt,
   119  				Result:     mapUintish(rt, result.Result),
   120  				Sieve: func(v interface{}) bool {
   121  					return result.Sieve == nil || result.Sieve(mapUintish(reflect.TypeOf(uint8(0)), v))
   122  				},
   123  				Shrinker: func(v interface{}) gopter.Shrink {
   124  					return result.Shrinker(mapUintish(reflect.TypeOf(uint8(0)), v)).Map(func(s interface{}) interface{} {
   125  						return mapUintish(rt, s)
   126  					})
   127  				},
   128  			}
   129  		})
   130  	case reflect.Int16:
   131  		return gen.Int16().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   132  			return &gopter.GenResult{
   133  				Labels:     result.Labels,
   134  				ResultType: rt,
   135  				Result:     mapIntish(rt, result.Result),
   136  				Sieve: func(v interface{}) bool {
   137  					return result.Sieve == nil || result.Sieve(mapIntish(reflect.TypeOf(int16(0)), v))
   138  				},
   139  				Shrinker: func(v interface{}) gopter.Shrink {
   140  					return result.Shrinker(mapIntish(reflect.TypeOf(int16(0)), v)).Map(func(s interface{}) interface{} {
   141  						return mapIntish(rt, s)
   142  					})
   143  				},
   144  			}
   145  		})
   146  	case reflect.Uint16:
   147  		return gen.UInt16().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   148  			return &gopter.GenResult{
   149  				Labels:     result.Labels,
   150  				ResultType: rt,
   151  				Result:     mapUintish(rt, result.Result),
   152  				Sieve: func(v interface{}) bool {
   153  					return result.Sieve == nil || result.Sieve(mapUintish(reflect.TypeOf(uint16(0)), v))
   154  				},
   155  				Shrinker: func(v interface{}) gopter.Shrink {
   156  					return result.Shrinker(mapUintish(reflect.TypeOf(uint16(0)), v)).Map(func(s interface{}) interface{} {
   157  						return mapUintish(rt, s)
   158  					})
   159  				},
   160  			}
   161  		})
   162  	case reflect.Int32:
   163  		return gen.Int32().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   164  			return &gopter.GenResult{
   165  				Labels:     result.Labels,
   166  				ResultType: rt,
   167  				Result:     mapIntish(rt, result.Result),
   168  				Sieve: func(v interface{}) bool {
   169  					return result.Sieve == nil || result.Sieve(mapIntish(reflect.TypeOf(int32(0)), v))
   170  				},
   171  				Shrinker: func(v interface{}) gopter.Shrink {
   172  					return result.Shrinker(mapIntish(reflect.TypeOf(int32(0)), v)).Map(func(s interface{}) interface{} {
   173  						return mapIntish(rt, s)
   174  					})
   175  				},
   176  			}
   177  		})
   178  	case reflect.Uint32:
   179  		return gen.UInt32().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   180  			return &gopter.GenResult{
   181  				Labels:     result.Labels,
   182  				ResultType: rt,
   183  				Result:     mapUintish(rt, result.Result),
   184  				Sieve: func(v interface{}) bool {
   185  					return result.Sieve == nil || result.Sieve(mapUintish(reflect.TypeOf(uint32(0)), v))
   186  				},
   187  				Shrinker: func(v interface{}) gopter.Shrink {
   188  					return result.Shrinker(mapUintish(reflect.TypeOf(uint32(0)), v)).Map(func(s interface{}) interface{} {
   189  						return mapUintish(rt, s)
   190  					})
   191  				},
   192  			}
   193  		})
   194  	case reflect.Int64:
   195  		return gen.Int64().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   196  			return &gopter.GenResult{
   197  				Labels:     result.Labels,
   198  				ResultType: rt,
   199  				Result:     mapIntish(rt, result.Result),
   200  				Sieve: func(v interface{}) bool {
   201  					return result.Sieve == nil || result.Sieve(mapIntish(reflect.TypeOf(int32(0)), v))
   202  				},
   203  				Shrinker: func(v interface{}) gopter.Shrink {
   204  					return result.Shrinker(mapIntish(reflect.TypeOf(int64(0)), v)).Map(func(s interface{}) interface{} {
   205  						return mapIntish(rt, s)
   206  					})
   207  				},
   208  			}
   209  		})
   210  	case reflect.Uint64:
   211  		return gen.UInt64().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   212  			return &gopter.GenResult{
   213  				Labels:     result.Labels,
   214  				ResultType: rt,
   215  				Result:     mapUintish(rt, result.Result),
   216  				Sieve: func(v interface{}) bool {
   217  					return result.Sieve == nil || result.Sieve(mapUintish(reflect.TypeOf(uint64(0)), v))
   218  				},
   219  				Shrinker: func(v interface{}) gopter.Shrink {
   220  					return result.Shrinker(mapUintish(reflect.TypeOf(uint64(0)), v)).Map(func(s interface{}) interface{} {
   221  						return mapUintish(rt, s)
   222  					})
   223  				},
   224  			}
   225  		})
   226  	case reflect.Float32:
   227  		return gen.Float32().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   228  			return &gopter.GenResult{
   229  				Labels:     result.Labels,
   230  				ResultType: rt,
   231  				Result:     mapFloatish(rt, result.Result),
   232  				Sieve: func(v interface{}) bool {
   233  					return result.Sieve == nil || result.Sieve(mapFloatish(reflect.TypeOf(float32(0)), v))
   234  				},
   235  				Shrinker: func(v interface{}) gopter.Shrink {
   236  					return result.Shrinker(mapFloatish(reflect.TypeOf(float32(0)), v)).Map(func(s interface{}) interface{} {
   237  						return mapFloatish(rt, s)
   238  					})
   239  				},
   240  			}
   241  		})
   242  	case reflect.Float64:
   243  		return gen.Float64().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   244  			return &gopter.GenResult{
   245  				Labels:     result.Labels,
   246  				ResultType: rt,
   247  				Result:     mapFloatish(rt, result.Result),
   248  				Sieve: func(v interface{}) bool {
   249  					return result.Sieve == nil || result.Sieve(mapFloatish(reflect.TypeOf(float64(0)), v))
   250  				},
   251  				Shrinker: func(v interface{}) gopter.Shrink {
   252  					return result.Shrinker(mapFloatish(reflect.TypeOf(float64(0)), v)).Map(func(s interface{}) interface{} {
   253  						return mapFloatish(rt, s)
   254  					})
   255  				},
   256  			}
   257  		})
   258  	case reflect.Complex64:
   259  		return gen.Complex64().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   260  			return &gopter.GenResult{
   261  				Labels:     result.Labels,
   262  				ResultType: rt,
   263  				Result:     mapComplexish(rt, result.Result),
   264  				Sieve: func(v interface{}) bool {
   265  					return result.Sieve == nil || result.Sieve(mapComplexish(reflect.TypeOf(complex64(0)), v))
   266  				},
   267  				Shrinker: func(v interface{}) gopter.Shrink {
   268  					return result.Shrinker(mapComplexish(reflect.TypeOf(complex64(0)), v)).Map(func(s interface{}) interface{} {
   269  						return mapComplexish(rt, s)
   270  					})
   271  				},
   272  			}
   273  		})
   274  	case reflect.Complex128:
   275  		return gen.Complex128().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   276  			return &gopter.GenResult{
   277  				Labels:     result.Labels,
   278  				ResultType: rt,
   279  				Result:     mapComplexish(rt, result.Result),
   280  				Sieve: func(v interface{}) bool {
   281  					return result.Sieve == nil || result.Sieve(mapComplexish(reflect.TypeOf(complex128(0)), v))
   282  				},
   283  				Shrinker: func(v interface{}) gopter.Shrink {
   284  					return result.Shrinker(mapComplexish(reflect.TypeOf(complex128(0)), v)).Map(func(s interface{}) interface{} {
   285  						return mapComplexish(rt, s)
   286  					})
   287  				},
   288  			}
   289  		})
   290  	case reflect.String:
   291  		return gen.AnyString().MapResult(func(result *gopter.GenResult) *gopter.GenResult {
   292  			return &gopter.GenResult{
   293  				Labels:     result.Labels,
   294  				ResultType: rt,
   295  				Result:     mapStringish(rt, result.Result),
   296  				Sieve: func(v interface{}) bool {
   297  					return result.Sieve == nil || result.Sieve(mapStringish(reflect.TypeOf(string("")), v))
   298  				},
   299  				Shrinker: func(v interface{}) gopter.Shrink {
   300  					return result.Shrinker(mapStringish(reflect.TypeOf(string("")), v)).Map(func(s interface{}) interface{} {
   301  						return mapStringish(rt, s)
   302  					})
   303  				},
   304  			}
   305  		})
   306  	case reflect.Slice:
   307  		if elementGen := a.GenForType(rt.Elem()); elementGen != nil {
   308  			return gen.SliceOf(elementGen)
   309  		}
   310  	case reflect.Ptr:
   311  		if rt.Elem().Kind() == reflect.Struct {
   312  			gens := make(map[string]gopter.Gen)
   313  			for i := 0; i < rt.Elem().NumField(); i++ {
   314  				field := rt.Elem().Field(i)
   315  				if gen := a.GenForType(field.Type); gen != nil {
   316  					gens[field.Name] = gen
   317  				}
   318  			}
   319  			return gen.StructPtr(rt, gens)
   320  		}
   321  		return gen.PtrOf(a.GenForType(rt.Elem()))
   322  	case reflect.Struct:
   323  		gens := make(map[string]gopter.Gen)
   324  		for i := 0; i < rt.NumField(); i++ {
   325  			field := rt.Field(i)
   326  			if gen := a.GenForType(field.Type); gen != nil {
   327  				gens[field.Name] = gen
   328  			}
   329  		}
   330  		return gen.Struct(rt, gens)
   331  	case reflect.Map:
   332  		keyGen := a.GenForType(rt.Key())
   333  		valueGen := a.GenForType(rt.Elem())
   334  		return gen.MapOf(keyGen, valueGen)
   335  	}
   336  	return nil
   337  }