diff --git a/deepequal.go b/deepequal.go index bbe3c68..6d76db2 100644 --- a/deepequal.go +++ b/deepequal.go @@ -6,6 +6,7 @@ package teq import ( "bytes" + "fmt" "reflect" "unsafe" ) @@ -85,11 +86,12 @@ type next func(v1, v2 reflect.Value) bool var eqs = map[reflect.Kind]func(v1, v2 reflect.Value, nx next) bool{ reflect.Array: arrayEq, reflect.Slice: sliceEq, + reflect.Chan: todo, reflect.Interface: interfaceEq, reflect.Pointer: pointerEq, reflect.Struct: structEq, reflect.Map: mapEq, - reflect.Func: todo, + reflect.Func: funcEq, reflect.Int: intEq, reflect.Int8: intEq, reflect.Int16: intEq, @@ -118,7 +120,7 @@ func hard(k reflect.Kind) bool { } func todo(v1, v2 reflect.Value, nx next) bool { - panic("not implemented") + panic(fmt.Sprintf("not implemented (%s, %s)", v1.Type(), v1.Kind())) } func arrayEq(v1, v2 reflect.Value, nx next) bool { @@ -195,6 +197,14 @@ func mapEq(v1, v2 reflect.Value, nx next) bool { return true } +func funcEq(v1, v2 reflect.Value, _ next) bool { + if v1.IsNil() && v2.IsNil() { + return true + } + // Can't do better than this: + return false +} + func intEq(v1, v2 reflect.Value, _ next) bool { return v1.Int() == v2.Int() } func uintEq(v1, v2 reflect.Value, _ next) bool { return v1.Uint() == v2.Uint() } func stringEq(v1, v2 reflect.Value, _ next) bool { return v1.String() == v2.String() } diff --git a/format.go b/format.go index 7e9ed38..3b77a9b 100644 --- a/format.go +++ b/format.go @@ -102,11 +102,11 @@ func (teq Teq) format(v reflect.Value, depth int) lines { var fmts = map[reflect.Kind]func(reflect.Value, func(reflect.Value) lines) lines{ reflect.Array: arrayFmt, reflect.Slice: sliceFmt, - reflect.Interface: todoFmt, + reflect.Interface: interfaceFmt, reflect.Pointer: pointerFmt, reflect.Struct: structFmt, reflect.Map: mapFmt, - reflect.Func: todoFmt, + reflect.Func: funcFmt, reflect.Int: intFmt, reflect.Int8: intFmt, reflect.Int16: intFmt, @@ -163,6 +163,15 @@ func sliceFmt(v reflect.Value, next func(reflect.Value) lines) lines { return result } +func interfaceFmt(v reflect.Value, next func(reflect.Value) lines) lines { + open := fmt.Sprintf("%s(", v.Type().String()) + close := ")" + if v.IsNil() { + return linesOf(open + "" + close) + } + return next(v.Elem()).ledBy(open).followedBy(close) +} + func pointerFmt(v reflect.Value, next func(reflect.Value) lines) lines { if v.IsNil() { return linesOf("") @@ -220,6 +229,10 @@ func mapFmt(v reflect.Value, next func(reflect.Value) lines) lines { return result } +func funcFmt(v reflect.Value, _ func(reflect.Value) lines) lines { + return linesOf(fmt.Sprintf("%s(%v)", v.Type(), v.Pointer())) +} + func intFmt(v reflect.Value, _ func(reflect.Value) lines) lines { return linesOf(fmt.Sprintf("%s(%d)", v.Type(), v.Int())) } diff --git a/teq_default_test.go b/teq_default_test.go index 662c2c7..4b5f885 100644 --- a/teq_default_test.go +++ b/teq_default_test.go @@ -1,7 +1,9 @@ package teq_test import ( + "bytes" "fmt" + "io" "testing" "github.com/seiyab/teq" @@ -27,6 +29,7 @@ func TestEqual(t *testing.T) { {"structs", structs()}, {"slices", slices()}, {"maps", maps()}, + {"interfaces", interfaces()}, {"recursions", recursions()}, } @@ -51,6 +54,7 @@ func TestEqual(t *testing.T) { if mt.errors[i] != e { t.Errorf("expected %q, got %q at i = %d", e, mt.errors[i], i) } + assert.Equal(t, e, mt.errors[i]) } } @@ -128,6 +132,20 @@ differences: - int(2), } `}, false}, + {io.Reader(bytes.NewBuffer([]byte("a"))), io.Reader(bytes.NewBuffer(nil)), []string{ + `not equal +differences: +--- expected ++++ actual +@@ -1,5 +1,3 @@ + *bytes.Buffer{ +- buf: []uint8{ +- uint8(97), +- }, ++ buf: []uint8{}, + off: int(0), +`, + }, false}, } } @@ -224,6 +242,46 @@ differences: } } +func interfaces() []test { + return []test{ + { + []io.Reader{io.Reader(bytes.NewBuffer([]byte("a")))}, + []io.Reader{io.Reader(bytes.NewBuffer([]byte("a")))}, + nil, + false, + }, + { + []io.Reader{ + bytes.NewBuffer([]byte("a")), + bytes.NewBuffer([]byte("b")), + }, + []io.Reader{nil}, + []string{`not equal +differences: +--- expected ++++ actual +@@ -1,16 +1,3 @@ + []io.Reader{ +- io.Reader(*bytes.Buffer{ +- buf: []uint8{ +- uint8(97), +- }, +- off: int(0), +- lastRead: bytes.readOp(0), +- }), +- io.Reader(*bytes.Buffer{ +- buf: []uint8{ +- uint8(98), +- }, +- off: int(0), +- lastRead: bytes.readOp(0), +- }), ++ io.Reader(), + } +`}, false}, + } +} + func recursions() []test { type privateRecursiveStruct struct { i int diff --git a/teq_diff_test.go b/teq_diff_test.go index cd1be42..086c253 100644 --- a/teq_diff_test.go +++ b/teq_diff_test.go @@ -89,7 +89,6 @@ differences: }) t.Run("pointer of struct", func(t *testing.T) { - t.Skip() mt := &mockT{} assert.Equal(mt, &http.Client{Timeout: time.Second}, http.DefaultClient) @@ -100,9 +99,10 @@ differences: differences: --- expected +++ actual -@@ -1 +1 @@ -- Timeout: time.Duration(0), -+ Timeout: 1s, +@@ -4,3 +4,3 @@ + Jar: http.CookieJar(), +- Timeout: time.Duration(1000000000), ++ Timeout: time.Duration(0), } ` if mt.errors[0] != expected {