Avoid relying on undefined behavior in assert.ObjectsAreEqual().

The previous assert.ObjectsAreEqual() implementation is broken in go 1.4beta1:

   x := uint64(3)
   log.Printf("equal? %t", assert.ObjectsAreEqual(3, x))

This prints "true" under Go 1.3 and "false" under 1.4beta1 (amd64/darwin).

The reason is that the ObjectsAreEqual() was comparing two reflect.Value values
for equality using ==, but the behavior of that operation is apparently
undefined (https://code.google.com/p/go/issues/detail?id=9034). The fix is to do
the type conversion and then do the comparison between two interface{} values.
pull/94/head
Neil Conway 2014-10-31 16:02:32 -07:00
parent d6577e08ec
commit 49c5c6cdb1
1 changed files with 7 additions and 9 deletions

View File

@ -36,15 +36,13 @@ func ObjectsAreEqual(expected, actual interface{}) bool {
return true
}
expectedValue := reflect.ValueOf(expected)
actualValue := reflect.ValueOf(actual)
if expectedValue == actualValue {
return true
}
// Attempt comparison after type conversion
if actualValue.Type().ConvertibleTo(expectedValue.Type()) && expectedValue == actualValue.Convert(expectedValue.Type()) {
return true
actualType := reflect.TypeOf(actual)
if reflect.TypeOf(actual).ConvertibleTo(reflect.TypeOf(expected)) {
expectedValue := reflect.ValueOf(expected)
// Attempt comparison after type conversion
if actual == expectedValue.Convert(actualType).Interface() {
return true
}
}
// Last ditch effort