smartystreets / goconvey

Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go.
http://smartystreets.github.io/goconvey/
Other
8.23k stars 554 forks source link

Ignore slice order in ShouldResemble, something like assert. ElementsMatch #652

Closed LebronKodan closed 2 years ago

LebronKodan commented 2 years ago

In some scenarios, we need a function like ShouldElementsMatch to compare two slices without order, e.g.

a := []int{1, 2, 3}
b := []int{3, 2, 1}
So(a, ShouldElementsMatch, b)  // true

testify has ElementsMatch, does goconvey provide something like this?

riannucci commented 2 years ago

You'd have to ask this over in https://github.com/smartystreets/assertions, as that's the assertions library that convey uses.

However, I think the simpler approach might be to: 1) Use a map[int]struct{} to store sets of integers. Maps are not order-preserving, and so ShouldResemble will show them as equal. Plus, set-membership operations (like union, or "contains") will be faster :). 2) If you really want them to be unordered slices, just wrap them using the stdlib sort.IntSlice type: sort.IntSlice(a).Sort(). After that a would be sorted (and do the same for b). Then ShouldResemble will be able to compare them as equal.

The core implementation of ElementsMatch looks like it could be a fairly expensive O(NM), so it wouldn't be a good idea for large lists. If I understand what they're doing there, I think there's actually an O(max(N,M)log N) implementation though.