Open ernesto-jimenez opened 8 years ago
/cc @TechnotronicOz
This also happens in a worse case, when comparing a "enum" variable to a literal constant of that enum, as follow:
type MyEnum int
const (
_ MyEnum = iota
Enum1 = iota
Enum2 = iota
)
func TestIt(t *testing.T) {
a := Enum1
assert.Equal(t, a, Enum1, "Enum1 = Enum1")
}
This code fails saying that Enum1 != Enum1
. Seems like Go takes that typed constant and flattens its type to int and thus reflect.DeepEqual
fails.
@greenboxal, that test does pass properly. What version of testify are you using?
=== RUN TestIt
--- PASS: TestIt (0.00s)
PASS
We should determine whether or not this is still the case and investigate accordingly.
Using v1.4.0, I can replicate the error this way.
type MyEnum int
const (
Enum1 MyEnum = 1
Enum2 = 2
)
func TestIt(t *testing.T) {
assert := assert.New(t)
var a MyEnum = Enum2
assert.True(a == Enum2)
assert.EqualValues(Enum2, a)
assert.Equal(Enum2, a)
}
The assert.True passes, assert.EqualValues passes, but the assert.Equal calls fails. If you change the enum definition to
type MyEnum int
const (
Enum1 MyEnum = 1
Enum2 MyEnum = 2
)
Equal doesn't have a problem.
@zach-skysafe That is because the following code
package main
import (
"fmt"
"reflect"
)
type MyEnum int
const (
Enum1 MyEnum = 1
Enum2 = 2
)
func main() {
fmt.Println(reflect.TypeOf(Enum1).Name())
fmt.Println(reflect.TypeOf(Enum2).Name())
}
Outputs the following:
MyEnum
int
The correct way to specify the enum would be to do:
type MyEnum int
const (
Enum1 MyEnum = iota
Enum2
)
Replace with
type MyEnum string
const (
Enum1 MyEnum = "first"
Enum2 = "second"
)
And you'll see the same error. I'm just providing an example case of when Equal and EqualValues don't match. Seeing as the builtin == also passes, I would expect Equal to pass as well.
I can understand the argument either way in this case. IMHO, this is dealing with a weakness in golang itself. So coding around that is probably not going to satisfy everyone.
Another way to look at the question of Equal vs EqualValue; if there are two different functions, I would expect them to have a difference. If they both evaluate with the same logic, why have 2 functions? I also just saw now that there is an Exactly function, which appears to work the same as Equals in all the test cases in this thread.
I think that Equal
here shouldn't pass since they are not the same type (string
vs MyEnum
). And that is why there is the EqualValue
function.
Another way to look at the question of Equal vs EqualValue; if there are two different functions, I would expect them to have a difference. If they both evaluate with the same logic, why have 2 functions? I also just saw now that there is an Exactly function, which appears to work the same as Equals in all the test cases in this thread.
Exactly, they don't evaluate to the same logic since Equal
requires that the types are the same.
I would understand Exactly
not passing, since it specifies "Exactly asserts that two objects are equal in value and type."
Equal
is just commented "Equal asserts that two objects are equal", which is ambiguous. Is it intended to be similar to Exactly
, or are there distinctions for other cases?
Can anyone clarify the difference between Exactly
and Equal
?
Right now there are some cases where
Equals
fails whereEqualValues
passes. e.g: comparingassert.Equal(t, uint32(5), 5)
However,
Equal
is a broader term and seems to imply that it would includeEqualValues
.I want to consider making
Equal
pass whenEqualValues
passes too.Main thing to research is whether there's any case where that behaviour would translate in an
Equal
assertion passing when it should be failing.