-
Notifications
You must be signed in to change notification settings - Fork 7
Description
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 the actual 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.go func EveryElement is confused with is.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 the has 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 the has 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 a Equal 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 to fmt.Sprintf("actual %+v", actual) style throughout. This is in quite a lot of places but relatively easy to correct.
5. is.Nil() is confusing
This 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 of is.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.