go-sdk icon indicating copy to clipboard operation
go-sdk copied to clipboard

[assert] Function doesn't compare equal to itself

Open dhermes opened this issue 6 years ago • 2 comments

What happened:

Function doesn't compare equal to itself.

What you expected to happen:

it := assert.New(t)
it.Equal(f, f)
it.ReferenceEqual(f, f)

to pass. (What's worse, it.ReferenceEqual() panics)

How to reproduce it (as minimally and precisely as possible):

See: https://play.golang.org/p/FksPb7SsO6o

package main

import (
	"fmt"
	"net/http"
	"reflect"
)

func areEqual(expected, actual interface{}) bool {
	if expected == nil && actual == nil {
		return true
	}
	if (expected == nil && actual != nil) || (expected != nil && actual == nil) {
		return false
	}

	actualType := reflect.TypeOf(actual)
	if actualType == nil {
		return false
	}
	expectedValue := reflect.ValueOf(expected)
	if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
		return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
	}

	return reflect.DeepEqual(expected, actual)
}

func areReferenceEqual(expected, actual interface{}) bool {
	if expected == nil && actual == nil {
		return true
	}
	if (expected == nil && actual != nil) || (expected != nil && actual == nil) {
		return false
	}

	return expected == actual
}

func main() {
	tr := func(req *http.Request) error {
		return nil
	}
	fmt.Println(areEqual(tr, tr))
	fmt.Println(areReferenceEqual(tr, tr))
}

Environment:

  • go-sdk version: master at 72508cad6c40fefeab0bdaf14274ff7b0a016810
  • go version (e.g go version): go version go1.13 darwin/amd64
  • OS (e.g: cat /etc/os-release): macOS

dhermes avatar Jan 17 '20 19:01 dhermes

Surprisingly reflect.DeepEqual also says nope, but you can directly compare (H/T) value pointers:

reflect.DeepEqual(f, f) // false
reflect.ValueOf(f).Pointer() == reflect.ValueOf(f).Pointer() // true

dhermes avatar Jan 17 '20 19:01 dhermes

We may want to close this as "working as intended". The reason f == f panics at runtime is because Go explicitly doesn't want to worry about comparing enclosed scope when comparing functions for equality (did some reading).

dhermes avatar Jan 17 '20 19:01 dhermes