Skip to content

Commit

Permalink
Merge pull request #55 from go-test/cmp-func-issue-46
Browse files Browse the repository at this point in the history
Add CompareFunctions (issue 46)
  • Loading branch information
daniel-nichter committed Dec 8, 2022
2 parents 88c902f + d97d7b6 commit 47c10a1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
20 changes: 19 additions & 1 deletion deep.go
Expand Up @@ -32,6 +32,12 @@ var (
// fields cannot be called.
CompareUnexportedFields = false

// CompareFunctions compares functions the same as reflect.DeepEqual:
// only two nil functions are equal. Every other combination is not equal.
// This is disabled by default because previous versions of this package
// ignored functions. Enabling it can possibly report new diffs.
CompareFunctions = false

// NilSlicesAreEmpty causes a nil slice to be equal to an empty slice.
NilSlicesAreEmpty = false

Expand Down Expand Up @@ -392,7 +398,19 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
if a.String() != b.String() {
c.saveDiff(a.String(), b.String())
}

case reflect.Func:
if CompareFunctions {
if !a.IsNil() || !b.IsNil() {
aVal, bVal := "nil func", "nil func"
if !a.IsNil() {
aVal = "func"
}
if !b.IsNil() {
bVal = "func"
}
c.saveDiff(aVal, bVal)
}
}
default:
logError(ErrNotHandled)
}
Expand Down
62 changes: 60 additions & 2 deletions deep_test.go
Expand Up @@ -6,6 +6,7 @@ import (
"reflect"
"testing"
"time"
"unsafe"

"github.com/go-test/deep"
v1 "github.com/go-test/deep/test/v1"
Expand Down Expand Up @@ -311,8 +312,14 @@ func TestMaxDiff(t *testing.T) {
}

func TestNotHandled(t *testing.T) {
a := func(int) {}
b := func(int) {}
// UnsafePointer is pretty much the only kind not handled now
v := []int{1}
a := unsafe.Pointer(&v)
b := unsafe.Pointer(&v)
// UnsafePointer added in Go 1.88. Use these lines once this pkg
// no longer supports Go 1.17.
//a := reflect.ValueOf(v).UnsafePointer()
//b := reflect.ValueOf(v).UnsafePointer()
diff := deep.Equal(a, b)
if len(diff) > 0 {
t.Error("got diffs:", diff)
Expand Down Expand Up @@ -1437,3 +1444,54 @@ func TestNil(t *testing.T) {
t.Error("Nil value to comparison should not be equal")
}
}

var testFunc = func() {}

func TestFunc(t *testing.T) {
// https://github.com/go-test/deep/issues/46
type TestStruct struct {
Function func()
}
t1 := TestStruct{
Function: testFunc,
}
t2 := TestStruct{
Function: testFunc,
}

// CompareFunctions is off by default, so this should report no diff:
diff := deep.Equal(t1, t2)
if len(diff) != 0 {
t.Fatalf("expected 0 diff when CompareFunctions=false, got %d: %s", len(diff), diff)
}

deep.CompareFunctions = true
defer func() { deep.CompareFunctions = false }()

// Two funcs are not equal (even if they're the same func)
diff = deep.Equal(t1, t2)
if len(diff) != 1 {
t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
}
if diff[0] != "Function: func != func" {
t.Errorf("got '%s', expected 'Function: func != func'", diff[0])
}

// One func nil, the other set: not equal
t1.Function = nil
diff = deep.Equal(t1, t2)
if len(diff) != 1 {
t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
}
if diff[0] != "Function: nil func != func" {
t.Errorf("got '%s', expected 'Function: nil func != func'", diff[0])
}

// Two nil funcs are equal
t1.Function = nil
t2.Function = nil
diff = deep.Equal(t1, t2)
if len(diff) != 0 {
t.Errorf("expected 0 diff, got %d: %s", len(diff), diff)
}
}
3 changes: 3 additions & 0 deletions test/coverage
@@ -0,0 +1,3 @@
#!/bin/sh
go test -coverprofile=coverage.out "$@"
go tool cover -html=coverage.out

0 comments on commit 47c10a1

Please sign in to comment.