Improve API for List/Iterable assertions
dzirbel opened this issue · comments
I find it very useful to use assertions like containsExactly()
by providing a List
whose elements should match rather than vararg list of elements. This can be particularly helpful for more complicated tests that construct their reference elements rather than having them pre-defined.
Moreover, I've found the API of containsExactly()
to be somewhat error prone, in particular since it is defined on List<*>
with elements as Any?
it is possible to make assertions which make no "type-sense", for example
assertThat(listOf(1, 2, 3)).containsExactly("1", "2", "3")
I think (but may not have considered all the edge cases where parameterization might be ambiguous) that it would be possible to redefine this family of methods along the line of
fun <T> Assert<List<T>>.containsExactly(vararg elements: T)
This was particularly difficult when trying to override containsExactly
with an extension method to solve the first problem; namely something like
fun <T> Assert<List<T>>.containsExactly(elements: List<T>)
since the vararg Any?
parameters of the default method also match this signature.
So, I have two questions:
- Could we make the existing
contains*()
methods more typesafe by parameterization? If it's not possible for parametrization to cover all cases, perhaps we could consider a typesafe variant and one matching the current signature, or something along those lines. - Could we add new
contains*()
variants with the input as aList/Iterable
? My implementation matches the naming pattern used by Google Truth, namely addingElementsOf
to these variants to disambiguate them, but there are a number of ways to do it.
I also wish these methods supported element-wise matching. I work a lot with lists and arrays of floating point numbers, and we're always told not to use exact equality matching for floating point numbers.
AssertJ for example has satisfiesExactly
where you pass a list of conditions for each element.