This doesn't seem to work...: ```inline fun <re...
# strikt
d
This doesn't seem to work...:
Copy code
inline fun <reified R> Assertion.Builder<Iterable<*>>.filterIsInstance(): DescribeableBuilder<List<R>> =
		get { filterIsInstance<R>() }
?
@robfletcher Any suggestions on how this could work? My test code is currently littered with replacements...
If I could get that working I could also avoid the single after it by making a
filterSingleInstance
after it... but then I don't know how to add the
single
assertion with reporting...
r
Will take a look shortly. Sitting in line at the DMV right now
d
Thanks!
I like the lib alot, but there's still quite a few assertions that could be added... and techniques for making certain types of assertions and filters could be added to the docs 🙂... Like I said, if I figure things out, I wouldn't mind PRing what I make, if you want.
r
Oh for sure. It’s only 6 months old!
That would be awesome. PRs and issues are very welcome.
I’m at work now. Will go over some of the Slack backlog at lunchtime
d
For 6 months, I think its better than most of what I've seen so far 😉!
r
Thanks
d
I tried again today... I really don't know what could be wrong with this... any ideas @robfletcher?
Sorry for bothering you, you're probably very busy...
r
I think without the generic type for the sub-type of
Iterable
that the other similar mapping functions have the compiler can’t find it unless you explicitly declare the subject to be
Iterable<*>
Not sure how to resolve that while retaining the reified parameter, otherwise you have to specify all of the types
d
Funny that in stdlib:
Copy code
public inline fun <reified R> Iterable<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> {
    return filterIsInstanceTo(ArrayList<R>())
}
Does it work there because of NoInfer? I'm not great at generics 🙃
r
It’s because there genuinely is only one generic type
I don’t know what that NoInfer thing is tbh
If you declare your subject specifically to be
Iterable<*>
I think your function works but that’s the only way it will work
d
Meaning
assertThat(result as Iterable<*>).filterIsInstance<List<Foo>>()
?
r
right
I can make it work like this:
Copy code
fun <T : Iterable<E>, E, R> Builder<T>.filterIsInstance(type: Class<R>): Builder<List<R>> =
  get { filterIsInstance(type) }
Giving
Copy code
val subject = listOf(1, 2L, 3.0, 4)
    expectThat(subject)
      .filterIsInstance(Int::class.java)
      .containsExactly(1, 4)
but that’s not as nice syntactically
d
And not have an extension function over that to provide the Class?
Maybe both together could do the trick 🙂
r
but it would have to provide
T
and
E
as well
Then it ends up looking like
Copy code
expectThat(subject as List<Number>)
      .filterIsInstance<List<Number>, Number, Int>()
      .containsExactly(1, 4)
which is even worse
d
That could be done with the reified with only two... but not nice either...
r
oh wait, I might have figured it out
crazy. I have the inline reified version working now but not the Java-y one
but the former calls the latter
there’s some boxing shenanigoats going on because I’m using
Int::class.java
I think
Copy code
inline fun <reified R> Builder<out Iterable<*>>.filterIsInstance(): Builder<List<R>>
seems to be the magic declaration.
Note the
out
type bound
d
Oh, I thought about that one, I just forgot that it could be specified on the receiver 👍🏼. That opens a few doors for assertions and filters on homogeneous collections... 🎉
Thanks!
r
cool. I’ll do some more poking later and get this added (along with a general
filter
method) and cut a release. Gotta get some work done now though!
💯 1
Hope that gets some stuff unblocked for you. (Are you in SA? Judging by time zone.)
d
It certainly does 😉. Running a bit late here now in Israel...
r
ah, that’s where you are. I was thinking South Africa.
have a good night
d
have a nice day!