Skip to content

Commit 65cca83

Browse files
authored
Tidy up app launcher (#391)
1 parent 8c3af70 commit 65cca83

7 files changed

Lines changed: 52 additions & 66 deletions

File tree

app/src/androidTest/java/com/mitteloupe/whoami/launcher/FromScreen.kt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ import androidx.activity.ComponentActivity
44
import androidx.activity.compose.LocalActivity
55
import androidx.appcompat.app.AppCompatActivity
66
import com.mitteloupe.whoami.di.testAppDependenciesEntryPoint
7-
import com.mitteloupe.whoami.test.test.BaseTest.AppLauncher
7+
import com.mitteloupe.whoami.test.launcher.AppLauncher
8+
import com.mitteloupe.whoami.test.launcher.fromComposable
89
import com.mitteloupe.whoami.test.test.TypedAndroidComposeTestRule
910
import com.mitteloupe.whoami.ui.main.AppNavHost
1011
import com.mitteloupe.whoami.ui.theme.WhoAmITheme
1112

12-
data class FromScreen<ACTIVITY : ComponentActivity>(
13-
private val composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
14-
private val startDestination: Any
15-
) : AppLauncher() {
16-
private val composableAppLauncher = FromComposable(composeContentTestRule) {
13+
fun <ACTIVITY : ComponentActivity> fromScreen(
14+
composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
15+
startDestination: Any
16+
) = AppLauncher {
17+
fromComposable(composeContentTestRule) {
1718
WhoAmITheme {
1819
val activity = LocalActivity.current as AppCompatActivity
1920
with(testAppDependenciesEntryPoint(activity).appNavHostDependencies) {
@@ -23,7 +24,5 @@ data class FromScreen<ACTIVITY : ComponentActivity>(
2324
)
2425
}
2526
}
26-
}
27-
28-
override fun launch() = composableAppLauncher.launch()
27+
}.launch()
2928
}

app/src/androidTest/java/com/mitteloupe/whoami/test/HistoryHighlightedIpAddressTest.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package com.mitteloupe.whoami.test
22

33
import androidx.compose.ui.test.ExperimentalTestApi
44
import androidx.compose.ui.test.junit4.createAndroidComposeRule
5-
import com.mitteloupe.whoami.launcher.FromScreen
5+
import com.mitteloupe.whoami.launcher.fromScreen
66
import com.mitteloupe.whoami.localstore.KEY_VALUE_SAVED_HISTORY
77
import com.mitteloupe.whoami.screen.HistoryScreen
88
import com.mitteloupe.whoami.test.annotation.LocalStore
9+
import com.mitteloupe.whoami.test.launcher.AppLauncher
910
import com.mitteloupe.whoami.test.test.BaseTest
1011
import com.mitteloupe.whoami.test.test.retry
1112
import com.mitteloupe.whoami.ui.main.MainActivity
@@ -22,16 +23,14 @@ class HistoryHighlightedIpAddressTest : BaseTest() {
2223
override val composeTestRule = createAndroidComposeRule<MainActivity>()
2324

2425
override val startActivityLauncher: AppLauncher by lazy {
25-
FromScreen(composeTestRule, History(highlightedIpAddress = HIGHLIGHTED_IP_ADDRESS))
26+
fromScreen(composeTestRule, History(highlightedIpAddress = HIGHLIGHTED_IP_ADDRESS))
2627
}
2728

2829
@Inject
2930
lateinit var historyScreen: HistoryScreen
3031

3132
@Test
32-
@LocalStore(
33-
localStoreDataIds = [KEY_VALUE_SAVED_HISTORY]
34-
)
33+
@LocalStore(localStoreDataIds = [KEY_VALUE_SAVED_HISTORY])
3534
fun givenSavedHistoryAndHighlightedIpAddressWhenOnHistoryScreenTheSeesHighlight() {
3635
with(historyScreen) {
3736
retry(repeat = 20) {

app/src/androidTest/java/com/mitteloupe/whoami/test/HistoryTest.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package com.mitteloupe.whoami.test
22

33
import androidx.compose.ui.test.ExperimentalTestApi
44
import androidx.compose.ui.test.junit4.createAndroidComposeRule
5-
import com.mitteloupe.whoami.launcher.FromScreen
5+
import com.mitteloupe.whoami.launcher.fromScreen
66
import com.mitteloupe.whoami.localstore.KEY_VALUE_NO_HISTORY
77
import com.mitteloupe.whoami.localstore.KEY_VALUE_SAVED_HISTORY
88
import com.mitteloupe.whoami.screen.HistoryScreen
99
import com.mitteloupe.whoami.test.annotation.LocalStore
10+
import com.mitteloupe.whoami.test.launcher.AppLauncher
1011
import com.mitteloupe.whoami.test.test.BaseTest
1112
import com.mitteloupe.whoami.test.test.doesNot
1213
import com.mitteloupe.whoami.test.test.retry
@@ -22,7 +23,7 @@ class HistoryTest : BaseTest() {
2223
override val composeTestRule = createAndroidComposeRule<MainActivity>()
2324

2425
override val startActivityLauncher: AppLauncher by lazy {
25-
FromScreen(composeTestRule, History(highlightedIpAddress = null))
26+
fromScreen(composeTestRule, History(highlightedIpAddress = null))
2627
}
2728

2829
@Inject

app/src/androidTest/java/com/mitteloupe/whoami/test/HomeTest.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package com.mitteloupe.whoami.test
33
import androidx.compose.ui.test.ExperimentalTestApi
44
import androidx.compose.ui.test.junit4.createAndroidComposeRule
55
import androidx.test.espresso.intent.Intents
6-
import com.mitteloupe.whoami.launcher.FromScreen
6+
import com.mitteloupe.whoami.launcher.fromScreen
77
import com.mitteloupe.whoami.screen.HomeScreen
88
import com.mitteloupe.whoami.screen.OpenSourceNoticesScreen
99
import com.mitteloupe.whoami.server.REQUEST_RESPONSE_GET_IP
1010
import com.mitteloupe.whoami.server.REQUEST_RESPONSE_GET_IP_DETAILS
1111
import com.mitteloupe.whoami.test.annotation.ServerRequestResponse
12+
import com.mitteloupe.whoami.test.launcher.AppLauncher
1213
import com.mitteloupe.whoami.test.test.BaseTest
1314
import com.mitteloupe.whoami.ui.main.MainActivity
1415
import com.mitteloupe.whoami.ui.main.route.Home
@@ -22,7 +23,7 @@ class HomeTest : BaseTest() {
2223
override val composeTestRule = createAndroidComposeRule<MainActivity>()
2324

2425
override val startActivityLauncher: AppLauncher by lazy {
25-
FromScreen(composeTestRule, Home)
26+
fromScreen(composeTestRule, Home)
2627
}
2728

2829
@Inject
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.mitteloupe.whoami.test.launcher
2+
3+
fun interface AppLauncher {
4+
fun launch()
5+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.mitteloupe.whoami.test.launcher
2+
3+
import android.view.ViewGroup
4+
import androidx.activity.ComponentActivity
5+
import androidx.compose.runtime.Composable
6+
import com.mitteloupe.whoami.test.test.TypedAndroidComposeTestRule
7+
import kotlinx.coroutines.Dispatchers
8+
import kotlinx.coroutines.runBlocking
9+
10+
fun <ACTIVITY : ComponentActivity> fromComposable(
11+
composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
12+
composable: @Composable () -> Unit
13+
) = AppLauncher {
14+
val activity = composeContentTestRule.activity
15+
val root = activity.findViewById<ViewGroup>(android.R.id.content)
16+
if (root != null) {
17+
runBlocking(Dispatchers.Main) {
18+
root.removeAllViews()
19+
}
20+
}
21+
composeContentTestRule.setContent(composable)
22+
}

architecture/instrumentation-test/src/main/java/com/mitteloupe/whoami/test/test/BaseTest.kt

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,19 @@ package com.mitteloupe.whoami.test.test
22

33
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
44
import android.annotation.SuppressLint
5-
import android.app.Activity
6-
import android.content.Intent
75
import android.content.SharedPreferences
8-
import android.view.ViewGroup
9-
import androidx.activity.ComponentActivity
106
import androidx.annotation.CallSuper
11-
import androidx.compose.runtime.Composable
127
import androidx.compose.ui.test.IdlingResource as ComposeIdlingResource
138
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
149
import androidx.compose.ui.test.junit4.ComposeContentTestRule
15-
import androidx.test.core.app.ActivityScenario
1610
import androidx.test.espresso.IdlingRegistry
1711
import androidx.test.espresso.IdlingResource as EspressoIdlingResource
1812
import androidx.test.ext.junit.rules.ActivityScenarioRule
1913
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
2014
import androidx.test.uiautomator.UiDevice
2115
import com.mitteloupe.whoami.test.idlingresource.findAndCloseAppNotRespondingDialog
2216
import com.mitteloupe.whoami.test.idlingresource.registerAppNotRespondingWatcher
17+
import com.mitteloupe.whoami.test.launcher.AppLauncher
2318
import com.mitteloupe.whoami.test.localstore.KeyValueStore
2419
import com.mitteloupe.whoami.test.rule.DisableAnimationsRule
2520
import com.mitteloupe.whoami.test.rule.HiltInjectorRule
@@ -32,8 +27,6 @@ import com.mitteloupe.whoami.test.server.MockWebServerProvider
3227
import com.mitteloupe.whoami.test.server.ResponseStore
3328
import dagger.hilt.android.testing.HiltAndroidRule
3429
import javax.inject.Inject
35-
import kotlinx.coroutines.Dispatchers
36-
import kotlinx.coroutines.runBlocking
3730
import org.junit.Before
3831
import org.junit.BeforeClass
3932
import org.junit.Rule
@@ -49,13 +42,13 @@ abstract class BaseTest {
4942
lateinit var mockDispatcher: MockDispatcher
5043

5144
@Inject
52-
lateinit var mockWebServerProvider: MockWebServerProvider
45+
lateinit var responseStore: ResponseStore
5346

5447
@Inject
55-
lateinit var sharedPreferences: SharedPreferences
48+
lateinit var mockWebServerProvider: MockWebServerProvider
5649

5750
@Inject
58-
lateinit var responseStore: ResponseStore
51+
lateinit var sharedPreferences: SharedPreferences
5952

6053
@Inject
6154
lateinit var keyValueStore: KeyValueStore
@@ -80,8 +73,10 @@ abstract class BaseTest {
8073
)
8174
}
8275

76+
abstract val composeTestRule: ComposeContentTestRule
77+
8378
@get:Rule
84-
open val testRules: RuleChain by lazy {
79+
val testRules: RuleChain by lazy {
8580
@SuppressLint("UnsafeOptInUsageError")
8681
val grantPermissionRule = SdkAwareGrantPermissionRule.grant(
8782
WRITE_EXTERNAL_STORAGE
@@ -97,8 +92,6 @@ abstract class BaseTest {
9792
.around(grantPermissionRule)
9893
}
9994

100-
abstract val composeTestRule: ComposeContentTestRule
101-
10295
abstract val startActivityLauncher: AppLauncher
10396

10497
@Before
@@ -116,40 +109,6 @@ abstract class BaseTest {
116109
composeIdlingResources.forEach(composeTestRule::registerIdlingResource)
117110
}
118111

119-
abstract class AppLauncher {
120-
abstract fun launch()
121-
122-
data class FromIntent(private val intent: Intent) : AppLauncher() {
123-
override fun launch() {
124-
ActivityScenario.launch<Activity>(intent)
125-
}
126-
}
127-
128-
data class FromClass<ACTIVITY : Activity>(private val activityClass: Class<out ACTIVITY>) :
129-
AppLauncher() {
130-
@Suppress("UNCHECKED_CAST")
131-
override fun launch() {
132-
ActivityScenario.launch(activityClass) as ActivityScenario<Activity>
133-
}
134-
}
135-
136-
data class FromComposable<ACTIVITY : ComponentActivity>(
137-
private val composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
138-
private val composable: @Composable () -> Unit
139-
) : AppLauncher() {
140-
override fun launch() {
141-
val activity = composeContentTestRule.activity
142-
val root = activity.findViewById<ViewGroup>(android.R.id.content)
143-
if (root != null) {
144-
runBlocking(Dispatchers.Main) {
145-
root.removeAllViews()
146-
}
147-
}
148-
composeContentTestRule.setContent(composable)
149-
}
150-
}
151-
}
152-
153112
companion object {
154113
@BeforeClass
155114
@CallSuper

0 commit comments

Comments
 (0)