| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 | package assertionsimport (	"errors"	"fmt"	"math"	"reflect"	"strings"	"github.com/smartystreets/assertions/internal/oglematchers"	"github.com/smartystreets/assertions/internal/go-render/render")// default acceptable delta for ShouldAlmostEqualconst defaultDelta = 0.0000000001// ShouldEqual receives exactly two parameters and does an equality check.func ShouldEqual(actual interface{}, expected ...interface{}) string {	if message := need(1, expected); message != success {		return message	}	return shouldEqual(actual, expected[0])}func shouldEqual(actual, expected interface{}) (message string) {	defer func() {		if r := recover(); r != nil {			message = serializer.serialize(expected, actual, fmt.Sprintf(shouldHaveBeenEqual, expected, actual))			return		}	}()	if matchError := oglematchers.Equals(expected).Matches(actual); matchError != nil {		expectedSyntax := fmt.Sprintf("%v", expected)		actualSyntax := fmt.Sprintf("%v", actual)		if expectedSyntax == actualSyntax && reflect.TypeOf(expected) != reflect.TypeOf(actual) {			message = fmt.Sprintf(shouldHaveBeenEqualTypeMismatch, expected, expected, actual, actual)		} else {			message = fmt.Sprintf(shouldHaveBeenEqual, expected, actual)		}		message = serializer.serialize(expected, actual, message)		return	}	return success}// ShouldNotEqual receives exactly two parameters and does an inequality check.func ShouldNotEqual(actual interface{}, expected ...interface{}) string {	if fail := need(1, expected); fail != success {		return fail	} else if ShouldEqual(actual, expected[0]) == success {		return fmt.Sprintf(shouldNotHaveBeenEqual, actual, expected[0])	}	return success}// ShouldAlmostEqual makes sure that two parameters are close enough to being equal.// The acceptable delta may be specified with a third argument,// or a very small default delta will be used.func ShouldAlmostEqual(actual interface{}, expected ...interface{}) string {	actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...)	if err != "" {		return err	}	if math.Abs(actualFloat-expectedFloat) <= deltaFloat {		return success	} else {		return fmt.Sprintf(shouldHaveBeenAlmostEqual, actualFloat, expectedFloat)	}}// ShouldNotAlmostEqual is the inverse of ShouldAlmostEqualfunc ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) string {	actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...)	if err != "" {		return err	}	if math.Abs(actualFloat-expectedFloat) > deltaFloat {		return success	} else {		return fmt.Sprintf(shouldHaveNotBeenAlmostEqual, actualFloat, expectedFloat)	}}func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) (float64, float64, float64, string) {	deltaFloat := 0.0000000001	if len(expected) == 0 {		return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided neither)"	} else if len(expected) == 2 {		delta, err := getFloat(expected[1])		if err != nil {			return 0.0, 0.0, 0.0, "delta must be a numerical type"		}		deltaFloat = delta	} else if len(expected) > 2 {		return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided more values)"	}	actualFloat, err := getFloat(actual)	if err != nil {		return 0.0, 0.0, 0.0, err.Error()	}	expectedFloat, err := getFloat(expected[0])	if err != nil {		return 0.0, 0.0, 0.0, err.Error()	}	return actualFloat, expectedFloat, deltaFloat, ""}// returns the float value of any real number, or error if it is not a numerical typefunc getFloat(num interface{}) (float64, error) {	numValue := reflect.ValueOf(num)	numKind := numValue.Kind()	if numKind == reflect.Int ||		numKind == reflect.Int8 ||		numKind == reflect.Int16 ||		numKind == reflect.Int32 ||		numKind == reflect.Int64 {		return float64(numValue.Int()), nil	} else if numKind == reflect.Uint ||		numKind == reflect.Uint8 ||		numKind == reflect.Uint16 ||		numKind == reflect.Uint32 ||		numKind == reflect.Uint64 {		return float64(numValue.Uint()), nil	} else if numKind == reflect.Float32 ||		numKind == reflect.Float64 {		return numValue.Float(), nil	} else {		return 0.0, errors.New("must be a numerical type, but was " + numKind.String())	}}// ShouldResemble receives exactly two parameters and does a deep equal check (see reflect.DeepEqual)func ShouldResemble(actual interface{}, expected ...interface{}) string {	if message := need(1, expected); message != success {		return message	}	if matchError := oglematchers.DeepEquals(expected[0]).Matches(actual); matchError != nil {		return serializer.serializeDetailed(expected[0], actual,			fmt.Sprintf(shouldHaveResembled, render.Render(expected[0]), render.Render(actual)))	}	return success}// ShouldNotResemble receives exactly two parameters and does an inverse deep equal check (see reflect.DeepEqual)func ShouldNotResemble(actual interface{}, expected ...interface{}) string {	if message := need(1, expected); message != success {		return message	} else if ShouldResemble(actual, expected[0]) == success {		return fmt.Sprintf(shouldNotHaveResembled, render.Render(actual), render.Render(expected[0]))	}	return success}// ShouldPointTo receives exactly two parameters and checks to see that they point to the same address.func ShouldPointTo(actual interface{}, expected ...interface{}) string {	if message := need(1, expected); message != success {		return message	}	return shouldPointTo(actual, expected[0])}func shouldPointTo(actual, expected interface{}) string {	actualValue := reflect.ValueOf(actual)	expectedValue := reflect.ValueOf(expected)	if ShouldNotBeNil(actual) != success {		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "nil")	} else if ShouldNotBeNil(expected) != success {		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "nil")	} else if actualValue.Kind() != reflect.Ptr {		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "not")	} else if expectedValue.Kind() != reflect.Ptr {		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "not")	} else if ShouldEqual(actualValue.Pointer(), expectedValue.Pointer()) != success {		actualAddress := reflect.ValueOf(actual).Pointer()		expectedAddress := reflect.ValueOf(expected).Pointer()		return serializer.serialize(expectedAddress, actualAddress, fmt.Sprintf(shouldHavePointedTo,			actual, actualAddress,			expected, expectedAddress))	}	return success}// ShouldNotPointTo receives exactly two parameters and checks to see that they point to different addresess.func ShouldNotPointTo(actual interface{}, expected ...interface{}) string {	if message := need(1, expected); message != success {		return message	}	compare := ShouldPointTo(actual, expected[0])	if strings.HasPrefix(compare, shouldBePointers) {		return compare	} else if compare == success {		return fmt.Sprintf(shouldNotHavePointedTo, actual, expected[0], reflect.ValueOf(actual).Pointer())	}	return success}// ShouldBeNil receives a single parameter and ensures that it is nil.func ShouldBeNil(actual interface{}, expected ...interface{}) string {	if fail := need(0, expected); fail != success {		return fail	} else if actual == nil {		return success	} else if interfaceHasNilValue(actual) {		return success	}	return fmt.Sprintf(shouldHaveBeenNil, actual)}func interfaceHasNilValue(actual interface{}) bool {	value := reflect.ValueOf(actual)	kind := value.Kind()	nilable := kind == reflect.Slice ||		kind == reflect.Chan ||		kind == reflect.Func ||		kind == reflect.Ptr ||		kind == reflect.Map	// Careful: reflect.Value.IsNil() will panic unless it's an interface, chan, map, func, slice, or ptr	// Reference: http://golang.org/pkg/reflect/#Value.IsNil	return nilable && value.IsNil()}// ShouldNotBeNil receives a single parameter and ensures that it is not nil.func ShouldNotBeNil(actual interface{}, expected ...interface{}) string {	if fail := need(0, expected); fail != success {		return fail	} else if ShouldBeNil(actual) == success {		return fmt.Sprintf(shouldNotHaveBeenNil, actual)	}	return success}// ShouldBeTrue receives a single parameter and ensures that it is true.func ShouldBeTrue(actual interface{}, expected ...interface{}) string {	if fail := need(0, expected); fail != success {		return fail	} else if actual != true {		return fmt.Sprintf(shouldHaveBeenTrue, actual)	}	return success}// ShouldBeFalse receives a single parameter and ensures that it is false.func ShouldBeFalse(actual interface{}, expected ...interface{}) string {	if fail := need(0, expected); fail != success {		return fail	} else if actual != false {		return fmt.Sprintf(shouldHaveBeenFalse, actual)	}	return success}// ShouldBeZeroValue receives a single parameter and ensures that it is// the Go equivalent of the default value, or "zero" value.func ShouldBeZeroValue(actual interface{}, expected ...interface{}) string {	if fail := need(0, expected); fail != success {		return fail	}	zeroVal := reflect.Zero(reflect.TypeOf(actual)).Interface()	if !reflect.DeepEqual(zeroVal, actual) {		return serializer.serialize(zeroVal, actual, fmt.Sprintf(shouldHaveBeenZeroValue, actual))	}	return success}
 |