Revisiting `is.Equal` and the role of `reflect.DeepEqual`
- Dominant language
- Go
- Stars
- 2k
- Forks
- 67
- PR merge metrics
- No merged PRs in 30d
Description
I started switching from [`google/go-cmp`](https://github.com/google/go-cmp) to `is` in pursuit of the latter's more pleasant and succinct syntax, but unfortunately have run into issues with how times are compared by `is`.
In the code being tested, a time is created using `time.Now()`, stored to a database, and then later retrieved. When comparing the two times (or the structs containing time values), `is.Equal` reports that the times are different because one has a monotonic counter and the other does not. This differs from how the standard library [`time.Equal()`](https://pkg.go.dev/time#Time.Equal) functions, which is recommend by the Go team instead of directly comparing time values.
For example, consider the following excerpt where `time1` has a monotonic counter, and `time2` is the same time without a monotonic counter:
```go
time1 := time.Now()
time2 := time1.Round(0) // returns time1 stripped of any monotonic clock reading but otherwise unchanged (see https://pkg.go.dev/time#Time.Round)
fmt.Printf("time1.Equal(time2) = %v\n", time1.Equal(time2))
is.Equal(time1, time2)
```
which results in the following:
```
time1.Equal(time2) = true
test.go:25: 2023-03-10 19:18:46.3692787 -0500 EST m=+0.083328801 != 2023-03-10 19:18:46.3692787 -0500 EST
```
Is there a better way to handle these comparisons in `is`? Some options I can imagine include:
1. Switch to using [`time.Equal()`](https://pkg.go.dev/time#Time.Equal) if the values being compared are times.
2. Adopting a model similar to [`google/go-cmp`](https://github.com/google/go-cmp#package-for-equality-of-go-values) where all "Types that have an Equal method may use that method to determine equality".
3. Use the tried-and-true [`google/go-cmp`](https://github.com/google/go-cmp) library itself to perform underlying equality comparisons.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the is.Equal entry point and reproduce the time.Now()/Round(0) example from the issue. Compare the observed behavior with time.Equal and review the proposed equality approaches. Done means the chosen behavior is clearly specified and covered by tests for times and structs containing time values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100