smarter diff for maps
diff --git a/diff.go b/diff.go
index fdcd1eb..645f4e2 100644
--- a/diff.go
+++ b/diff.go
@@ -86,21 +86,63 @@
for i := 0; i < av.NumField(); i++ {
w.relabel(at.Field(i).Name).diff(av.Field(i), bv.Field(i))
}
+ case reflect.Map:
+ ak, both, bk := keyDiff(av.MapKeys(), bv.MapKeys())
+ for _, k := range ak {
+ w := w.relabel(fmt.Sprintf("[%q]", k.String()))
+ w.printf("%q != (missing)", av.MapIndex(k))
+ }
+ for _, k := range both {
+ w := w.relabel(fmt.Sprintf("[%q]", k.String()))
+ w.diff(av.MapIndex(k), bv.MapIndex(k))
+ }
+ for _, k := range bk {
+ w := w.relabel(fmt.Sprintf("[%q]", k.String()))
+ w.printf("(missing) != %q", bv.MapIndex(k))
+ }
case reflect.Interface:
w.diff(reflect.ValueOf(av.Interface()), reflect.ValueOf(bv.Interface()))
default:
if !reflect.DeepEqual(av.Interface(), bv.Interface()) {
- w.printf("%#v != %#v", av.Interface(), bv.Interface())
+ w.printf("%# v != %# v", Formatter(av.Interface()), Formatter(bv.Interface()))
}
}
}
func (d diffWriter) relabel(name string) (d1 diffWriter) {
d1 = d
- if d.l != "" {
- d1.l = d.l + "." + name
- } else {
- d1.l = name
+ if d.l != "" && name[0] != '[' {
+ d1.l += "."
}
+ d1.l += name
return d1
}
+
+func keyDiff(a, b []reflect.Value) (ak, both, bk []reflect.Value) {
+ for _, av := range a {
+ inBoth := false
+ for _, bv := range b {
+ if reflect.DeepEqual(av.Interface(), bv.Interface()) {
+ inBoth = true
+ both = append(both, av)
+ break
+ }
+ }
+ if !inBoth {
+ ak = append(ak, av)
+ }
+ }
+ for _, bv := range b {
+ inBoth := false
+ for _, av := range a {
+ if reflect.DeepEqual(av.Interface(), bv.Interface()) {
+ inBoth = true
+ break
+ }
+ }
+ if !inBoth {
+ bk = append(bk, bv)
+ }
+ }
+ return
+}