Test unexported field access in format logic (#41)
The format logic should work even if the reflect.Value is in RO mode.
diff --git a/cmp/internal/value/format.go b/cmp/internal/value/format.go
index abaeca8..9b27152 100644
--- a/cmp/internal/value/format.go
+++ b/cmp/internal/value/format.go
@@ -13,10 +13,6 @@
"unicode/utf8"
)
-// formatFakePointers controls whether to substitute pointer addresses with nil.
-// This is used for deterministic testing.
-var formatFakePointers = false
-
var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
// Format formats the value v as a string.
@@ -27,7 +23,7 @@
// * Prints a nil-slice as being nil, not empty
// * Prints map entries in deterministic order
func Format(v reflect.Value, useStringer bool) string {
- return formatAny(v, formatConfig{useStringer, true, true, !formatFakePointers}, nil)
+ return formatAny(v, formatConfig{useStringer, true, true, true}, nil)
}
type formatConfig struct {
diff --git a/cmp/internal/value/format_test.go b/cmp/internal/value/format_test.go
index 6498854..b56380f 100644
--- a/cmp/internal/value/format_test.go
+++ b/cmp/internal/value/format_test.go
@@ -80,10 +80,12 @@
want: "[2]interface {}{&[2]interface {}{(*[2]interface {})(0x00), interface {}(nil)}, interface {}(nil)}",
}}
- formatFakePointers = true
- defer func() { formatFakePointers = false }()
for i, tt := range tests {
- got := Format(reflect.ValueOf(tt.in), true)
+ // Intentionally retrieve the value through an unexported field to
+ // ensure the format logic does not depend on read-write access
+ // to the reflect.Value.
+ v := reflect.ValueOf(struct{ x interface{} }{tt.in}).Field(0)
+ got := formatAny(v, formatConfig{useStringer: true, printType: true, followPointers: true}, nil)
if got != tt.want {
t.Errorf("test %d, Format():\ngot %q\nwant %q", i, got, tt.want)
}