androidkotlingenericsinheritance

How to assert if an object has an ancestor of another object in when clause?


So as the title suggests I need to check if an object is inherited from a given class.

I've written a function (code snippet below) which checks if an item is an instance of a given class, but I want to check if it is a descendant of the KView class, not a direct child (as in I want it to check it's ancestors until it find KView or reaches the root ancestor).

Is it possible in Kotlin and if it is, can I use it in a when clause?

when (item) {
    is KRecyclerView -> item.assertWithCondition { isVisibleAndEnabled() }
    is KView -> item.assertWithCondition { isVisibleAndEnabled() }
    else -> throw IllegalArgumentException("Item has wrong type")
}

Solution

  • this function actually works (posting full function just in case anybody else would need it), it's just that I checked if an item is inherited from a wrong ancestor, duh

    fun scrollForward(steps: Int = 30): Boolean = try {
            getUiScrollable().scrollForward(steps)
        } catch (e: UiObjectNotFoundException) {
            false
        }
    
    private fun conditionalAssertion(assert: () -> Unit) =
            try {
                assert()
                true
            } catch (e: Exception) {
                if (e is NullPointerException || e is NoMatchingViewException) {
                    false
                } else {
                    throw e
                }
            }
    
    fun <K : BaseAssertions> K.assertWithCondition(assertion: K.() -> Unit): Boolean =
            conditionalAssertion { assertion() }
    
    fun <T>RecyclerActions.scrollToFirstItemFromTop(item: T, shouldExist: Boolean = true) {
            run breaking@{
                repeat(3) {
                    ScreenScrollerHelper.scrollForward(100)
                    val isElementFound =
                        when (item) {
                            is KRecyclerView -> item.assertWithCondition { isVisibleAndEnabled() }
                            is KView -> item.assertWithCondition { isVisibleAndEnabled() }
                            is KDSLView<*> -> item.assertWithCondition { isVisibleAndEnabled() }
                            else -> throw IllegalArgumentException("Item has wrong type")
                        }
                    if (isElementFound || !shouldExist) {
                        return@breaking
                    }
                }
            }
        }