Created
February 6, 2018 13:08
-
-
Save timfreiheit/be07970ecd09bff7c5291125362e2c57 to your computer and use it in GitHub Desktop.
DynamicIntending.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.Activity | |
import android.app.Instrumentation.ActivityResult | |
import android.content.Intent | |
import android.support.test.espresso.intent.Intents | |
import android.support.test.espresso.intent.Intents.intending | |
import android.support.test.espresso.matcher.ViewMatchers.assertThat | |
import org.hamcrest.CoreMatchers.allOf | |
import org.hamcrest.Description | |
import org.hamcrest.Matcher | |
import org.hamcrest.StringDescription | |
import org.hamcrest.TypeSafeMatcher | |
import java.util.* | |
/** | |
* replacement for [Intents.intending] | |
* to provide a more flexible way handling and checking intents | |
* | |
* usage is basically the same as [Intents.intending]: intents are only captured when any respondWith* method is called on [OngoingStubbing] | |
*/ | |
fun dynamicIntending(matcher: Matcher<Intent>): OngoingStubbing { | |
return OngoingStubbing(matcher) | |
} | |
class OngoingStubbing internal constructor(private val catchIntentMatcher: Matcher<Intent>) { | |
private val checkIntentMatchers = ArrayList<Matcher<Intent>>() | |
fun check(intentMatcher: Matcher<Intent>): OngoingStubbing { | |
checkIntentMatchers.add(intentMatcher) | |
return this | |
} | |
fun respondWithResultOk(): IntentValidator { | |
return respondWith(ActivityResult(Activity.RESULT_OK, null)) | |
} | |
fun respondWithResultCanceled(): IntentValidator { | |
return respondWith(ActivityResult(Activity.RESULT_CANCELED, null)) | |
} | |
fun respondWith(resultCode: Int, data: Intent? = null): IntentValidator { | |
return respondWith(ActivityResult(resultCode, data)) | |
} | |
/** | |
* Sets a static response for the intent being stubbed. | |
*/ | |
fun respondWith(result: ActivityResult): IntentValidator { | |
val validator = IntentValidator(catchIntentMatcher) | |
intending(object : TypeSafeMatcher<Intent>() { | |
override fun matchesSafely(item: Intent): Boolean { | |
val matches = catchIntentMatcher.matches(item) | |
if (matches) { | |
validator.intentWasCalled = true | |
checkIntent(item) | |
} | |
return matches | |
} | |
override fun describeTo(description: Description) { | |
catchIntentMatcher.describeTo(description) | |
} | |
}).respondWith(result) | |
return validator | |
} | |
/** | |
* Sets a response for the intent being stubbed. | |
*/ | |
fun respondWith(resultCode: Int, prepareResultIntent: (input: Intent, output: Intent) -> Unit): IntentValidator { | |
val validator = IntentValidator(catchIntentMatcher) | |
val outputIntent = Intent() | |
intending(object : TypeSafeMatcher<Intent>() { | |
override fun matchesSafely(item: Intent): Boolean { | |
val matches = catchIntentMatcher.matches(item) | |
if (matches) { | |
validator.intentWasCalled = true | |
if (outputIntent.extras != null) { | |
outputIntent.extras.clear() | |
} | |
checkIntent(item) | |
prepareResultIntent(item, outputIntent) | |
} | |
return matches | |
} | |
override fun describeTo(description: Description) { | |
catchIntentMatcher.describeTo(description) | |
} | |
}).respondWith(ActivityResult(resultCode, outputIntent)) | |
return validator | |
} | |
private fun checkIntent(intent: Intent) { | |
if (checkIntentMatchers.size == 0) { | |
return | |
} | |
val intentMatcher = allOf(*checkIntentMatchers.toTypedArray()) | |
val description = StringDescription() | |
description.appendText("'") | |
intentMatcher.describeTo(description) | |
description.appendText("' doesn't match the fired intent.") | |
assertThat<Intent>(description.toString(), intent, intentMatcher) | |
} | |
} | |
/** | |
* used to check if the intent was fired by the app | |
*/ | |
class IntentValidator internal constructor(private val matcher: Matcher<Intent>) { | |
var intentWasCalled = false | |
fun verifyIntentWasFired() { | |
if (intentWasCalled) { | |
return | |
} | |
val description = StringDescription() | |
description.appendText("'") | |
matcher.describeTo(description) | |
description.appendText("' was not fired.") | |
throw AssertionError(description.toString()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment