github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/fix/testdata/reflect.quick.go.in (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This package implements utility functions to help with black box testing.
     6  package quick
     7  
     8  import (
     9  	"flag"
    10  	"fmt"
    11  	"math"
    12  	"os"
    13  	"rand"
    14  	"reflect"
    15  	"strings"
    16  )
    17  
    18  var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")
    19  
    20  // A Generator can generate random values of its own type.
    21  type Generator interface {
    22  	// Generate returns a random instance of the type on which it is a
    23  	// method using the size as a size hint.
    24  	Generate(rand *rand.Rand, size int) reflect.Value
    25  }
    26  
    27  // randFloat32 generates a random float taking the full range of a float32.
    28  func randFloat32(rand *rand.Rand) float32 {
    29  	f := rand.Float64() * math.MaxFloat32
    30  	if rand.Int()&1 == 1 {
    31  		f = -f
    32  	}
    33  	return float32(f)
    34  }
    35  
    36  // randFloat64 generates a random float taking the full range of a float64.
    37  func randFloat64(rand *rand.Rand) float64 {
    38  	f := rand.Float64()
    39  	if rand.Int()&1 == 1 {
    40  		f = -f
    41  	}
    42  	return f
    43  }
    44  
    45  // randInt64 returns a random integer taking half the range of an int64.
    46  func randInt64(rand *rand.Rand) int64 { return rand.Int63() - 1<<62 }
    47  
    48  // complexSize is the maximum length of arbitrary values that contain other
    49  // values.
    50  const complexSize = 50
    51  
    52  // Value returns an arbitrary value of the given type.
    53  // If the type implements the Generator interface, that will be used.
    54  // Note: in order to create arbitrary values for structs, all the members must be public.
    55  func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) {
    56  	if m, ok := reflect.MakeZero(t).Interface().(Generator); ok {
    57  		return m.Generate(rand, complexSize), true
    58  	}
    59  
    60  	switch concrete := t.(type) {
    61  	case *reflect.BoolType:
    62  		return reflect.NewValue(rand.Int()&1 == 0), true
    63  	case *reflect.FloatType, *reflect.IntType, *reflect.UintType, *reflect.ComplexType:
    64  		switch t.Kind() {
    65  		case reflect.Float32:
    66  			return reflect.NewValue(randFloat32(rand)), true
    67  		case reflect.Float64:
    68  			return reflect.NewValue(randFloat64(rand)), true
    69  		case reflect.Complex64:
    70  			return reflect.NewValue(complex(randFloat32(rand), randFloat32(rand))), true
    71  		case reflect.Complex128:
    72  			return reflect.NewValue(complex(randFloat64(rand), randFloat64(rand))), true
    73  		case reflect.Int16:
    74  			return reflect.NewValue(int16(randInt64(rand))), true
    75  		case reflect.Int32:
    76  			return reflect.NewValue(int32(randInt64(rand))), true
    77  		case reflect.Int64:
    78  			return reflect.NewValue(randInt64(rand)), true
    79  		case reflect.Int8:
    80  			return reflect.NewValue(int8(randInt64(rand))), true
    81  		case reflect.Int:
    82  			return reflect.NewValue(int(randInt64(rand))), true
    83  		case reflect.Uint16:
    84  			return reflect.NewValue(uint16(randInt64(rand))), true
    85  		case reflect.Uint32:
    86  			return reflect.NewValue(uint32(randInt64(rand))), true
    87  		case reflect.Uint64:
    88  			return reflect.NewValue(uint64(randInt64(rand))), true
    89  		case reflect.Uint8:
    90  			return reflect.NewValue(uint8(randInt64(rand))), true
    91  		case reflect.Uint:
    92  			return reflect.NewValue(uint(randInt64(rand))), true
    93  		case reflect.Uintptr:
    94  			return reflect.NewValue(uintptr(randInt64(rand))), true
    95  		}
    96  	case *reflect.MapType:
    97  		numElems := rand.Intn(complexSize)
    98  		m := reflect.MakeMap(concrete)
    99  		for i := 0; i < numElems; i++ {
   100  			key, ok1 := Value(concrete.Key(), rand)
   101  			value, ok2 := Value(concrete.Elem(), rand)
   102  			if !ok1 || !ok2 {
   103  				return nil, false
   104  			}
   105  			m.SetElem(key, value)
   106  		}
   107  		return m, true
   108  	case *reflect.PtrType:
   109  		v, ok := Value(concrete.Elem(), rand)
   110  		if !ok {
   111  			return nil, false
   112  		}
   113  		p := reflect.MakeZero(concrete)
   114  		p.(*reflect.PtrValue).PointTo(v)
   115  		return p, true
   116  	case *reflect.SliceType:
   117  		numElems := rand.Intn(complexSize)
   118  		s := reflect.MakeSlice(concrete, numElems, numElems)
   119  		for i := 0; i < numElems; i++ {
   120  			v, ok := Value(concrete.Elem(), rand)
   121  			if !ok {
   122  				return nil, false
   123  			}
   124  			s.Elem(i).SetValue(v)
   125  		}
   126  		return s, true
   127  	case *reflect.StringType:
   128  		numChars := rand.Intn(complexSize)
   129  		codePoints := make([]int, numChars)
   130  		for i := 0; i < numChars; i++ {
   131  			codePoints[i] = rand.Intn(0x10ffff)
   132  		}
   133  		return reflect.NewValue(string(codePoints)), true
   134  	case *reflect.StructType:
   135  		s := reflect.MakeZero(t).(*reflect.StructValue)
   136  		for i := 0; i < s.NumField(); i++ {
   137  			v, ok := Value(concrete.Field(i).Type, rand)
   138  			if !ok {
   139  				return nil, false
   140  			}
   141  			s.Field(i).SetValue(v)
   142  		}
   143  		return s, true
   144  	default:
   145  		return nil, false
   146  	}
   147  
   148  	return
   149  }
   150  
   151  // A Config structure contains options for running a test.
   152  type Config struct {
   153  	// MaxCount sets the maximum number of iterations. If zero,
   154  	// MaxCountScale is used.
   155  	MaxCount int
   156  	// MaxCountScale is a non-negative scale factor applied to the default
   157  	// maximum. If zero, the default is unchanged.
   158  	MaxCountScale float64
   159  	// If non-nil, rand is a source of random numbers. Otherwise a default
   160  	// pseudo-random source will be used.
   161  	Rand *rand.Rand
   162  	// If non-nil, Values is a function which generates a slice of arbitrary
   163  	// Values that are congruent with the arguments to the function being
   164  	// tested. Otherwise, Values is used to generate the values.
   165  	Values func([]reflect.Value, *rand.Rand)
   166  }
   167  
   168  var defaultConfig Config
   169  
   170  // getRand returns the *rand.Rand to use for a given Config.
   171  func (c *Config) getRand() *rand.Rand {
   172  	if c.Rand == nil {
   173  		return rand.New(rand.NewSource(0))
   174  	}
   175  	return c.Rand
   176  }
   177  
   178  // getMaxCount returns the maximum number of iterations to run for a given
   179  // Config.
   180  func (c *Config) getMaxCount() (maxCount int) {
   181  	maxCount = c.MaxCount
   182  	if maxCount == 0 {
   183  		if c.MaxCountScale != 0 {
   184  			maxCount = int(c.MaxCountScale * float64(*defaultMaxCount))
   185  		} else {
   186  			maxCount = *defaultMaxCount
   187  		}
   188  	}
   189  
   190  	return
   191  }
   192  
   193  // A SetupError is the result of an error in the way that check is being
   194  // used, independent of the functions being tested.
   195  type SetupError string
   196  
   197  func (s SetupError) String() string { return string(s) }
   198  
   199  // A CheckError is the result of Check finding an error.
   200  type CheckError struct {
   201  	Count int
   202  	In    []interface{}
   203  }
   204  
   205  func (s *CheckError) String() string {
   206  	return fmt.Sprintf("#%d: failed on input %s", s.Count, toString(s.In))
   207  }
   208  
   209  // A CheckEqualError is the result CheckEqual finding an error.
   210  type CheckEqualError struct {
   211  	CheckError
   212  	Out1 []interface{}
   213  	Out2 []interface{}
   214  }
   215  
   216  func (s *CheckEqualError) String() string {
   217  	return fmt.Sprintf("#%d: failed on input %s. Output 1: %s. Output 2: %s", s.Count, toString(s.In), toString(s.Out1), toString(s.Out2))
   218  }
   219  
   220  // Check looks for an input to f, any function that returns bool,
   221  // such that f returns false.  It calls f repeatedly, with arbitrary
   222  // values for each argument.  If f returns false on a given input,
   223  // Check returns that input as a *CheckError.
   224  // For example:
   225  //
   226  // 	func TestOddMultipleOfThree(t *testing.T) {
   227  // 		f := func(x int) bool {
   228  // 			y := OddMultipleOfThree(x)
   229  // 			return y%2 == 1 && y%3 == 0
   230  // 		}
   231  // 		if err := quick.Check(f, nil); err != nil {
   232  // 			t.Error(err)
   233  // 		}
   234  // 	}
   235  func Check(function interface{}, config *Config) (err os.Error) {
   236  	if config == nil {
   237  		config = &defaultConfig
   238  	}
   239  
   240  	f, fType, ok := functionAndType(function)
   241  	if !ok {
   242  		err = SetupError("argument is not a function")
   243  		return
   244  	}
   245  
   246  	if fType.NumOut() != 1 {
   247  		err = SetupError("function returns more than one value.")
   248  		return
   249  	}
   250  	if _, ok := fType.Out(0).(*reflect.BoolType); !ok {
   251  		err = SetupError("function does not return a bool")
   252  		return
   253  	}
   254  
   255  	arguments := make([]reflect.Value, fType.NumIn())
   256  	rand := config.getRand()
   257  	maxCount := config.getMaxCount()
   258  
   259  	for i := 0; i < maxCount; i++ {
   260  		err = arbitraryValues(arguments, fType, config, rand)
   261  		if err != nil {
   262  			return
   263  		}
   264  
   265  		if !f.Call(arguments)[0].(*reflect.BoolValue).Get() {
   266  			err = &CheckError{i + 1, toInterfaces(arguments)}
   267  			return
   268  		}
   269  	}
   270  
   271  	return
   272  }
   273  
   274  // CheckEqual looks for an input on which f and g return different results.
   275  // It calls f and g repeatedly with arbitrary values for each argument.
   276  // If f and g return different answers, CheckEqual returns a *CheckEqualError
   277  // describing the input and the outputs.
   278  func CheckEqual(f, g interface{}, config *Config) (err os.Error) {
   279  	if config == nil {
   280  		config = &defaultConfig
   281  	}
   282  
   283  	x, xType, ok := functionAndType(f)
   284  	if !ok {
   285  		err = SetupError("f is not a function")
   286  		return
   287  	}
   288  	y, yType, ok := functionAndType(g)
   289  	if !ok {
   290  		err = SetupError("g is not a function")
   291  		return
   292  	}
   293  
   294  	if xType != yType {
   295  		err = SetupError("functions have different types")
   296  		return
   297  	}
   298  
   299  	arguments := make([]reflect.Value, xType.NumIn())
   300  	rand := config.getRand()
   301  	maxCount := config.getMaxCount()
   302  
   303  	for i := 0; i < maxCount; i++ {
   304  		err = arbitraryValues(arguments, xType, config, rand)
   305  		if err != nil {
   306  			return
   307  		}
   308  
   309  		xOut := toInterfaces(x.Call(arguments))
   310  		yOut := toInterfaces(y.Call(arguments))
   311  
   312  		if !reflect.DeepEqual(xOut, yOut) {
   313  			err = &CheckEqualError{CheckError{i + 1, toInterfaces(arguments)}, xOut, yOut}
   314  			return
   315  		}
   316  	}
   317  
   318  	return
   319  }
   320  
   321  // arbitraryValues writes Values to args such that args contains Values
   322  // suitable for calling f.
   323  func arbitraryValues(args []reflect.Value, f *reflect.FuncType, config *Config, rand *rand.Rand) (err os.Error) {
   324  	if config.Values != nil {
   325  		config.Values(args, rand)
   326  		return
   327  	}
   328  
   329  	for j := 0; j < len(args); j++ {
   330  		var ok bool
   331  		args[j], ok = Value(f.In(j), rand)
   332  		if !ok {
   333  			err = SetupError(fmt.Sprintf("cannot create arbitrary value of type %s for argument %d", f.In(j), j))
   334  			return
   335  		}
   336  	}
   337  
   338  	return
   339  }
   340  
   341  func functionAndType(f interface{}) (v *reflect.FuncValue, t *reflect.FuncType, ok bool) {
   342  	v, ok = reflect.NewValue(f).(*reflect.FuncValue)
   343  	if !ok {
   344  		return
   345  	}
   346  	t = v.Type().(*reflect.FuncType)
   347  	return
   348  }
   349  
   350  func toInterfaces(values []reflect.Value) []interface{} {
   351  	ret := make([]interface{}, len(values))
   352  	for i, v := range values {
   353  		ret[i] = v.Interface()
   354  	}
   355  	return ret
   356  }
   357  
   358  func toString(interfaces []interface{}) string {
   359  	s := make([]string, len(interfaces))
   360  	for i, v := range interfaces {
   361  		s[i] = fmt.Sprintf("%#v", v)
   362  	}
   363  	return strings.Join(s, ", ")
   364  }