diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 4975f5e41..46e3ccefa 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -837,6 +837,39 @@ func TestEqualFormatting(t *testing.T) { } } +func TestEqualFormattingWithPanic(t *testing.T) { + t.Parallel() + + type structWithUnexportedMapWithArrayKey struct { + m interface{} + } + + for _, c := range []struct { + a interface{} + b interface{} + }{ + { + // from the issue https://github.com/stretchr/testify/pull/1816 + a: structWithUnexportedMapWithArrayKey{ + map[[1]byte]*struct{}{ + {1}: nil, + {2}: nil, + }, + }, + b: structWithUnexportedMapWithArrayKey{}, + }, + } { + + mockT := new(mockTestingT) + NotPanics(t, func() { + Equal(mockT, c.a, c.b) + }, "should not panic") + + True(t, mockT.Failed(), "should have failed") + Contains(t, mockT.errorString(), "Not equal:", "error message should mention inequality") + } +} + func TestFormatUnequalValues(t *testing.T) { t.Parallel() diff --git a/internal/spew/common.go b/internal/spew/common.go index 1be8ce945..7551866a7 100644 --- a/internal/spew/common.go +++ b/internal/spew/common.go @@ -312,6 +312,12 @@ func valueSortLess(a, b reflect.Value) bool { for i := 0; i < l; i++ { av := a.Index(i) bv := b.Index(i) + + if !av.CanInterface() || !bv.CanInterface() { + // Unexported fields would panic on Interface() call. + continue + } + if av.Interface() == bv.Interface() { continue }