Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[assert] Function doesn't compare equal to itself #167

Open
dhermes opened this issue Jan 17, 2020 · 2 comments
Open

[assert] Function doesn't compare equal to itself #167

dhermes opened this issue Jan 17, 2020 · 2 comments
Assignees
Labels
v2.x.y Version 2 series v3.x.y Version 3 series

Comments

@dhermes
Copy link
Contributor

dhermes commented Jan 17, 2020

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 72508ca
  • go version (e.g go version): go version go1.13 darwin/amd64
  • OS (e.g: cat /etc/os-release): macOS
@dhermes dhermes added v3.x.y Version 3 series v2.x.y Version 2 series labels Jan 17, 2020
@dhermes dhermes self-assigned this Jan 17, 2020
@dhermes
Copy link
Contributor Author

dhermes commented Jan 17, 2020

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
Copy link
Contributor Author

dhermes commented Jan 17, 2020

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v2.x.y Version 2 series v3.x.y Version 3 series
Projects
None yet
Development

No branches or pull requests

1 participant