agoda-com / Kakao

This repo is no longer supported. Please visit a https://github.com/KakaoCup/Kakao
Apache License 2.0
1.11k stars 102 forks source link

Take a look at IndexMatcher fix. #199

Closed yapkolotilov closed 4 years ago

yapkolotilov commented 4 years ago

Hi, guys!

We found issue in your framework that IndexMatcher can't be used more than once. We use this reusable version in our company. Check it out and maybe put it in your library.

class IndexMatcher(private val matcher: Matcher<View>, private val index: Int) : TypeSafeMatcher<View>() {
    private var currentIndex = 0
    private val seen = mutableSetOf<View>()

    override fun describeTo(desc: Description) {
        desc.appendText("${index}th view with: ")
            .appendDescriptionOf(matcher)
    }

    public override fun matchesSafely(view: View): Boolean {
        if (seen.contains(view)) {
            currentIndex = 0
            seen.clear()
        }

        seen.add(view)
        return matcher.matches(view) && currentIndex++ == index
    }
}

With best regards,

Yaroslav.

Unlimity commented 4 years ago

Hi! Actually, it's not a bug, it's a design flaw :) But your solution looks like an interesting hack. What will happen if I, let's say change the screen, so the views will change, but I will reuse this matcher? Anyway, you're more than welcome to submit a PR 👍

yapkolotilov commented 4 years ago

What will happen if I, let's say change the screen, so the views will change, but I will reuse this matcher?

Espresso scans view tree on each interaction, so, if we change screen, it will keep working but with some views from previous Activity/Fragment remembered. If there is another matching view on the other screen, then 'seen' set will be cleared. We're testing app with multiple fragments and similar views, and we haven't met any problems with this implementation yet.

Vacxe commented 4 years ago

@yapkolotilov TY for the contribution mate!