Skip to content

Extend assert.Same to support pointer-like objects #1777

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Michael0x2a
Copy link

Summary

Modify assert.Same and assert.NotSame to support comparing maps and channels by pointer equality.

Changes

  1. Rename samePointers to sameReferences and generalize it so it will try comparing objects that are represented using a single pointer/reference, as opposed to comparing only literal pointers. We maintain the invariant that the two args must have the same Kind and Type.
  2. Rename Test_samePointers to Test_sameReferences
  3. Add test cases to Test_sameReferences, TestSame, and TestNotSame.

Motivation

Today, assert.Same and assert.NotSame support comparing only literal pointers. This PR generalizes both functions so they also support comparing maps and channels by type and pointer equality.

Why these two types? Because the Go language reference states:

  • A pointer value is a reference to the variable holding the pointer base type value.
  • A map or channel value is a reference to the implementation-specific data structure of the map or channel.

That is, all three types are represented by a single reference to some underlying value.

Given this, my belief is it would minimize surprise for users if we handle all three cases in the same way in Same/NotSame: we compare the objects by pointer equality, regardless if the underlying value is a user-defined object vs some implementation-specific data structure.

By this logic, I decided against modifying Same/NotSame to support comparing things like slices, which are not represented via a single reference.

Related issues

There is a related discussion #1732, where (iiuc) the claim was made that we should not support Same/NotSame for maps because we cannot compare map keys and values for sameness in all cases.

However, I found this a somewhat surprising argument: if Same is given a pointer to some user-defined struct, it currently does not attempt to introspect and compare the contents of that struct. So, I don't see why it's necessary or expected to do the same for maps.

Hence, this PR.

Today, assert.Same and assert.NotSame support comparing only literal
pointers. This PR generalizes both functions so they also support
comparing maps and channels by type and pointer equality.

Why these two types? Because the [Go language reference][0] states:

> A map or channel value is a reference to the implementation-specific
> data structure of the map or channel.

That is, it states maps and channels are de-facto pointers.

So, my belief is that it would minimize surprise if we allow Same/NotSame
to compare any two values that consist of just a reference to some
underlying value, regardless if that underlying value is a user-defined
object vs some implementation-specific data structure.

By this logic, I decided against modifying Same/NotSame to support
comparing things like slices, which are not represented via a
single reference.

  [0]: https://go.dev/ref/spec#Representation_of_values
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant