willowtreeapps / assertk

assertions for kotlin inspired by assertj

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

  1. 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.
  2. Could we add new contains*() variants with the input as a List/Iterable? My implementation matches the naming pattern used by Google Truth, namely adding ElementsOf 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.