From 49c5c6cdb11776deb678dd3bb48e1e79e7e33943 Mon Sep 17 00:00:00 2001 From: Neil Conway Date: Fri, 31 Oct 2014 16:02:32 -0700 Subject: [PATCH] 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. --- assert/assertions.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 5de1ab1..f3921b0 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -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