Open rickb777 opened 2 months ago
Thank you for your kind words and your detailed analysis.
I will look into each of your points and make the appropriate changes/issues as required. Go is not my native language, so I appreciate the guidance.
Feel free, however, to open your own prs as you feel fit in the meantime!
Hi, Again, thanks for your thorough analysis of the lib. I've put together some responses to each numbered point:
equals
method does not seem to be the standard interface for comparison, I'm not sure about making a specific is.EqualTo
method for something like this part of the lib though.BaseDescription
tries to understand the type being asserted in order to build the message, something that GoCrest could do, but it seemed a waste of effort given that the idea is just to isolate the actual output from the rest of the message.Again, thank you for all the detailed input. Very much appreciated!
Firstly, I like the API. What you're trying to achieve and the way you've applied generics is very commendable.
It got me interested in delving deeper into the implementation. I came up with a few issues, which I'm going to list here rather than making a Github Issue for each. (We could do that later. Maybe PRs too.)
I don't want this to be too picky but it's hopefully going to help make Gocrest better for everyone. So in no particular order:
1. Containment semantics - especially is/contains.go
func listContains
func listContains
doesn't implement what the documentation says. Maybe the documentation is wrong. The function checks whether all elements are present in theactual
list, regardless of order. There need to be functions to cover both the unordered and ordered cases.Note that
is.ArrayMatching
has the same documentation issue., Also, has/haseveryelement.gofunc EveryElement
is confused withis.ArrayMatching
.To make things as simple as possible for users, I suggest using the
is
package for ordered comparisons of arrays and slices; then using thehas
package for unordered containment assertions. This will mean changing the documentation in some places and implementation in others.For map assertions, the functions in the
is
package should verify all keys or values are present and no others are. Those in thehas
package should do a simpler subset test.2. is/equalto.go
func EqualTo
Google's developers have a cmp package. It's a really heavy to use but it highlights something missing from Gocrest: comparing value equality sometimes requires refinement. The obvious cases are when comparing floats given a margin of error, or when comparing types such as
time.Time
that provide aEqual
method. Gocrest doesn't provide for this yet.3. is/equalto.go
func EqualTo
Also related to the point above, the test error message printed for structs that have different values are unhelpfully terse. It would be good to indicate what part within the struct (or array, map, etc) was different. For comparison, see Juju testing/checkers/deepequal.go - but note the License is incompatible with BSD. It's not ideal to add an external dependency on that package and its API isn't great, so some fresh implementation along similar lines would be needed.
4. Angle brackets
Mostly, actual and expected values are rendered like
fmt.Sprintf("actual <%v>", actual)
, but this looks cluttered in practice. IMO, It would help the user if Gocrest switched tofmt.Sprintf("actual %+v", actual)
style throughout. This is in quite a lot of places but relatively easy to correct.5.
is.Nil()
is confusingThis is declared in is/nil.go. It caught me out as soon as I started using Gocrest. What it means is
is.NoError()
so it ought to be called that. Other irrelevant things can be nil, hence the confusion. The existence ofis.NilPtr()
is fine for the obvious pointer case.6. Redundant code
Just a few things I spotted: in is/nil.go, the assignments to the
match.Actual
field are all redundant - see then/assertthat.go which provides the default.