diff options
Diffstat (limited to 'src/pkg/testing/quick')
-rw-r--r-- | src/pkg/testing/quick/quick.go | 358 | ||||
-rw-r--r-- | src/pkg/testing/quick/quick_test.go | 249 |
2 files changed, 0 insertions, 607 deletions
diff --git a/src/pkg/testing/quick/quick.go b/src/pkg/testing/quick/quick.go deleted file mode 100644 index bc79cc329..000000000 --- a/src/pkg/testing/quick/quick.go +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package quick implements utility functions to help with black box testing. -package quick - -import ( - "flag" - "fmt" - "math" - "math/rand" - "reflect" - "strings" -) - -var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check") - -// A Generator can generate random values of its own type. -type Generator interface { - // Generate returns a random instance of the type on which it is a - // method using the size as a size hint. - Generate(rand *rand.Rand, size int) reflect.Value -} - -// randFloat32 generates a random float taking the full range of a float32. -func randFloat32(rand *rand.Rand) float32 { - f := rand.Float64() * math.MaxFloat32 - if rand.Int()&1 == 1 { - f = -f - } - return float32(f) -} - -// randFloat64 generates a random float taking the full range of a float64. -func randFloat64(rand *rand.Rand) float64 { - f := rand.Float64() * math.MaxFloat64 - if rand.Int()&1 == 1 { - f = -f - } - return f -} - -// randInt64 returns a random integer taking half the range of an int64. -func randInt64(rand *rand.Rand) int64 { return rand.Int63() - 1<<62 } - -// complexSize is the maximum length of arbitrary values that contain other -// values. -const complexSize = 50 - -// Value returns an arbitrary value of the given type. -// If the type implements the Generator interface, that will be used. -// Note: To create arbitrary values for structs, all the fields must be exported. -func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { - if m, ok := reflect.Zero(t).Interface().(Generator); ok { - return m.Generate(rand, complexSize), true - } - - v := reflect.New(t).Elem() - switch concrete := t; concrete.Kind() { - case reflect.Bool: - v.SetBool(rand.Int()&1 == 0) - case reflect.Float32: - v.SetFloat(float64(randFloat32(rand))) - case reflect.Float64: - v.SetFloat(randFloat64(rand)) - case reflect.Complex64: - v.SetComplex(complex(float64(randFloat32(rand)), float64(randFloat32(rand)))) - case reflect.Complex128: - v.SetComplex(complex(randFloat64(rand), randFloat64(rand))) - case reflect.Int16: - v.SetInt(randInt64(rand)) - case reflect.Int32: - v.SetInt(randInt64(rand)) - case reflect.Int64: - v.SetInt(randInt64(rand)) - case reflect.Int8: - v.SetInt(randInt64(rand)) - case reflect.Int: - v.SetInt(randInt64(rand)) - case reflect.Uint16: - v.SetUint(uint64(randInt64(rand))) - case reflect.Uint32: - v.SetUint(uint64(randInt64(rand))) - case reflect.Uint64: - v.SetUint(uint64(randInt64(rand))) - case reflect.Uint8: - v.SetUint(uint64(randInt64(rand))) - case reflect.Uint: - v.SetUint(uint64(randInt64(rand))) - case reflect.Uintptr: - v.SetUint(uint64(randInt64(rand))) - case reflect.Map: - numElems := rand.Intn(complexSize) - v.Set(reflect.MakeMap(concrete)) - for i := 0; i < numElems; i++ { - key, ok1 := Value(concrete.Key(), rand) - value, ok2 := Value(concrete.Elem(), rand) - if !ok1 || !ok2 { - return reflect.Value{}, false - } - v.SetMapIndex(key, value) - } - case reflect.Ptr: - elem, ok := Value(concrete.Elem(), rand) - if !ok { - return reflect.Value{}, false - } - v.Set(reflect.New(concrete.Elem())) - v.Elem().Set(elem) - case reflect.Slice: - numElems := rand.Intn(complexSize) - v.Set(reflect.MakeSlice(concrete, numElems, numElems)) - for i := 0; i < numElems; i++ { - elem, ok := Value(concrete.Elem(), rand) - if !ok { - return reflect.Value{}, false - } - v.Index(i).Set(elem) - } - case reflect.String: - numChars := rand.Intn(complexSize) - codePoints := make([]rune, numChars) - for i := 0; i < numChars; i++ { - codePoints[i] = rune(rand.Intn(0x10ffff)) - } - v.SetString(string(codePoints)) - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - elem, ok := Value(concrete.Field(i).Type, rand) - if !ok { - return reflect.Value{}, false - } - v.Field(i).Set(elem) - } - default: - return reflect.Value{}, false - } - - return v, true -} - -// A Config structure contains options for running a test. -type Config struct { - // MaxCount sets the maximum number of iterations. If zero, - // MaxCountScale is used. - MaxCount int - // MaxCountScale is a non-negative scale factor applied to the default - // maximum. If zero, the default is unchanged. - MaxCountScale float64 - // If non-nil, rand is a source of random numbers. Otherwise a default - // pseudo-random source will be used. - Rand *rand.Rand - // If non-nil, the Values function generates a slice of arbitrary - // reflect.Values that are congruent with the arguments to the function - // being tested. Otherwise, the top-level Values function is used - // to generate them. - Values func([]reflect.Value, *rand.Rand) -} - -var defaultConfig Config - -// getRand returns the *rand.Rand to use for a given Config. -func (c *Config) getRand() *rand.Rand { - if c.Rand == nil { - return rand.New(rand.NewSource(0)) - } - return c.Rand -} - -// getMaxCount returns the maximum number of iterations to run for a given -// Config. -func (c *Config) getMaxCount() (maxCount int) { - maxCount = c.MaxCount - if maxCount == 0 { - if c.MaxCountScale != 0 { - maxCount = int(c.MaxCountScale * float64(*defaultMaxCount)) - } else { - maxCount = *defaultMaxCount - } - } - - return -} - -// A SetupError is the result of an error in the way that check is being -// used, independent of the functions being tested. -type SetupError string - -func (s SetupError) Error() string { return string(s) } - -// A CheckError is the result of Check finding an error. -type CheckError struct { - Count int - In []interface{} -} - -func (s *CheckError) Error() string { - return fmt.Sprintf("#%d: failed on input %s", s.Count, toString(s.In)) -} - -// A CheckEqualError is the result CheckEqual finding an error. -type CheckEqualError struct { - CheckError - Out1 []interface{} - Out2 []interface{} -} - -func (s *CheckEqualError) Error() string { - 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)) -} - -// Check looks for an input to f, any function that returns bool, -// such that f returns false. It calls f repeatedly, with arbitrary -// values for each argument. If f returns false on a given input, -// Check returns that input as a *CheckError. -// For example: -// -// func TestOddMultipleOfThree(t *testing.T) { -// f := func(x int) bool { -// y := OddMultipleOfThree(x) -// return y%2 == 1 && y%3 == 0 -// } -// if err := quick.Check(f, nil); err != nil { -// t.Error(err) -// } -// } -func Check(function interface{}, config *Config) (err error) { - if config == nil { - config = &defaultConfig - } - - f, fType, ok := functionAndType(function) - if !ok { - err = SetupError("argument is not a function") - return - } - - if fType.NumOut() != 1 { - err = SetupError("function returns more than one value.") - return - } - if fType.Out(0).Kind() != reflect.Bool { - err = SetupError("function does not return a bool") - return - } - - arguments := make([]reflect.Value, fType.NumIn()) - rand := config.getRand() - maxCount := config.getMaxCount() - - for i := 0; i < maxCount; i++ { - err = arbitraryValues(arguments, fType, config, rand) - if err != nil { - return - } - - if !f.Call(arguments)[0].Bool() { - err = &CheckError{i + 1, toInterfaces(arguments)} - return - } - } - - return -} - -// CheckEqual looks for an input on which f and g return different results. -// It calls f and g repeatedly with arbitrary values for each argument. -// If f and g return different answers, CheckEqual returns a *CheckEqualError -// describing the input and the outputs. -func CheckEqual(f, g interface{}, config *Config) (err error) { - if config == nil { - config = &defaultConfig - } - - x, xType, ok := functionAndType(f) - if !ok { - err = SetupError("f is not a function") - return - } - y, yType, ok := functionAndType(g) - if !ok { - err = SetupError("g is not a function") - return - } - - if xType != yType { - err = SetupError("functions have different types") - return - } - - arguments := make([]reflect.Value, xType.NumIn()) - rand := config.getRand() - maxCount := config.getMaxCount() - - for i := 0; i < maxCount; i++ { - err = arbitraryValues(arguments, xType, config, rand) - if err != nil { - return - } - - xOut := toInterfaces(x.Call(arguments)) - yOut := toInterfaces(y.Call(arguments)) - - if !reflect.DeepEqual(xOut, yOut) { - err = &CheckEqualError{CheckError{i + 1, toInterfaces(arguments)}, xOut, yOut} - return - } - } - - return -} - -// arbitraryValues writes Values to args such that args contains Values -// suitable for calling f. -func arbitraryValues(args []reflect.Value, f reflect.Type, config *Config, rand *rand.Rand) (err error) { - if config.Values != nil { - config.Values(args, rand) - return - } - - for j := 0; j < len(args); j++ { - var ok bool - args[j], ok = Value(f.In(j), rand) - if !ok { - err = SetupError(fmt.Sprintf("cannot create arbitrary value of type %s for argument %d", f.In(j), j)) - return - } - } - - return -} - -func functionAndType(f interface{}) (v reflect.Value, t reflect.Type, ok bool) { - v = reflect.ValueOf(f) - ok = v.Kind() == reflect.Func - if !ok { - return - } - t = v.Type() - return -} - -func toInterfaces(values []reflect.Value) []interface{} { - ret := make([]interface{}, len(values)) - for i, v := range values { - ret[i] = v.Interface() - } - return ret -} - -func toString(interfaces []interface{}) string { - s := make([]string, len(interfaces)) - for i, v := range interfaces { - s[i] = fmt.Sprintf("%#v", v) - } - return strings.Join(s, ", ") -} diff --git a/src/pkg/testing/quick/quick_test.go b/src/pkg/testing/quick/quick_test.go deleted file mode 100644 index e925ba675..000000000 --- a/src/pkg/testing/quick/quick_test.go +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package quick - -import ( - "math/rand" - "reflect" - "testing" -) - -func fBool(a bool) bool { return a } - -type TestBoolAlias bool - -func fBoolAlias(a TestBoolAlias) TestBoolAlias { return a } - -func fFloat32(a float32) float32 { return a } - -type TestFloat32Alias float32 - -func fFloat32Alias(a TestFloat32Alias) TestFloat32Alias { return a } - -func fFloat64(a float64) float64 { return a } - -type TestFloat64Alias float64 - -func fFloat64Alias(a TestFloat64Alias) TestFloat64Alias { return a } - -func fComplex64(a complex64) complex64 { return a } - -type TestComplex64Alias complex64 - -func fComplex64Alias(a TestComplex64Alias) TestComplex64Alias { return a } - -func fComplex128(a complex128) complex128 { return a } - -type TestComplex128Alias complex128 - -func fComplex128Alias(a TestComplex128Alias) TestComplex128Alias { return a } - -func fInt16(a int16) int16 { return a } - -type TestInt16Alias int16 - -func fInt16Alias(a TestInt16Alias) TestInt16Alias { return a } - -func fInt32(a int32) int32 { return a } - -type TestInt32Alias int32 - -func fInt32Alias(a TestInt32Alias) TestInt32Alias { return a } - -func fInt64(a int64) int64 { return a } - -type TestInt64Alias int64 - -func fInt64Alias(a TestInt64Alias) TestInt64Alias { return a } - -func fInt8(a int8) int8 { return a } - -type TestInt8Alias int8 - -func fInt8Alias(a TestInt8Alias) TestInt8Alias { return a } - -func fInt(a int) int { return a } - -type TestIntAlias int - -func fIntAlias(a TestIntAlias) TestIntAlias { return a } - -func fMap(a map[int]int) map[int]int { return a } - -type TestMapAlias map[int]int - -func fMapAlias(a TestMapAlias) TestMapAlias { return a } - -func fSlice(a []byte) []byte { return a } - -type TestSliceAlias []byte - -func fSliceAlias(a TestSliceAlias) TestSliceAlias { return a } - -func fString(a string) string { return a } - -type TestStringAlias string - -func fStringAlias(a TestStringAlias) TestStringAlias { return a } - -type TestStruct struct { - A int - B string -} - -func fStruct(a TestStruct) TestStruct { return a } - -type TestStructAlias TestStruct - -func fStructAlias(a TestStructAlias) TestStructAlias { return a } - -func fUint16(a uint16) uint16 { return a } - -type TestUint16Alias uint16 - -func fUint16Alias(a TestUint16Alias) TestUint16Alias { return a } - -func fUint32(a uint32) uint32 { return a } - -type TestUint32Alias uint32 - -func fUint32Alias(a TestUint32Alias) TestUint32Alias { return a } - -func fUint64(a uint64) uint64 { return a } - -type TestUint64Alias uint64 - -func fUint64Alias(a TestUint64Alias) TestUint64Alias { return a } - -func fUint8(a uint8) uint8 { return a } - -type TestUint8Alias uint8 - -func fUint8Alias(a TestUint8Alias) TestUint8Alias { return a } - -func fUint(a uint) uint { return a } - -type TestUintAlias uint - -func fUintAlias(a TestUintAlias) TestUintAlias { return a } - -func fUintptr(a uintptr) uintptr { return a } - -type TestUintptrAlias uintptr - -func fUintptrAlias(a TestUintptrAlias) TestUintptrAlias { return a } - -func fIntptr(a *int) *int { - b := *a - return &b -} - -type TestIntptrAlias *int - -func fIntptrAlias(a TestIntptrAlias) TestIntptrAlias { return a } - -func reportError(property string, err error, t *testing.T) { - if err != nil { - t.Errorf("%s: %s", property, err) - } -} - -func TestCheckEqual(t *testing.T) { - reportError("fBool", CheckEqual(fBool, fBool, nil), t) - reportError("fBoolAlias", CheckEqual(fBoolAlias, fBoolAlias, nil), t) - reportError("fFloat32", CheckEqual(fFloat32, fFloat32, nil), t) - reportError("fFloat32Alias", CheckEqual(fFloat32Alias, fFloat32Alias, nil), t) - reportError("fFloat64", CheckEqual(fFloat64, fFloat64, nil), t) - reportError("fFloat64Alias", CheckEqual(fFloat64Alias, fFloat64Alias, nil), t) - reportError("fComplex64", CheckEqual(fComplex64, fComplex64, nil), t) - reportError("fComplex64Alias", CheckEqual(fComplex64Alias, fComplex64Alias, nil), t) - reportError("fComplex128", CheckEqual(fComplex128, fComplex128, nil), t) - reportError("fComplex128Alias", CheckEqual(fComplex128Alias, fComplex128Alias, nil), t) - reportError("fInt16", CheckEqual(fInt16, fInt16, nil), t) - reportError("fInt16Alias", CheckEqual(fInt16Alias, fInt16Alias, nil), t) - reportError("fInt32", CheckEqual(fInt32, fInt32, nil), t) - reportError("fInt32Alias", CheckEqual(fInt32Alias, fInt32Alias, nil), t) - reportError("fInt64", CheckEqual(fInt64, fInt64, nil), t) - reportError("fInt64Alias", CheckEqual(fInt64Alias, fInt64Alias, nil), t) - reportError("fInt8", CheckEqual(fInt8, fInt8, nil), t) - reportError("fInt8Alias", CheckEqual(fInt8Alias, fInt8Alias, nil), t) - reportError("fInt", CheckEqual(fInt, fInt, nil), t) - reportError("fIntAlias", CheckEqual(fIntAlias, fIntAlias, nil), t) - reportError("fInt32", CheckEqual(fInt32, fInt32, nil), t) - reportError("fInt32Alias", CheckEqual(fInt32Alias, fInt32Alias, nil), t) - reportError("fMap", CheckEqual(fMap, fMap, nil), t) - reportError("fMapAlias", CheckEqual(fMapAlias, fMapAlias, nil), t) - reportError("fSlice", CheckEqual(fSlice, fSlice, nil), t) - reportError("fSliceAlias", CheckEqual(fSliceAlias, fSliceAlias, nil), t) - reportError("fString", CheckEqual(fString, fString, nil), t) - reportError("fStringAlias", CheckEqual(fStringAlias, fStringAlias, nil), t) - reportError("fStruct", CheckEqual(fStruct, fStruct, nil), t) - reportError("fStructAlias", CheckEqual(fStructAlias, fStructAlias, nil), t) - reportError("fUint16", CheckEqual(fUint16, fUint16, nil), t) - reportError("fUint16Alias", CheckEqual(fUint16Alias, fUint16Alias, nil), t) - reportError("fUint32", CheckEqual(fUint32, fUint32, nil), t) - reportError("fUint32Alias", CheckEqual(fUint32Alias, fUint32Alias, nil), t) - reportError("fUint64", CheckEqual(fUint64, fUint64, nil), t) - reportError("fUint64Alias", CheckEqual(fUint64Alias, fUint64Alias, nil), t) - reportError("fUint8", CheckEqual(fUint8, fUint8, nil), t) - reportError("fUint8Alias", CheckEqual(fUint8Alias, fUint8Alias, nil), t) - reportError("fUint", CheckEqual(fUint, fUint, nil), t) - reportError("fUintAlias", CheckEqual(fUintAlias, fUintAlias, nil), t) - reportError("fUintptr", CheckEqual(fUintptr, fUintptr, nil), t) - reportError("fUintptrAlias", CheckEqual(fUintptrAlias, fUintptrAlias, nil), t) - reportError("fIntptr", CheckEqual(fIntptr, fIntptr, nil), t) - reportError("fIntptrAlias", CheckEqual(fIntptrAlias, fIntptrAlias, nil), t) -} - -// This tests that ArbitraryValue is working by checking that all the arbitrary -// values of type MyStruct have x = 42. -type myStruct struct { - x int -} - -func (m myStruct) Generate(r *rand.Rand, _ int) reflect.Value { - return reflect.ValueOf(myStruct{x: 42}) -} - -func myStructProperty(in myStruct) bool { return in.x == 42 } - -func TestCheckProperty(t *testing.T) { - reportError("myStructProperty", Check(myStructProperty, nil), t) -} - -func TestFailure(t *testing.T) { - f := func(x int) bool { return false } - err := Check(f, nil) - if err == nil { - t.Errorf("Check didn't return an error") - } - if _, ok := err.(*CheckError); !ok { - t.Errorf("Error was not a CheckError: %s", err) - } - - err = CheckEqual(fUint, fUint32, nil) - if err == nil { - t.Errorf("#1 CheckEqual didn't return an error") - } - if _, ok := err.(SetupError); !ok { - t.Errorf("#1 Error was not a SetupError: %s", err) - } - - err = CheckEqual(func(x, y int) {}, func(x int) {}, nil) - if err == nil { - t.Errorf("#2 CheckEqual didn't return an error") - } - if _, ok := err.(SetupError); !ok { - t.Errorf("#2 Error was not a SetupError: %s", err) - } - - err = CheckEqual(func(x int) int { return 0 }, func(x int) int32 { return 0 }, nil) - if err == nil { - t.Errorf("#3 CheckEqual didn't return an error") - } - if _, ok := err.(SetupError); !ok { - t.Errorf("#3 Error was not a SetupError: %s", err) - } -} |