diff --git a/assert/assertions.go b/assert/assertions.go index 166f63726..e8c1291b3 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -771,6 +771,12 @@ func isEmptyValue(objValue reflect.Value) bool { // non-nil pointers are empty if the value they point to is empty case reflect.Ptr: return isEmptyValue(objValue.Elem()) + // a non-nil interface is empty if the concrete value it holds is empty. + // This also covers a pointer to an interface, whose Elem() has kind + // Interface: without this case such a value would fall through to the + // default and be reported as non-empty (regression from v1.11.0, #1955). + case reflect.Interface: + return isEmptyValue(objValue.Elem()) } return false } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 11642e096..45c4a37b7 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1772,6 +1772,9 @@ func Test_isEmpty(t *testing.T) { True(t, isEmpty((*int)(nil))) True(t, isEmpty((*string)(nil))) True(t, isEmpty(new(string))) + // pointer to an interface (regression test for #1955): empty when the + // interface it points to is nil or holds an empty concrete value. + True(t, isEmpty(new(error))) True(t, isEmpty([]string{})) True(t, isEmpty([]string(nil))) True(t, isEmpty([]byte(nil))) @@ -1828,6 +1831,8 @@ func Test_isEmpty(t *testing.T) { True(t, isEmpty(&[2]int{0, 0})) False(t, isEmpty("something")) False(t, isEmpty(errors.New("something"))) + // pointer to an interface holding a non-empty value (regression #1955) + False(t, isEmpty(func() *error { e := errors.New("boom"); return &e }())) False(t, isEmpty([]string{"something"})) False(t, isEmpty(1)) False(t, isEmpty(int(1)))