diff --git a/cmp/report_compare.go b/cmp/report_compare.go index 17a05ee..d3fa154 100644 --- a/cmp/report_compare.go +++ b/cmp/report_compare.go @@ -81,14 +81,19 @@ func (opts formatOptions) FormatDiff(v *valueNode) textNode { return opts.FormatDiffSlice(v) } + var withinSlice bool + if v.parent != nil && (v.parent.Type.Kind() == reflect.Slice || v.parent.Type.Kind() == reflect.Array) { + withinSlice = true + } + // For leaf nodes, format the value based on the reflect.Values alone. if v.MaxDepth == 0 { switch opts.DiffMode { case diffUnknown, diffIdentical: // Format Equal. if v.NumDiff == 0 { - outx := opts.FormatValue(v.ValueX, visitedPointers{}) - outy := opts.FormatValue(v.ValueY, visitedPointers{}) + outx := opts.FormatValue(v.ValueX, withinSlice, visitedPointers{}) + outy := opts.FormatValue(v.ValueY, withinSlice, visitedPointers{}) if v.NumIgnored > 0 && v.NumSame == 0 { return textEllipsis } else if outx.Len() < outy.Len() { @@ -101,8 +106,8 @@ func (opts formatOptions) FormatDiff(v *valueNode) textNode { // Format unequal. assert(opts.DiffMode == diffUnknown) var list textList - outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, visitedPointers{}) - outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, visitedPointers{}) + outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, withinSlice, visitedPointers{}) + outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, withinSlice, visitedPointers{}) if outx != nil { list = append(list, textRecord{Diff: '-', Value: outx}) } @@ -111,9 +116,9 @@ func (opts formatOptions) FormatDiff(v *valueNode) textNode { } return opts.WithTypeMode(emitType).FormatType(v.Type, list) case diffRemoved: - return opts.FormatValue(v.ValueX, visitedPointers{}) + return opts.FormatValue(v.ValueX, withinSlice, visitedPointers{}) case diffInserted: - return opts.FormatValue(v.ValueY, visitedPointers{}) + return opts.FormatValue(v.ValueY, withinSlice, visitedPointers{}) default: panic("invalid diff mode") } diff --git a/cmp/report_reflect.go b/cmp/report_reflect.go index 2761b62..8f10883 100644 --- a/cmp/report_reflect.go +++ b/cmp/report_reflect.go @@ -74,7 +74,7 @@ func (opts formatOptions) FormatType(t reflect.Type, s textNode) textNode { // FormatValue prints the reflect.Value, taking extra care to avoid descending // into pointers already in m. As pointers are visited, m is also updated. -func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out textNode) { +func (opts formatOptions) FormatValue(v reflect.Value, withinSlice bool, m visitedPointers) (out textNode) { if !v.IsValid() { return nil } @@ -108,12 +108,15 @@ func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out t return textLine(fmt.Sprint(v.Bool())) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return textLine(fmt.Sprint(v.Int())) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - // Unnamed uints are usually bytes or words, so use hexadecimal. - if t.PkgPath() == "" || t.Kind() == reflect.Uintptr { + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return textLine(fmt.Sprint(v.Uint())) + case reflect.Uint8: + if withinSlice { return textLine(formatHex(v.Uint())) } return textLine(fmt.Sprint(v.Uint())) + case reflect.Uintptr: + return textLine(formatHex(v.Uint())) case reflect.Float32, reflect.Float64: return textLine(fmt.Sprint(v.Float())) case reflect.Complex64, reflect.Complex128: @@ -129,7 +132,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out t if value.IsZero(vv) { continue // Elide fields with zero values } - s := opts.WithTypeMode(autoType).FormatValue(vv, m) + s := opts.WithTypeMode(autoType).FormatValue(vv, false, m) list = append(list, textRecord{Key: t.Field(i).Name, Value: s}) } return textWrap{"{", list, "}"} @@ -156,7 +159,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out t continue } } - s := opts.WithTypeMode(elideType).FormatValue(vi, m) + s := opts.WithTypeMode(elideType).FormatValue(vi, true, m) list = append(list, textRecord{Value: s}) } return textWrap{ptr + "{", list, "}"} @@ -171,7 +174,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out t var list textList for _, k := range value.SortKeys(v.MapKeys()) { sk := formatMapKey(k) - sv := opts.WithTypeMode(elideType).FormatValue(v.MapIndex(k), m) + sv := opts.WithTypeMode(elideType).FormatValue(v.MapIndex(k), false, m) list = append(list, textRecord{Key: sk, Value: sv}) } if opts.PrintAddresses { @@ -189,7 +192,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out t ptr = formatPointer(v) } skipType = true // Let the underlying value print the type instead - return textWrap{"&" + ptr, opts.FormatValue(v.Elem(), m), ""} + return textWrap{"&" + ptr, opts.FormatValue(v.Elem(), false, m), ""} case reflect.Interface: if v.IsNil() { return textNil @@ -197,7 +200,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out t // Interfaces accept different concrete types, // so configure the underlying value to explicitly print the type. skipType = true // Print the concrete type instead - return opts.WithTypeMode(emitType).FormatValue(v.Elem(), m) + return opts.WithTypeMode(emitType).FormatValue(v.Elem(), false, m) default: panic(fmt.Sprintf("%v kind not handled", v.Kind())) } @@ -209,7 +212,7 @@ func formatMapKey(v reflect.Value) string { var opts formatOptions opts.TypeMode = elideType opts.ShallowPointers = true - s := opts.FormatValue(v, visitedPointers{}).String() + s := opts.FormatValue(v, false, visitedPointers{}).String() return strings.TrimSpace(s) } diff --git a/cmp/report_slices.go b/cmp/report_slices.go index eafcf2e..6f0847e 100644 --- a/cmp/report_slices.go +++ b/cmp/report_slices.go @@ -172,7 +172,9 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { switch t.Elem().Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: ss = append(ss, fmt.Sprint(v.Index(i).Int())) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + ss = append(ss, fmt.Sprint(v.Index(i).Uint())) + case reflect.Uint8, reflect.Uintptr: ss = append(ss, formatHex(v.Index(i).Uint())) case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: ss = append(ss, fmt.Sprint(v.Index(i).Interface())) diff --git a/cmp/testdata/diffs b/cmp/testdata/diffs index 5471f81..533edf6 100644 --- a/cmp/testdata/diffs +++ b/cmp/testdata/diffs @@ -54,8 +54,8 @@ ... // 4 identical fields Size: 1, ModTime: s"2009-11-10 23:00:00 +0000 UTC", -- Typeflag: 0x30, -+ Typeflag: 0x00, +- Typeflag: 48, ++ Typeflag: 0, Linkname: "", Uname: "user", ... // 6 identical fields @@ -64,8 +64,8 @@ ... // 4 identical fields Size: 2, ModTime: s"2009-11-11 00:00:00 +0000 UTC", -- Typeflag: 0x30, -+ Typeflag: 0x00, +- Typeflag: 48, ++ Typeflag: 0, Linkname: "", Uname: "user", ... // 6 identical fields @@ -74,8 +74,8 @@ ... // 4 identical fields Size: 4, ModTime: s"2009-11-11 01:00:00 +0000 UTC", -- Typeflag: 0x30, -+ Typeflag: 0x00, +- Typeflag: 48, ++ Typeflag: 0, Linkname: "", Uname: "user", ... // 6 identical fields @@ -84,8 +84,8 @@ ... // 4 identical fields Size: 8, ModTime: s"2009-11-11 02:00:00 +0000 UTC", -- Typeflag: 0x30, -+ Typeflag: 0x00, +- Typeflag: 48, ++ Typeflag: 0, Linkname: "", Uname: "user", ... // 6 identical fields @@ -94,8 +94,8 @@ ... // 4 identical fields Size: 16, ModTime: s"2009-11-11 03:00:00 +0000 UTC", -- Typeflag: 0x30, -+ Typeflag: 0x00, +- Typeflag: 48, ++ Typeflag: 0, Linkname: "", Uname: "user", ... // 6 identical fields @@ -188,8 +188,8 @@ >>> TestDiff/Comparer#46 <<< TestDiff/Transformer uint8(Inverse(λ, uint16(Inverse(λ, uint32(Inverse(λ, uint64( -- 0x00, -+ 0x01, +- 0, ++ 1, ))))))) >>> TestDiff/Transformer <<< TestDiff/Transformer#02 @@ -323,8 +323,8 @@ + -9, -8, -7, }, UintsA: []uint16{ -- 0x03e8, 0x07d0, 0x0bb8, -+ 0x0bb8, 0x07d0, 0x03e8, +- 1000, 2000, 3000, ++ 3000, 2000, 1000, }, UintsB: []cmp_test.MyUint{ - 4000, 5000, 6000, @@ -1029,7 +1029,7 @@ Slaps: []teststructs.Slap{ { ... // 6 identical fields - Homeland: 0x00, + Homeland: 0, FunnyPrank: "", Immutable: &teststructs.SlapImmutable{ ID: "immutableSlap", @@ -1130,7 +1130,7 @@ <<< TestDiff/Project4#03 teststructs.Cartel{ Headquarter: teststructs.Headquarter{ - id: 0x05, + id: 5, location: "moon", subDivisions: []string{ - "alpha",