Skip to content

Commit

Permalink
Moved AssetTest and Assertions into an android testutils package (#586)
Browse files Browse the repository at this point in the history
* Moved AssetTest and Aseertions into an android testutils package

* Changed visibility to protected

* Fixed failing tests

* Changed package export

* Fixed lint errors
  • Loading branch information
mrigankmg authored Feb 13, 2025
1 parent 3ff4fe0 commit fb718ce
Show file tree
Hide file tree
Showing 13 changed files with 81 additions and 58 deletions.
36 changes: 36 additions & 0 deletions android/testutils/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
load("@rules_kotlin//kotlin:android.bzl", "kt_android_library")
load("@rules_player//kotlin:defs.bzl", "lint")
load("@build_constants//:constants.bzl", "VERSION")
load("//jvm:defs.bzl", "distribution")
load(":deps.bzl", "main_deps")

kt_android_library(
name = "testutils_android",
srcs = glob(["src/main/java/**/*.kt"]),
custom_package = "com.intuit.playerui.android.testutils",
manifest = ":src/main/AndroidManifest.xml",
resource_files = glob(["src/main/res/**"]),
deps = main_deps,
)

android_library(
name = "testutils",
custom_package = "com.intuit.playerui.android.testutils",
manifest = ":src/main/AndroidManifest.xml",
resource_files = glob(["src/main/res/**"]),
tags = ["maven_coordinates=com.intuit.playerui.android:testutils:aar:%s" % VERSION],
visibility = ["//visibility:public"],
exports = [":testutils_android"],
deps = main_deps,
)

distribution(
name = "testutils",
maven_coordinates = "com.intuit.playerui.android:testutils:%s" % VERSION,
)

lint(
name = "testutils",
srcs = glob(["src/main/**/*.kt"]),
lint_config = "//jvm:lint_config",
)
3 changes: 3 additions & 0 deletions android/testutils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Test Utilities

Along with some generic utilities, this module exposes some base test classes to provide some structure to similar Player integration tests or runtime tests. These are built on JUnit Jupiter and require the concrete tests to be written using the JUnit Jupiter API.
File renamed without changes.
3 changes: 3 additions & 0 deletions android/testutils/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.intuit.playerui.android.testutils">
<uses-sdk android:minSdkVersion="14" />
</manifest>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.intuit.playerui.android.reference.assets.test
package com.intuit.playerui.android.testutils.asset

import android.view.View
import com.intuit.playerui.android.asset.RenderableAsset
Expand All @@ -10,7 +10,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract

@OptIn(ExperimentalContracts::class)
inline fun <reified T : RenderableAsset> Any?.shouldBeAsset(
public inline fun <reified T : RenderableAsset> Any?.shouldBeAsset(
block: T.() -> Unit = {},
): T {
shouldBeInstanceOf<T>(this)
Expand All @@ -19,7 +19,7 @@ inline fun <reified T : RenderableAsset> Any?.shouldBeAsset(
}

@OptIn(ExperimentalContracts::class)
inline fun <reified T : View> Any?.shouldBeView(assertions: T.() -> Unit = {}): T {
public inline fun <reified T : View> Any?.shouldBeView(assertions: T.() -> Unit = {}): T {
val view = if (T::class != SuspendableAsset.AsyncViewStub::class && this is SuspendableAsset.AsyncViewStub) {
runBlocking {
awaitView()
Expand All @@ -33,14 +33,14 @@ inline fun <reified T : View> Any?.shouldBeView(assertions: T.() -> Unit = {}):
}

@OptIn(ExperimentalContracts::class)
inline fun <reified T : PlayerFlowState> PlayerFlowState?.shouldBePlayerState(assertions: T.() -> Unit = {}): T {
public inline fun <reified T : PlayerFlowState> PlayerFlowState?.shouldBePlayerState(assertions: T.() -> Unit = {}): T {
shouldBeInstanceOf<T>(this)
assertions()
return this
}

@ExperimentalContracts
inline fun <reified T> shouldBeInstanceOf(
public inline fun <reified T> shouldBeInstanceOf(
`this`: Any?,
) {
contract {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.intuit.playerui.android.reference.assets.test
package com.intuit.playerui.android.testutils.asset

import android.content.Context
import android.view.View
Expand Down Expand Up @@ -46,16 +46,16 @@ import org.robolectric.annotation.Config
@RunWith(AndroidJUnit4::class)
@Config(sdk = [28])
@OptIn(ExperimentalCoroutinesApi::class)
abstract class AssetTest(val group: String? = null) {
public abstract class AssetTest(private val group: String? = null) {

@get:Rule
val name = TestName()
public val name: TestName = TestName()

open val plugins: List<Plugin> by lazy { listOf(ReferenceAssetsPlugin(), CommonTypesPlugin(), PendingTransactionPlugin()) }
protected open val plugins: List<Plugin> by lazy { listOf(ReferenceAssetsPlugin(), CommonTypesPlugin(), PendingTransactionPlugin()) }

val context: Context get() = ApplicationProvider.getApplicationContext()
protected val context: Context get() = ApplicationProvider.getApplicationContext()

val player by lazy {
protected val player: AndroidPlayer by lazy {
AndroidPlayer(plugins)
}

Expand All @@ -75,7 +75,7 @@ abstract class AssetTest(val group: String? = null) {
throw AssertionError("Expected view to update, but it did not.", exception)
}

var currentAssetTree: RenderableAsset? = null; private set(value) {
protected var currentAssetTree: RenderableAsset? = null; private set(value) {
// reset view on new asset
currentView = null

Expand All @@ -89,7 +89,7 @@ abstract class AssetTest(val group: String? = null) {
}
}

var currentView: View? = null; get() = field ?: blockUntilRendered()
protected var currentView: View? = null; get() = field ?: blockUntilRendered()
set(value) {
field = value.also {
// reset replay cache to clear value if the current value is set to null
Expand All @@ -99,14 +99,14 @@ abstract class AssetTest(val group: String? = null) {

protected val currentState: PlayerFlowState get() = player.state

protected val mocks get() = ClassLoaderMocksReader(context.classLoader).mocks.filter {
protected val mocks: List<ClassLoaderMock> get() = ClassLoaderMocksReader(context.classLoader).mocks.filter {
group == null || group == it.group
}

private val emptyView = View(context)

@Before
fun beforeEach() {
public fun beforeEach() {
Dispatchers.setMain(TestCoroutineDispatcher())
player.onUpdate { asset, _ -> currentAssetTree = asset }
player.hooks.state.tap { state ->
Expand All @@ -118,34 +118,34 @@ abstract class AssetTest(val group: String? = null) {
}

@After
fun afterEach() {
public fun afterEach() {
Dispatchers.resetMain()
}

fun launchMock() = launchMock(name.methodName)
protected fun launchMock(): Unit = launchMock(name.methodName)

fun launchMock(name: String) = launchMock(
protected fun launchMock(name: String): Unit = launchMock(
mocks.find { it.name == name || it.name == "$group-$name" }
?: throw IllegalArgumentException("$name not found in mocks: ${mocks.map { "${it.group}/${it.name}" }}"),
)

fun launchMock(mock: Mock<*>) = launchJson(
protected fun launchMock(mock: Mock<*>): Unit = launchJson(
when (mock) {
is ClassLoaderMock -> mock.getFlow(context.classLoader)
else -> throw IllegalArgumentException("mock of type ${mock::class.java.simpleName} not supported")
},
)

fun launchJson(json: JsonElement) = launchJson(Json.encodeToString(json))
protected fun launchJson(json: JsonElement): Unit = launchJson(Json.encodeToString(json))

fun launchJson(json: String) = player.start(makeFlow(json)).onComplete {
protected fun launchJson(json: String): Unit = player.start(makeFlow(json)).onComplete {
it.exceptionOrNull()?.printStackTrace()
}

/** Suspend until we have a [View] representation of [currentAssetTree] that is _completely_ hydrated */
suspend fun awaitRendered(timeout: Long = 5_000): View = consumeLatestView(timeout)
protected suspend fun awaitRendered(timeout: Long = 5_000): View = consumeLatestView(timeout)

fun blockUntilRendered(timeout: Long = 5_000) = runBlocking {
protected fun blockUntilRendered(timeout: Long = 5_000): View = runBlocking {
awaitRendered(timeout)
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/reference-assets/android/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def kt_asset_test(
test_class = test_class,
deps = deps + [
"//tools/mocks:jar",
"//plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test",
"//android/testutils",
"//jvm/j2v8:j2v8-all",
],
resources = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import android.widget.Button
import android.widget.LinearLayout
import androidx.core.view.get
import com.intuit.playerui.android.reference.assets.R
import com.intuit.playerui.android.reference.assets.test.AssetTest
import com.intuit.playerui.android.reference.assets.test.shouldBeAsset
import com.intuit.playerui.android.reference.assets.test.shouldBePlayerState
import com.intuit.playerui.android.reference.assets.test.shouldBeView
import com.intuit.playerui.android.reference.assets.text.Text
import com.intuit.playerui.android.testutils.asset.AssetTest
import com.intuit.playerui.android.testutils.asset.shouldBeAsset
import com.intuit.playerui.android.testutils.asset.shouldBePlayerState
import com.intuit.playerui.android.testutils.asset.shouldBeView
import com.intuit.playerui.core.player.state.CompletedState
import com.intuit.playerui.core.player.state.ErrorState
import com.intuit.playerui.core.player.state.InProgressState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.get
import com.intuit.playerui.android.reference.assets.R
import com.intuit.playerui.android.reference.assets.test.AssetTest
import com.intuit.playerui.android.reference.assets.test.shouldBePlayerState
import com.intuit.playerui.android.reference.assets.test.shouldBeView
import com.intuit.playerui.android.testutils.asset.AssetTest
import com.intuit.playerui.android.testutils.asset.shouldBePlayerState
import com.intuit.playerui.android.testutils.asset.shouldBeView
import com.intuit.playerui.core.player.state.InProgressState
import org.junit.Assert.assertEquals
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.get
import com.intuit.playerui.android.reference.assets.R
import com.intuit.playerui.android.reference.assets.test.AssetTest
import com.intuit.playerui.android.reference.assets.test.shouldBePlayerState
import com.intuit.playerui.android.reference.assets.test.shouldBeView
import com.intuit.playerui.android.testutils.asset.AssetTest
import com.intuit.playerui.android.testutils.asset.shouldBePlayerState
import com.intuit.playerui.android.testutils.asset.shouldBeView
import com.intuit.playerui.core.player.state.InProgressState
import org.junit.Assert.assertEquals
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.get
import com.intuit.playerui.android.reference.assets.R
import com.intuit.playerui.android.reference.assets.test.AssetTest
import com.intuit.playerui.android.reference.assets.test.shouldBePlayerState
import com.intuit.playerui.android.reference.assets.test.shouldBeView
import com.intuit.playerui.android.testutils.asset.AssetTest
import com.intuit.playerui.android.testutils.asset.shouldBePlayerState
import com.intuit.playerui.android.testutils.asset.shouldBeView
import com.intuit.playerui.core.player.state.InProgressState
import com.intuit.playerui.core.player.state.dataModel
import org.junit.Assert.assertEquals
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.get
import com.intuit.playerui.android.reference.assets.R
import com.intuit.playerui.android.reference.assets.test.AssetTest
import com.intuit.playerui.android.reference.assets.test.shouldBeView
import com.intuit.playerui.android.testutils.asset.AssetTest
import com.intuit.playerui.android.testutils.asset.shouldBeView
import org.junit.Assert.assertEquals
import org.junit.Test

Expand Down

0 comments on commit fb718ce

Please sign in to comment.