diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 56a7779..679f279 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -45,7 +45,8 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) } diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 2c09998..cedbdee 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -72,7 +72,8 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return Equal(a.t, expected, actual, msgAndArgs...) } @@ -126,7 +127,8 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { return Equalf(a.t, expected, actual, msg, args...) } diff --git a/assert/assertions.go b/assert/assertions.go index 2826738..9fe00d6 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "encoding/json" + "errors" "fmt" "math" "reflect" @@ -300,8 +301,13 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", + expected, actual, err), msgAndArgs...) + } if !ObjectsAreEqual(expected, actual) { diff := diff(expected, actual) @@ -575,6 +581,10 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", + expected, actual, err), msgAndArgs...) + } if ObjectsAreEqual(expected, actual) { return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) @@ -1155,6 +1165,22 @@ func diff(expected interface{}, actual interface{}) string { return "\n\nDiff:\n" + diff } +// validateEqualArgs checks whether provided arguments can be safely used in the +// Equal/NotEqual functions. +func validateEqualArgs(expected, actual interface{}) error { + if isFunction(expected) || isFunction(actual) { + return errors.New("cannot take func type as argument") + } + return nil +} + +func isFunction(arg interface{}) bool { + if arg == nil { + return false + } + return reflect.TypeOf(arg).Kind() == reflect.Func +} + var spewConfig = spew.ConfigState{ Indent: " ", DisablePointerAddresses: true, diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 96ecf33..0009be5 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -396,8 +396,8 @@ func TestNotEqual(t *testing.T) { } funcA := func() int { return 23 } funcB := func() int { return 42 } - if !NotEqual(mockT, funcA, funcB) { - t.Error("NotEqual should return true") + if NotEqual(mockT, funcA, funcB) { + t.Error("NotEqual should return false") } if NotEqual(mockT, "Hello World", "Hello World") { @@ -1375,3 +1375,8 @@ func BenchmarkBytesEqual(b *testing.B) { Equal(mockT, s, s2) } } + +func TestEqualArgsValidation(t *testing.T) { + err := validateEqualArgs(time.Now, time.Now) + EqualError(t, err, "cannot take func type as argument") +} diff --git a/require/require.go b/require/require.go index f990eaf..cc39791 100644 --- a/require/require.go +++ b/require/require.go @@ -85,7 +85,8 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if !assert.Equal(t, expected, actual, msgAndArgs...) { t.FailNow() @@ -149,7 +150,8 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if !assert.Equalf(t, expected, actual, msg, args...) { t.FailNow() diff --git a/require/require_forward.go b/require/require_forward.go index 1a0de74..fadac2f 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -73,7 +73,8 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { Equal(a.t, expected, actual, msgAndArgs...) } @@ -127,7 +128,8 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg // Returns whether the assertion was successful (true) or not (false). // // Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) { Equalf(a.t, expected, actual, msg, args...) }