Skip to content

Commit

Permalink
Introduce SlotTableInspector API for Compose.
Browse files Browse the repository at this point in the history
  • Loading branch information
zach-klippenstein committed Aug 12, 2021
1 parent 29d788d commit f75d8c8
Show file tree
Hide file tree
Showing 9 changed files with 716 additions and 63 deletions.
1 change: 1 addition & 0 deletions sample-compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ tasks.withType<KotlinCompile> {

dependencies {
implementation(project(":radiography"))
implementation(project(":slot-table-inspector"))
implementation(Dependencies.AppCompat)
implementation(Dependencies.Compose(sampleComposeVersion).Activity())
implementation(Dependencies.Compose(sampleComposeVersion).Material)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Checkbox
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material.TextField
Expand All @@ -31,15 +32,19 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import radiography.ExperimentalRadiographyComposeApi
import radiography.Radiography
import radiography.ScanScopes.FocusedWindowScope
Expand All @@ -50,93 +55,128 @@ import radiography.ViewStateRenderers.DefaultsNoPii
import radiography.ViewStateRenderers.ViewRenderer
import radiography.ViewStateRenderers.androidViewStateRendererFor
import radiography.ViewStateRenderers.textViewRenderer
import radiography.compose.slottable.SlotTableInspectable
import radiography.compose.slottable.SlotTableInspector
import radiography.compose.slottable.SlotTableInspectorState

internal const val TEXT_FIELD_TEST_TAG = "text-field"
internal const val LIVE_HIERARCHY_TEST_TAG = "live-hierarchy"


@Preview(showBackground = true, showSystemUi = true)
@Composable fun ComposeSampleAppPreview() {
ComposeSampleApp()
}

@OptIn(ExperimentalRadiographyComposeApi::class, ExperimentalAnimationApi::class)
@OptIn(
ExperimentalRadiographyComposeApi::class,
ExperimentalAnimationApi::class,
ExperimentalComposeUiApi::class,
)
@Composable fun ComposeSampleApp() {
val context = LocalContext.current
val liveHierarchy = remember { mutableStateOf<String?>(null) }
val slotTableInspectorState = remember { SlotTableInspectorState() }
var showSlotTableInspector by remember { mutableStateOf(false) }

var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var rememberMe by remember { mutableStateOf(false) }

MaterialTheme {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
RadiographyLogo(Modifier.height(128.dp))

TextField(
value = username,
onValueChange = { username = it },
label = { Text("Username") },
colors = TextFieldDefaults.outlinedTextFieldColors(),
modifier = Modifier.testTag(TEXT_FIELD_TEST_TAG)
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
colors = TextFieldDefaults.outlinedTextFieldColors(),
visualTransformation = PasswordVisualTransformation()
)
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(checked = rememberMe, onCheckedChange = { rememberMe = it })
Spacer(Modifier.width(8.dp))
Text("Remember me")
}
SlotTableInspectable(slotTableInspectorState) {
MaterialTheme {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
RadiographyLogo(Modifier.height(128.dp))

Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
TextButton(onClick = {}) {
Text("SIGN IN")
TextField(
value = username,
onValueChange = { username = it },
label = { Text("Username") },
colors = TextFieldDefaults.outlinedTextFieldColors(),
modifier = Modifier.testTag(TEXT_FIELD_TEST_TAG)
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
colors = TextFieldDefaults.outlinedTextFieldColors(),
visualTransformation = PasswordVisualTransformation()
)
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(checked = rememberMe, onCheckedChange = { rememberMe = it })
Spacer(Modifier.width(8.dp))
Text("Remember me")
}
TextButton(onClick = {}) {
Text("FORGOT PASSWORD")

Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
TextButton(onClick = {}) {
Text("SIGN IN")
}
TextButton(onClick = {}) {
Text("FORGOT PASSWORD")
}
}
}

// Include a classic Android view in the composition.
AndroidView(::TextView) {
@SuppressLint("SetTextI18n")
it.text = "By signing in, you agree to our Terms and Conditions."
}
// Include a classic Android view in the composition.
AndroidView(::TextView) {
@SuppressLint("SetTextI18n")
it.text = "By signing in, you agree to our Terms and Conditions."
}

liveHierarchy.value?.let {
Row(
modifier = Modifier
.horizontalScroll(rememberScrollState())
.weight(1f)
) {
Column(Modifier.verticalScroll(rememberScrollState())) {
Text(
liveHierarchy.value.orEmpty(),
fontFamily = FontFamily.Monospace,
fontSize = 6.sp,
modifier = Modifier.testTag(LIVE_HIERARCHY_TEST_TAG)
)
liveHierarchy.value?.let {
Row(
modifier = Modifier
.horizontalScroll(rememberScrollState())
.weight(1f)
) {
Column(Modifier.verticalScroll(rememberScrollState())) {
Text(
liveHierarchy.value.orEmpty(),
fontFamily = FontFamily.Monospace,
fontSize = 6.sp,
modifier = Modifier.testTag(LIVE_HIERARCHY_TEST_TAG)
)
}
}
}
Row {
TextButton(
modifier = Modifier.weight(1f),
onClick = { showSelectionDialog(context) }
) {
Text("SHOW STRING RENDERING DIALOG", textAlign = TextAlign.Center)
}
TextButton(
modifier = Modifier.weight(1f),
onClick = {
slotTableInspectorState.captureSlotTables()
showSlotTableInspector = true
}) {
Text("SHOW SLOT TABLE INSPECTOR", textAlign = TextAlign.Center)
}
}
}
TextButton(onClick = { showSelectionDialog(context) }) {
Text("SHOW STRING RENDERING DIALOG")
}

SideEffect {
liveHierarchy.value = Radiography.scan(
viewStateRenderers = DefaultsIncludingPii,
// Don't trigger infinite recursion.
viewFilter = skipComposeTestTagsFilter(LIVE_HIERARCHY_TEST_TAG)
)
SideEffect {
liveHierarchy.value = Radiography.scan(
viewStateRenderers = DefaultsIncludingPii,
// Don't trigger infinite recursion.
viewFilter = skipComposeTestTagsFilter(LIVE_HIERARCHY_TEST_TAG)
)
}
if (showSlotTableInspector) {
Dialog(
onDismissRequest = { showSlotTableInspector = false },
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
Surface {
SlotTableInspector(slotTableInspectorState)
}
}
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ include(
":compose-unsupported-tests",
":radiography",
":sample",
":sample-compose"
":sample-compose",
":slot-table-inspector",
)
71 changes: 71 additions & 0 deletions slot-table-inspector/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("com.android.library")
kotlin("android")
id("com.vanniktech.maven.publish")
}

android {
compileSdk = 30

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
// Compose minSdk is also 21.
minSdk = 21
targetSdk = 30
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildFeatures {
buildConfig = false
compose = true
}

composeOptions {
kotlinCompilerExtensionVersion = Versions.Compose
}

testOptions {
execution = "ANDROIDX_TEST_ORCHESTRATOR"
}
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += listOfNotNull(
"-Xopt-in=kotlin.RequiresOptIn",

// Require explicit public modifiers and types.
// TODO this should be moved to a top-level `kotlin { explicitApi() }` once that's working
// for android projects, see https://youtrack.jetbrains.com/issue/KT-37652.
"-Xexplicit-api=strict".takeUnless {
// Tests aren't part of the public API, don't turn explicit API mode on for them.
name.contains("test", ignoreCase = true)
}
)
}
}

dependencies {
implementation(Dependencies.Compose().Material)
// implementation(Dependencies.Compose().ToolingData)
implementation(Dependencies.Compose().Tooling)

testImplementation(Dependencies.JUnit)
testImplementation(Dependencies.Mockito)
testImplementation(Dependencies.Robolectric)
testImplementation(Dependencies.Truth)

androidTestImplementation(Dependencies.Compose().Testing)
androidTestImplementation(Dependencies.InstrumentationTests.Core)
androidTestImplementation(Dependencies.InstrumentationTests.Espresso)
androidTestImplementation(Dependencies.InstrumentationTests.Rules)
androidTestImplementation(Dependencies.InstrumentationTests.Runner)
androidTestImplementation(Dependencies.Truth)
androidTestUtil(Dependencies.InstrumentationTests.Orchestrator)
}
3 changes: 3 additions & 0 deletions slot-table-inspector/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
POM_ARTIFACT_ID=slot-table-inspector
POM_NAME=Radiography slot table inspector
POM_PACKAGING=aar
15 changes: 15 additions & 0 deletions slot-table-inspector/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.squareup.radiography.compose.slottable.test">

<!--
Workaround required for running tests on API 30 devices.
See https://github.com/android/android-test/issues/743.
Version 1.3.1 of the AndroidX Test libraries remove the need for this workaround.
-->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

<application>
<activity android:name="androidx.activity.ComponentActivity" />
</application>
</manifest>

1 change: 1 addition & 0 deletions slot-table-inspector/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest package="com.squareup.radiography.compose.slottable"/>
Loading

0 comments on commit f75d8c8

Please sign in to comment.