-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Fix compairsion of struct containing time.Time. #985
Conversation
I have a workaround here, but it only works with "struct containing time.Time", not with "struct containing struct containing time.Time". func ObjectsAreEqual(expected, actual interface{}) bool {
if expected == nil || actual == nil {
return expected == actual
}
switch expected.(type) {
case time.Time:
if tAct, ok := actual.(time.Time); ok {
return expected.(time.Time).Equal(tAct)
}
return false
case []byte:
if act, ok := actual.([]byte); ok {
exp := expected.([]byte)
if exp == nil || act == nil {
return exp == nil && act == nil
}
return bytes.Equal(exp, act)
}
return false
}
v1 := reflect.ValueOf(expected)
v2 := reflect.ValueOf(actual)
if v1.Kind() == reflect.Struct {
if !v1.IsValid() || !v2.IsValid() {
return v1.IsValid() == v2.IsValid()
}
if v1.Type() != v2.Type() {
return false
}
// Cause we won't call ObjectsAreEqual again
// So params like the "visited" param of reflect.deepValueEqual is not required.
for i, n := 0, v1.NumField(); i < n; i++ {
timeV1, ok1 := v1.Field(i).Interface().(time.Time)
timeV2, ok2 := v2.Field(i).Interface().(time.Time)
if ok1 && ok2 {
if !timeV1.Equal(timeV2) {
return false
}
} else {
if !reflect.DeepEqual(v1.Field(i).Interface(), v2.Field(i).Interface()) {
return false
}
}
}
return true
}
return reflect.DeepEqual(expected, actual)
} If we call |
I see. I'll revert the merged commit then to give us more room to work out a better approach. |
It occurs to me that the building the |
I've reverted the previous merge. No rush, feel free to scope out a better solution should you wish :) |
fdbb115
to
93d98ee
Compare
@boyan-soubachov Added a workaround to deal with non-recursive types. I think we can do nothing about recursive types, cause we can't look into the unexported field of reflect.Value. Something weird is that when I'm running Also, is it normal for the tests of the "suite" package kept failing? |
And......
Update: running all tests from |
a506bdc
to
90f9249
Compare
@boyan-soubachov ready for review. |
90f9249
to
dbfc7ee
Compare
Hmm. I'm not sure the complexity and safety (the use of Thank you for your time and effort but I think it's best we hold off on this. Thoughts? |
The unsafe pointers are only used to prevent dead-recurse. I'm using it exactly the same way which
For most cases(and in my case), support for "struct containing time.Time" is fairly enough. So, maybe this fix is acceptable? |
For the same reasons in #1536 we cannot deviate from reflect.DeepEqual on time.Time objects in v1. |
Summary
#979 fixed comparison of
time.Time
, but struct containingtime.Time
still can't be compared correctly because still, we will usereflect.DeepEqual
.This PR is trying to fix it.
Related issues
Closes #984