Status Update
Comments
pa...@google.com <pa...@google.com> #2
Branch: androidx-master-dev
commit c60f33e229e31ab328ef6b59dab63b264954831c
Author: Alexandre Elias <aelias@google.com>
Date: Fri Jul 10 16:23:09 2020
Semantics no-op cleanups
Partly in response to lmr's broad code review, I did a pass of
superficial API/implementation cleanup. The main changes are:
- I changed each Boolean SemanticsProperty where false is equivalent to
not being present to take "Unit" instead. This is conceptually
clearer: it avoids questions like "can I cancel out a semantics from a
merged child by setting it to false?" Because "property = Unit" looks
weird, I also changed the style of these to "property()".
- I moved the Semantics id generator closer to where it's used, in
SemanticsModifierCore. I made it internal and an AtomicInt.
(Note that integer ids are heavily used in the Android
AccessibilityNodeInfo APIs so I can't simply remove them entirely.)
- I deleted dead code. Some examples include SemanticsHintOverrides,
a public API not connected to anything, and SemanticsPropertyKey
merge() open method which is never called. (In both cases I have
a different plan in mind for accessibility.)
Fixes: 145951226
Fixes: 145955412
Test: existing tests
Relnote: "Single-value semantics properties now use a calling style.
For example, 'semantics { hidden = true }' is now written as:
'semantics { hidden() }'."
Change-Id: Ic1afd12ea22c926babc9662f1804d80b33aa0cfc
M ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/LayoutNodeModifierBenchmark.kt
M ui/ui-core/api/0.1.0-dev15.txt
M ui/ui-core/api/current.txt
M ui/ui-core/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-core/api/public_plus_experimental_current.txt
M ui/ui-core/api/restricted_0.1.0-dev15.txt
M ui/ui-core/api/restricted_current.txt
M ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/graphics/vector/VectorTest.kt
M ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/semantics/SemanticsTests.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidActuals.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidComposeView.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidComposeViewAccessibilityDelegateCompat.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidPopup.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/Expect.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsConfiguration.kt
D ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsHintOverrides.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsModifier.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsNode.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsOwner.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsWrapper.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/semantics/SemanticsProperties.kt
M ui/ui-foundation/api/0.1.0-dev15.txt
M ui/ui-foundation/api/current.txt
M ui/ui-foundation/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-foundation/api/public_plus_experimental_current.txt
M ui/ui-foundation/api/restricted_0.1.0-dev15.txt
M ui/ui-foundation/api/restricted_current.txt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Selectable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Toggleable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/semantics/FoundationSemanticsProperties.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/CardTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxScreenshotTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/RadioButtonScreenshotTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ScaffoldTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/SnackbarTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/SurfaceTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ripple/RippleIndicationTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/textfield/TextFieldScreenshotTest.kt
M ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
M ui/ui-material/src/main/java/androidx/ui/material/TextFieldImpl.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/AssertsTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/CallSemanticsActionTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/ErrorMessagesTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/FindersTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/PrintToStringTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/ScrollToTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/TextActionsTest.kt
M ui/ui-test/src/main/java/androidx/ui/test/Actions.kt
M ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
M ui/ui-text/api/0.1.0-dev15.txt
M ui/ui-text/api/current.txt
M ui/ui-text/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-text/api/public_plus_experimental_current.txt
M ui/ui-text/api/restricted_0.1.0-dev15.txt
M ui/ui-text/api/restricted_current.txt
M ui/ui-text/src/commonMain/kotlin/androidx/ui/text/CoreTextField.kt
M ui/ui-text/src/commonMain/kotlin/androidx/ui/text/TextSemanticsProperties.kt
jo...@google.com <jo...@google.com> #3
Actually, createAndroidComposeRule
does not seem to allow for the situation where an Activity needs input. I can only find a version where you pass the activity class name, and it gets constructed for you without inputs.
pa...@google.com <pa...@google.com> #4
What kind of input do you mean? Do you mean input for Activity or ActivityScenarioRule?
jo...@google.com <jo...@google.com> #5
Input for the Activity. In the scenario that I linked, the Activity needs a string passed in its intent:
val intent = Intent(context, DetailsActivity::class.java)
intent.putExtra(KEY_ARG_DETAILS_CITY_NAME, item.city.name)
return intent
If I use createAndroidComposeRule
, how would I pass that city name?
je...@google.com <je...@google.com> #6
Our API is not very friendly to accommodate this scenario (because we didn't think of this use when designing it), but it is possible to achieve with public API:
@LargeTest
@RunWith(AndroidJUnit4::class)
class LateActivityLaunchTest {
private lateinit var activityScenario: ActivityScenario<CustomActivity>
@get:Rule
val rule = AndroidComposeTestRule(EmptyTestRule()) {
var activity: CustomActivity? = null
activityScenario.onActivity { activity = it }
checkNotNull(activity) { "Activity didn't launch" }
}
class EmptyTestRule : TestRule {
override fun apply(base: Statement, description: Description) = base
}
@Test
fun test() {
setupSomethingFirst()
ActivityScenario.launch<CustomActivity>(
Intent(ApplicationProvider.getApplicationContext(), CustomActivity::class.java)
).use {
activityScenario = it
rule.onNode(hasText("Hello")).assertExists()
}
}
private fun setupSomethingFirst() {
}
}
class CustomActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Text("Hello")
}
}
}
We should provide more accessible support in our API for this though
je...@google.com <je...@google.com> #7
Current thoughts are to split the ComposeTestRule
interface and add fun createComposeRuleNoLauncher
. Roughly something like this:
// commonMain
interface ComposeTestRule {
// same as now, but without `fun setContent`
}
// commonMain
interface ComposeContentTestRule : ComposeTestRule {
fun setContent(content: @Composable () -> Unit)
}
// androidMain
class AndroidComposeTestRule : ComposeContentTestRule
// commonMain
expect fun createComposeRule() : ComposeContentTestRule
// androidMain
actual fun createComposeRule() = createAndroidComposeRule()
// androidMain
fun createAndroidComposeRule() : AndroidComposeTestRule
// androidMain
fun createComposeRuleNoLauncher() : ComposeTestRule = AndroidComposeTestRule(activityRule = null)
A few things still have to be worked out, but the main bit I wanted to share is the new factory method and the interface split.
Things still to be worked out:
- Will we keep supporting AndroidComposeTestRule with a generic activityRule + activityProvider, or do we direct devs to use
createComposeRuleNoLauncher
and do the wiring themselves? - AndroidComposeTestRule constructor to be used by
createComposeRuleNoLauncher
. Depends on answer to 1.
pa...@google.com <pa...@google.com>
ap...@google.com <ap...@google.com> #8
Branch: androidx-main
commit ce81b84e699a64e9538bb57d3dcdf25fdd5151c1
Author: Jelle Fresen <jellefresen@google.com>
Date: Tue Jan 19 18:44:09 2021
Use ComposeTestRule without launching Activity
The factory method createEmptyComposeRule has been added that creates an
AndroidComposeTestRule that does not start any Activity. To make sure
one can't call setContent (which uses the started Activity) on that test
rule, the ComposeTestRule interface has been split into ComposeTestRule
and ComposeContentTestRule, with the latter containing setContent and
the former containing all the other methods. createEmptyComposeRule's
return type is ComposeTestRule, without setContent.
Fixes: 174472899
Test: Added LateActivityLaunchTest
Relnote: "Introduced `ComposeContentTestRule`, which extends
`ComposeTestRule` and defines `setContent`, which has been removed from
`ComposeTestRule`. Added a factory method `createEmptyComposeRule()`
that returns a `ComposeTestRule` and does not launch an Activity for
you. Use this when you want to launch your Activity during your test,
e.g. using `ActivityScenario.launch`"
Change-Id: I9d78283c27d87a3135071884e115bbd814492c47
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/FoundationTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldScrollTest.kt
M compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerScreenshotTest.kt
M compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialRippleThemeTest.kt
M compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MaterialTest.kt
M compose/ui/ui-test-junit4/api/current.txt
M compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt
M compose/ui/ui-test-junit4/api/restricted_current.txt
M compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/FirstDrawTest.kt
A compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/LateActivityLaunchTest.kt
M compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.kt
M compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/StateRestorationTester.kt
M compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/DesktopComposeTestRule.kt
M compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule.kt
M compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusTestUtils.kt
Description
Jetpack Compose release version: Snapshot 6995125 Android Studio Build: n/a
See update to Alpha08 in Crane:https://github.com/android/compose-samples/pull/298/files#diff-b10b1fb51606b96175c832427089cc3f024a536153eab5cdbb95e4a7bb273b7cR60-R74
The
AndroidComposeTestRule
class has been changed in Alpha08, and it now needs anactivityProvider
parameter. That requires quite some boilerplate, asActivityScenarioRule.getActivity()
is private (AndroidComposeTestRule.kt line 311), and so the consumer has to copy that implementation.