diff --git a/assert/assertions.go b/assert/assertions.go index cf1807e..eb3b39b 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -350,6 +350,37 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) } +// Same asserts that two pointers reference the same object. +// +// assert.Same(t, ptr1, ptr2) +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + expectedPtr, actualPtr := reflect.ValueOf(expected), reflect.ValueOf(actual) + if expectedPtr.Kind() != reflect.Ptr || actualPtr.Kind() != reflect.Ptr { + return Fail(t, "Invalid operation: both arguments must be pointers", msgAndArgs...) + } + + expectedType, actualType := reflect.TypeOf(expected), reflect.TypeOf(actual) + if expectedType != actualType { + return Fail(t, fmt.Sprintf("Pointer expected to be of type %v, but was %v", + expectedType, actualType), msgAndArgs...) + } + + if expected != actual { + return Fail(t, fmt.Sprintf("Not same: \n"+ + "expected: %p %#v\n"+ + "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) + } + + return true +} + // formatUnequalValues takes two values of arbitrary types and returns string // representations appropriate to be presented to the user. // diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 00e2d21..332271e 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -217,6 +217,29 @@ func TestEqual(t *testing.T) { } } +func TestSame(t *testing.T) { + + mockT := new(testing.T) + + ptr := func(i int) *int { + return &i + } + + if Same(mockT, ptr(1), ptr(1)) { + t.Error("Same should return false") + } + if Same(mockT, 1, 1) { + t.Error("Same should return false") + } + p := ptr(2) + if Same(mockT, p, *p) { + t.Error("Same should return false") + } + if !Same(mockT, p, p) { + t.Error("Same should return true") + } +} + // bufferT implements TestingT. Its implementation of Errorf writes the output that would be produced by // testing.T.Errorf to an internal bytes.Buffer. type bufferT struct {