go-cmp icon indicating copy to clipboard operation
go-cmp copied to clipboard

add examples for AllowUnexported and IgnoreUnexported

Open kevinburke opened this issue 5 years ago • 8 comments

Reading the docs and attempting simple implementations, I'm still not sure how to use these, since I keep getting panics. I'm going to search Github to see people using these successfully to figure out what I am missing.

kevinburke avatar Mar 04 '19 06:03 kevinburke

Hey there ! any update on this one ? I'm actually interested too ! :p

maeglindeveloper avatar Jun 10 '19 09:06 maeglindeveloper

Feel free to mail out a PR fixing this.

dsnet avatar Jun 10 '19 17:06 dsnet

Basic usage of them seems simple enough, for example:

func (e Example) Equals(e2 Example) bool {
	return cmp.Equal(e, e2, cmp.AllowUnexported(Example{}))
}

But even a bit more advanced seems a little odd to me. For example, using AllowUnexported together with IgnoreFields. It still gives a name must be exported panic for the IgnoreFields option when I try to ignore an unexported field.

Some examples for this would be nice.

SamuilDichev avatar Jul 08 '19 14:07 SamuilDichev

IgnoreOptions also makes a confusing statement to the effect of "never use this for types you don't control" because of some hand-wavy statement about implementation details changing in the future.

Perhaps a controversial view: IgnoreUnexported should be the default for all types. You cannot check unexported fields anyway, and even if you could, doing so in test would violate the basic tenet of Go readability, which is to test public behavior.

the80srobot avatar Dec 18 '20 08:12 the80srobot

I think it may be reasonable for IgnoreUnexported to be the default behaviour only if there is a way to signal to the user that unexported fields are not checked.

When I first used cmp.Diff in replacement of reflect.DeepEqual, it didn't occur to me that unexported fields will not be checked until the tests panic-ed. If, hypothetically, IgnoreUnexported was set as the default, I would have taken the passing tests as indication that the swap was successful even though the new tests will not cover changes in unexported fields.

Additionally, I think the current behaviour provides an explicit visual indication to other readers that this comparison ignores unexported fields.

if diff := cmp.Diff(a, b, cmpopts.IgnoreUnexported(SomeStruct{})); diff != "" {
	t.Errorf("mismatch (-got +want):\n%s", diff)
}

I know that this behaviour is already documented in the package documentation but, perhaps, what may be helpful (especially to new users) are more examples on the usage of these options.

loozhengyuan avatar Dec 18 '20 15:12 loozhengyuan

Is there any way to IgnoreUnexported when comparing slices of a specific struct?

droslean avatar Mar 03 '21 13:03 droslean

Can you give an example?

dsnet avatar Mar 03 '21 17:03 dsnet

it's not easy to understand in my first impression eg. GetIssueAdvancedReply_Data is member of GetIssueAdvancedReply, GetIssueAdvancedReply_Data contains some unexported fields. if want to ingore it, it seems should be:

cmp.Equal(tt.want, tt.args.rsp, cmpopts.IgnoreUnexported(pb.GetIssueAdvancedReply{}, pb.GetIssueAdvancedReply_Data{})

hope help

ochapman avatar Jan 13 '22 13:01 ochapman