testify/assert/assertions.go

197 lines
4.9 KiB
Go

package assert
import (
"fmt"
"reflect"
"runtime"
"strings"
"testing"
)
/*
Helper functions
*/
// ObjectsAreEqual determines if two objects are considered equal.
//
// This function does no assertion of any kind.
func ObjectsAreEqual(a, b interface{}) bool {
if reflect.DeepEqual(a, b) {
return true
}
if reflect.ValueOf(a) == reflect.ValueOf(b) {
return true
}
return false
}
/* CallerInfo is necessary because the assert functions use the testing object
internally, causing it to print the file:line of the assert method, rather than where
the problem actually occured in calling code.*/
// CallerInfo returns a string containing the file and line number of the assert call
// that failed.
func CallerInfo() string {
_, file, line, ok := runtime.Caller(0)
if !ok {
return ""
}
parts := strings.Split(file, "/")
thisDir := parts[len(parts)-2]
for i := 1; ; i++ {
_, file, line, ok = runtime.Caller(i)
if !ok {
return ""
}
parts = strings.Split(file, "/")
dir := parts[len(parts)-2]
file = parts[len(parts)-1]
if thisDir != dir || file == "assertions_test.go" {
break
}
}
return fmt.Sprintf("[ %s:%d ] - ", file, line)
}
// Implements asserts that an object is implemented by the specified interface.
//
// Example
// assert.Implements(t, (*core.Codec)(nil), new(JsonCodec), "JsonCodec")
func Implements(t *testing.T, interfaceObject interface{}, object interface{}, message ...string) bool {
interfaceType := reflect.TypeOf(interfaceObject).Elem()
return True(t, reflect.TypeOf(object).Implements(interfaceType), fmt.Sprintf("%sObject must implement %s. %s", CallerInfo(), interfaceType, message))
}
// IsType asserts that the specified object is of the specified type.
func IsType(t *testing.T, expectedType interface{}, object interface{}, message ...string) bool {
return Equal(t, reflect.TypeOf(object), reflect.TypeOf(expectedType), fmt.Sprintf("Object expected to be of type %s, but was %s. %s", reflect.TypeOf(expectedType), reflect.TypeOf(object), message))
}
// Equal asserts that two objects are equal.
func Equal(t *testing.T, a, b interface{}, message ...string) bool {
if !ObjectsAreEqual(a, b) {
t.Errorf("%s%s Not equal. %#v != %#v.", CallerInfo(), message, a, b)
return false
}
return true
}
// NotNil asserts that the specified object is not nil.
func NotNil(t *testing.T, object interface{}, message ...string) bool {
var success bool = true
if object == nil {
success = false
} else if reflect.ValueOf(object).IsNil() {
success = false
}
if !success {
t.Errorf("%sExpected not to be nil. %s", CallerInfo(), message)
}
return success
}
// Nil asserts that the specified object is nil.
func Nil(t *testing.T, object interface{}, message ...string) bool {
if object == nil {
return true
} else if reflect.ValueOf(object).IsNil() {
return true
}
t.Errorf("%sExpected to be nil but was %#v. %s", CallerInfo(), object, message)
return false
}
// True asserts that the specified value is true.
func True(t *testing.T, value bool, message ...string) bool {
return Equal(t, true, value, message...)
}
// False asserts that the specified value is true.
func False(t *testing.T, value bool, message ...string) bool {
return Equal(t, false, value, message...)
}
// NotEqual asserts that the specified values are NOT equal.
func NotEqual(t *testing.T, a, b interface{}, message ...string) bool {
if ObjectsAreEqual(a, b) {
t.Errorf("%s%s Should not be equal. %#v == %#v.", CallerInfo(), message, a, b)
return false
}
return true
}
// Contains asserts that the specified string contains the specified substring.
func Contains(t *testing.T, s, contains string, message ...string) bool {
if !strings.Contains(s, contains) {
t.Errorf("%s %s '%s' does not contain '%s'", CallerInfo(), message, s, contains)
return false
}
return true
}
// NotContains asserts that the specified string does NOT contain the specified substring.
func NotContains(t *testing.T, s, contains string, message ...string) bool {
if strings.Contains(s, contains) {
t.Errorf("%s%s '%s' should not contain '%s'", CallerInfo(), message, s, contains)
return false
}
return true
}
// PanicTestFunc defines a type that is used for type checking and convenience
type PanicTestFunc func()
// didPanic returns true if the function passed to it panics. Otherwise, it returns false.
func didPanic(f PanicTestFunc) bool {
var didPanic bool = false
func() {
defer func() {
if r := recover(); r != nil {
didPanic = true
}
}()
// call the target function
f()
}()
return didPanic
}
// Panics asserts that the function passed to it panics
func Panics(t *testing.T, f PanicTestFunc, message ...string) bool {
return True(t, didPanic(f), fmt.Sprintf("Func should panic but didn't. %s", message))
}
// NotPanics asserts that the function passed to it does not panic
func NotPanics(t *testing.T, f PanicTestFunc, message ...string) bool {
return False(t, didPanic(f), fmt.Sprintf("Func should not panic. %s", message))
}