diff --git a/android/testutils/BUILD b/android/testutils/BUILD
new file mode 100644
index 000000000..abb617d4d
--- /dev/null
+++ b/android/testutils/BUILD
@@ -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",
+)
\ No newline at end of file
diff --git a/android/testutils/README.md b/android/testutils/README.md
new file mode 100644
index 000000000..5175ab487
--- /dev/null
+++ b/android/testutils/README.md
@@ -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.
\ No newline at end of file
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/deps.bzl b/android/testutils/deps.bzl
similarity index 100%
rename from plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/deps.bzl
rename to android/testutils/deps.bzl
diff --git a/android/testutils/src/main/AndroidManifest.xml b/android/testutils/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..2d1b71c11
--- /dev/null
+++ b/android/testutils/src/main/AndroidManifest.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/Assertions.kt b/android/testutils/src/main/java/com/intuit/playerui/android/testutils/asset/Assertions.kt
similarity index 75%
rename from plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/Assertions.kt
rename to android/testutils/src/main/java/com/intuit/playerui/android/testutils/asset/Assertions.kt
index 8f21b6deb..ed7537b42 100644
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/Assertions.kt
+++ b/android/testutils/src/main/java/com/intuit/playerui/android/testutils/asset/Assertions.kt
@@ -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
@@ -10,7 +10,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
-inline fun Any?.shouldBeAsset(
+public inline fun Any?.shouldBeAsset(
block: T.() -> Unit = {},
): T {
shouldBeInstanceOf(this)
@@ -19,7 +19,7 @@ inline fun Any?.shouldBeAsset(
}
@OptIn(ExperimentalContracts::class)
-inline fun Any?.shouldBeView(assertions: T.() -> Unit = {}): T {
+public inline fun Any?.shouldBeView(assertions: T.() -> Unit = {}): T {
val view = if (T::class != SuspendableAsset.AsyncViewStub::class && this is SuspendableAsset.AsyncViewStub) {
runBlocking {
awaitView()
@@ -33,14 +33,14 @@ inline fun Any?.shouldBeView(assertions: T.() -> Unit = {}):
}
@OptIn(ExperimentalContracts::class)
-inline fun PlayerFlowState?.shouldBePlayerState(assertions: T.() -> Unit = {}): T {
+public inline fun PlayerFlowState?.shouldBePlayerState(assertions: T.() -> Unit = {}): T {
shouldBeInstanceOf(this)
assertions()
return this
}
@ExperimentalContracts
-inline fun shouldBeInstanceOf(
+public inline fun shouldBeInstanceOf(
`this`: Any?,
) {
contract {
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/AssetTest.kt b/android/testutils/src/main/java/com/intuit/playerui/android/testutils/asset/AssetTest.kt
similarity index 78%
rename from plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/AssetTest.kt
rename to android/testutils/src/main/java/com/intuit/playerui/android/testutils/asset/AssetTest.kt
index 903d0df5a..07367d883 100644
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/AssetTest.kt
+++ b/android/testutils/src/main/java/com/intuit/playerui/android/testutils/asset/AssetTest.kt
@@ -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
@@ -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 by lazy { listOf(ReferenceAssetsPlugin(), CommonTypesPlugin(), PendingTransactionPlugin()) }
+ protected open val plugins: List 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)
}
@@ -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
@@ -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
@@ -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 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 ->
@@ -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)
}
diff --git a/plugins/reference-assets/android/defs.bzl b/plugins/reference-assets/android/defs.bzl
index c253463a2..acd8112f9 100644
--- a/plugins/reference-assets/android/defs.bzl
+++ b/plugins/reference-assets/android/defs.bzl
@@ -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 = [
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/action/ActionTest.kt b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/action/ActionTest.kt
index aa6d9797d..230404252 100644
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/action/ActionTest.kt
+++ b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/action/ActionTest.kt
@@ -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
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/collection/CollectionTest.kt b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/collection/CollectionTest.kt
index 0bb5e5e62..3252c81a2 100644
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/collection/CollectionTest.kt
+++ b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/collection/CollectionTest.kt
@@ -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
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/info/InfoTest.kt b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/info/InfoTest.kt
index 6b2ebdf5a..f36d53ccc 100644
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/info/InfoTest.kt
+++ b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/info/InfoTest.kt
@@ -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
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/input/InputTest.kt b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/input/InputTest.kt
index 14f164715..e5d0b77a9 100644
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/input/InputTest.kt
+++ b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/input/InputTest.kt
@@ -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
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/BUILD b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/BUILD
deleted file mode 100644
index 80a0a36f2..000000000
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/test/BUILD
+++ /dev/null
@@ -1,19 +0,0 @@
-load("@rules_kotlin//kotlin:android.bzl", "kt_android_library")
-load("@rules_player//kotlin:defs.bzl", "lint")
-load(":deps.bzl", "main_deps")
-
-kt_android_library(
- name = "test",
- srcs = [
- "Assertions.kt",
- "AssetTest.kt",
- ],
- visibility = ["//plugins/reference-assets/android:__subpackages__"],
- deps = main_deps,
-)
-
-lint(
- name = "test",
- srcs = glob(["*.kt"]),
- lint_config = "//jvm:lint_config",
-)
diff --git a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/text/TextTest.kt b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/text/TextTest.kt
index 79e573875..9aea5e843 100644
--- a/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/text/TextTest.kt
+++ b/plugins/reference-assets/android/src/androidTest/java/com/intuit/playerui/android/reference/assets/text/TextTest.kt
@@ -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