diff --git a/testing/src/main/java/org/oppia/android/testing/espresso/GenericViewMatchers.kt b/testing/src/main/java/org/oppia/android/testing/espresso/GenericViewMatchers.kt index ea1f8b15de4..efbb360d967 100644 --- a/testing/src/main/java/org/oppia/android/testing/espresso/GenericViewMatchers.kt +++ b/testing/src/main/java/org/oppia/android/testing/espresso/GenericViewMatchers.kt @@ -1,7 +1,9 @@ package org.oppia.android.testing.espresso import android.graphics.drawable.GradientDrawable +import android.os.Build import android.view.View +import androidx.annotation.RequiresApi import org.hamcrest.Description import org.hamcrest.Matcher import org.hamcrest.TypeSafeMatcher @@ -19,6 +21,7 @@ class GenericViewMatchers { * Returns a [Matcher] that verifies a view has a fully opaque background. The view is expected * to have a [GradientDrawable] background. */ + @RequiresApi(Build.VERSION_CODES.N) fun withOpaqueBackground(): Matcher = withColorBackgroundMatching( descriptionSuffix = "an opaque background" ) { color -> color?.extractAlpha() == 0xff } @@ -27,6 +30,7 @@ class GenericViewMatchers { * Returns a [Matcher] with the specified description suffix and color matcher, matching against * filled background colors of views. */ + @RequiresApi(Build.VERSION_CODES.N) private fun withColorBackgroundMatching( @Suppress("SameParameterValue") descriptionSuffix: String, colorMatcher: (Long?) -> Boolean diff --git a/testing/src/main/java/org/oppia/android/testing/junit/OppiaParameterizedTestRunner.kt b/testing/src/main/java/org/oppia/android/testing/junit/OppiaParameterizedTestRunner.kt index 4dd7b3427c7..ae5e3e5f55c 100644 --- a/testing/src/main/java/org/oppia/android/testing/junit/OppiaParameterizedTestRunner.kt +++ b/testing/src/main/java/org/oppia/android/testing/junit/OppiaParameterizedTestRunner.kt @@ -1,5 +1,7 @@ package org.oppia.android.testing.junit +import android.os.Build +import androidx.annotation.RequiresApi import org.junit.runner.Description import org.junit.runner.Runner import org.junit.runner.manipulation.Filter @@ -76,6 +78,7 @@ import kotlin.reflect.KClass * contain (thus they should be treated as undefined outside of tests that specific define their * value via [Iteration]). */ +@RequiresApi(Build.VERSION_CODES.N) class OppiaParameterizedTestRunner(private val testClass: Class<*>) : Suite(testClass, listOf()) { private val parameterizedMethods = computeParameterizedMethods() private val selectedRunnerClass by lazy { fetchSelectedRunnerPlatformClass() } @@ -95,6 +98,7 @@ class OppiaParameterizedTestRunner(private val testClass: Class<*>) : Suite(test override fun getChildren(): MutableList = childrenRunners.toMutableList() + @RequiresApi(Build.VERSION_CODES.N) private fun computeParameterizedMethods(): Map { val fieldsAndParsers = fetchParameterizedFields().map { field -> val valueParser = ParameterValue.createParserForField(field) @@ -184,12 +188,14 @@ class OppiaParameterizedTestRunner(private val testClass: Class<*>) : Suite(test }.associateBy { it.methodName } } + @RequiresApi(Build.VERSION_CODES.N) private fun fetchParameterizedFields(): List { return testClass.declaredFields.mapNotNull { field -> field.getDeclaredAnnotation(Parameter::class.java)?.let { field } } } + @RequiresApi(Build.VERSION_CODES.N) private fun fetchParameterizedMethodDeclarations(): List { return testClass.declaredMethods.mapNotNull { method -> method.getDeclaredAnnotationsByType(Iteration::class.java).map { parameters -> @@ -208,6 +214,7 @@ class OppiaParameterizedTestRunner(private val testClass: Class<*>) : Suite(test } } + @RequiresApi(Build.VERSION_CODES.N) private fun fetchSelectedRunnerPlatformClass(): Class<*> { return checkNotNull(testClass.getDeclaredAnnotation(SelectRunnerPlatform::class.java)) { "All suites using OppiaParameterizedTestRunner must declare their base platform runner" + diff --git a/testing/src/main/java/org/oppia/android/testing/threading/TestCoroutineDispatchersRobolectricImpl.kt b/testing/src/main/java/org/oppia/android/testing/threading/TestCoroutineDispatchersRobolectricImpl.kt index 3c93d9065bd..2f27175670b 100644 --- a/testing/src/main/java/org/oppia/android/testing/threading/TestCoroutineDispatchersRobolectricImpl.kt +++ b/testing/src/main/java/org/oppia/android/testing/threading/TestCoroutineDispatchersRobolectricImpl.kt @@ -1,5 +1,7 @@ package org.oppia.android.testing.threading +import android.os.Build +import androidx.annotation.RequiresApi import org.oppia.android.testing.time.FakeSystemClock import java.lang.reflect.Method import java.time.Duration @@ -34,6 +36,7 @@ class TestCoroutineDispatchersRobolectricImpl @Inject constructor( } while (hasPendingCompletableTasks()) } + @RequiresApi(Build.VERSION_CODES.O) override fun advanceTimeBy(delayTimeMillis: Long) { var remainingDelayMillis = delayTimeMillis while (remainingDelayMillis > 0) { @@ -49,6 +52,7 @@ class TestCoroutineDispatchersRobolectricImpl @Inject constructor( } } + @RequiresApi(Build.VERSION_CODES.O) override fun advanceUntilIdle() { // First, run through all tasks that are currently pending and can be run immediately. runCurrent() @@ -67,6 +71,7 @@ class TestCoroutineDispatchersRobolectricImpl @Inject constructor( } } + @RequiresApi(Build.VERSION_CODES.O) private fun advanceToNextFutureTask( currentTimeMillis: Long, maxDelayMs: Long = Long.MAX_VALUE @@ -94,6 +99,7 @@ class TestCoroutineDispatchersRobolectricImpl @Inject constructor( } /** Returns whether any of the dispatchers have any tasks to run, including in the future. */ + @RequiresApi(Build.VERSION_CODES.O) private fun hasPendingTasks(): Boolean { return backgroundTestDispatcher.hasPendingTasks() || blockingTestDispatcher.hasPendingTasks() || @@ -107,6 +113,7 @@ class TestCoroutineDispatchersRobolectricImpl @Inject constructor( !uiTaskCoordinator.isIdle() } + @RequiresApi(Build.VERSION_CODES.O) private fun getNextFutureTaskTimeMillis(timeMillis: Long): Long? { val nextBackgroundFutureTaskTimeMills = backgroundTestDispatcher.getNextFutureTaskCompletionTimeMillis(timeMillis) @@ -120,6 +127,7 @@ class TestCoroutineDispatchersRobolectricImpl @Inject constructor( return futureTimes.firstOrNull() } + @RequiresApi(Build.VERSION_CODES.O) private fun getNextUiThreadFutureTaskTimeMillis(timeMillis: Long): Long? { return uiTaskCoordinator.getNextUiThreadFutureTaskTimeMillis(timeMillis) } @@ -139,6 +147,7 @@ class TestCoroutineDispatchersRobolectricImpl @Inject constructor( idleMethod.invoke(shadowUiLooper) } + @RequiresApi(Build.VERSION_CODES.O) fun getNextUiThreadFutureTaskTimeMillis(timeMillis: Long): Long? { val nextScheduledTime = nextScheduledTimeMethod.invoke(shadowUiLooper) as Duration val delayMs = nextScheduledTime.toMillis()