matryer / matryer/is

Revisiting `is.Equal` and the role of `reflect.DeepEqual`

Open
#53 11 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.