Not sure what to do about this, but we’ve used ass...
# strikt
e
Not sure what to do about this, but we’ve used assertions like this:
Copy code
get { value }.isA<List<FooBar>>()
But
isA
doesn’t (and can’t, I think until Valhalla give us reified generics natively in Java?) check the type of the entries of the
List
that they are all an instance of
FooBar
. So this will also pass:
Copy code
get { value }.isA<List<LiterallyAnyClassYouWant>>()
Something like this will do that:
Copy code
@Suppress("UNCHECKED_CAST")
inline fun <reified T> Assertion.Builder<*>.isCollectionOf(): Assertion.Builder<Collection<T>> =
    assert("is a collection of %s", T::class.java) {
        val collection = it as? Collection<*>
        val wronglyTypedEntries = collection?.mapIndexedNotNull { index, entry ->
            when (entry) {
                is T -> null
                null -> "null @ index $index"
                else -> "${entry::class} @ index $index"
            }
        } ?: emptyList()
        when {
            it == null -> fail(actual = null)
            collection == null -> fail(actual = it::class.java)
            wronglyTypedEntries.isEmpty() -> pass()
            else -> fail(actual = wronglyTypedEntries)
        }
    } as Assertion.Builder<Collection<T>>

val numbers = listOf(1, 2f)
expectThat(numbers).isA<List<*>>() // passes
expectThat(numbers).isA<List<Any>>() // passes
expectThat(numbers).isA<List<String>>() // passes!!!
expectThat(numbers).isCollectionOf<Number>() // passes
expectThat(numbers).isCollectionOf<Int>() // fails with:
// ▼ Expect that [1, 2.0]:
//  ✗ is a collection of java.lang.Integer
//                 found ["class kotlin.Float @ index 1"]
but devs still need to know to avoid using
isA
on
Collections
.