Merge "Make AppListPage testable"

This commit is contained in:
Chaohui Wang
2022-12-06 02:50:22 +00:00
committed by Android (Google) Code Review
9 changed files with 67 additions and 27 deletions

View File

@@ -24,7 +24,9 @@ android_library {
srcs: ["src/**/*.kt"],
static_libs: [
"SpaLib",
"androidx.arch.core_core-testing",
"androidx.compose.runtime_runtime",
"androidx.compose.ui_ui-test-junit4",
"androidx.compose.ui_ui-test-manifest",
"mockito",

View File

@@ -44,9 +44,17 @@ android {
jvmTarget = '1.8'
freeCompilerArgs = ["-Xjvm-default=all"]
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion jetpack_compose_compiler_version
}
}
dependencies {
api project(":SpaLib")
api "androidx.arch.core:core-testing:2.1.0"
api "androidx.compose.ui:ui-test-junit4:$jetpack_compose_version"
api "com.google.truth:truth:1.1.3"

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settingslib.spa.testutils
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import com.android.settingslib.spa.framework.compose.LocalNavController
import com.android.settingslib.spa.framework.compose.NavControllerWrapper
class FakeNavControllerWrapper : NavControllerWrapper {
var navigateCalledWith: String? = null
var navigateBackIsCalled = false
override fun navigate(route: String) {
navigateCalledWith = route
}
override fun navigateBack() {
navigateBackIsCalled = true
}
@Composable
fun Wrapper(content: @Composable () -> Unit) {
CompositionLocalProvider(LocalNavController provides this) {
content()
}
}
}

View File

@@ -29,7 +29,7 @@ import kotlinx.coroutines.flow.combine
/**
* The config used to load the App List.
*/
internal data class AppListConfig(
data class AppListConfig(
val userId: Int,
val showInstantApps: Boolean,
)

View File

@@ -49,13 +49,13 @@ import kotlinx.coroutines.Dispatchers
private const val TAG = "AppList"
private const val CONTENT_TYPE_HEADER = "header"
internal data class AppListState(
data class AppListState(
val showSystem: State<Boolean>,
val option: State<Int>,
val searchQuery: State<String>,
)
internal data class AppListInput<T : AppRecord>(
data class AppListInput<T : AppRecord>(
val config: AppListConfig,
val listModel: AppListModel<T>,
val state: AppListState,
@@ -70,10 +70,13 @@ internal data class AppListInput<T : AppRecord>(
* This UI element will take the remaining space on the screen to show the App List.
*/
@Composable
internal fun <T : AppRecord> AppListInput<T>.AppList(
appListDataSupplier: @Composable () -> State<AppListData<T>?> = {
loadAppListData(config, listModel, state)
},
fun <T : AppRecord> AppListInput<T>.AppList() {
AppListImpl { loadAppListData(config, listModel, state) }
}
@Composable
internal fun <T : AppRecord> AppListInput<T>.AppListImpl(
appListDataSupplier: @Composable () -> State<AppListData<T>?>,
) {
LogCompositions(TAG, config.userId.toString())
val appListData = appListDataSupplier()

View File

@@ -28,7 +28,7 @@ import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.AppRecord
class AppListItemModel<T : AppRecord>(
data class AppListItemModel<T : AppRecord>(
val record: T,
val label: String,
val summary: State<String>,

View File

@@ -47,23 +47,8 @@ fun <T : AppRecord> AppListPage(
primaryUserOnly: Boolean = false,
moreOptions: @Composable MoreOptionsScope.() -> Unit = {},
header: @Composable () -> Unit = {},
appList: @Composable AppListInput<T>.() -> Unit = { AppList() },
appItem: @Composable AppListItemModel<T>.() -> Unit,
) {
AppListPageImpl(
title, listModel, showInstantApps, primaryUserOnly, moreOptions, header, appItem,
) { it.AppList() }
}
@Composable
internal fun <T : AppRecord> AppListPageImpl(
title: String,
listModel: AppListModel<T>,
showInstantApps: Boolean = false,
primaryUserOnly: Boolean = false,
moreOptions: @Composable MoreOptionsScope.() -> Unit = {},
header: @Composable () -> Unit = {},
appItem: @Composable AppListItemModel<T>.() -> Unit,
appList: @Composable (input: AppListInput<T>) -> Unit,
) {
val showSystem = rememberSaveable { mutableStateOf(false) }
SearchScaffold(

View File

@@ -118,12 +118,12 @@ class AppListPageTest {
): State<AppListInput<TestAppRecord>?> {
val appListState = mutableStateOf<AppListInput<TestAppRecord>?>(null)
composeTestRule.setContent {
AppListPageImpl(
AppListPage(
title = TITLE,
listModel = TestAppListModel(options),
header = header,
appItem = { AppListItem {} },
appList = { appListState.value = it },
appList = { appListState.value = this },
)
}
return appListState

View File

@@ -102,7 +102,7 @@ class AppListTest {
appItem = { AppListItem {} },
bottomPadding = 0.dp,
)
appListInput.AppList { stateOf(AppListData(appEntries, option = 0)) }
appListInput.AppListImpl { stateOf(AppListData(appEntries, option = 0)) }
}
}