-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce support for rendering Compose hierarchies. #33
Conversation
sample-compose/src/main/java/com/squareup/radiography/sample/compose/ComposeSampleApp.kt
Outdated
Show resolved
Hide resolved
1072f37
to
37a7160
Compare
3a9e450
to
e41fece
Compare
e41fece
to
51b59cc
Compare
Just rewrote and simplified all the analysis code, polished up the API and documentation, and added tests. This is ready for review. |
|
||
// Note that this class can't use viewStateRendererFor, since that function is defined in the | ||
// ViewStateRenderers object, whose class initializer may initialize _this_ class, which will cause | ||
// NoClassDefFoundExceptions. This can happen when a debugger is attached. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what fresh hell is this? Are you saying that if ComposeLayoutRenderers uses a function defined in ViewStateRenderers, then when loading ViewStateRenderers the classloader may also also load ComposeLayoutRenderers? If yes, something's wrong with the compiler..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, why would initializing this class cause NoClassDefFoundExceptions ? Looks like everything here has if (!isComposeAvailable) NoRenderer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My response too. Doesn't happen normally, only happens when the debugger was connected and about to stop at a breakpoint that involved ViewStateRenderers.
The NoClassDef wasn't for compose, it was for this class, because of the circular ref. VSR starts initializing, asks this class for its defaults, this class starts initializing, which calls functions on VSR which require that class to be loaded, but it's already in the process of initializing.
I'm not sure why this wasn't happening unless the debugger was connected. Anyway a better solution might just be to make the VSR.Defaults* fields initialize lazily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tracked: #59.
SemanticsProperties.Focused -> if (value == true) append("FOCUSED") | ||
SemanticsProperties.Hidden -> append("HIDDEN") | ||
SemanticsProperties.IsDialog -> append("DIALOG") | ||
SemanticsProperties.IsPopup -> append("POPUP") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why all the uppercase yelling :) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just more consistent with the output for classic views (e.g. GONE
).
*/ | ||
@ExperimentalRadiographyComposeApi | ||
@JvmSynthetic | ||
fun SlotTable.scan( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's a use case for using this public API directly? Since we're saying "you probably want scan instead", would be interesting to also mention why you'd want this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent question. The only use case I had for it at all was getting rid of noise from Android views in some of the UI tests. I justified making this public because the SlotTable type is so burried in the Compose API anyway that I doubt anyone would ever even see this. And if they did, they're obviously doing something weird and low-level enough that it might be useful to scan the table directly.
Having said that out loud, the warning in the kdoc seems unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another solution to this problem, which would be much more useful for devs, would be the ability to start the scan at some point further down in the tree, similar to passing a non-root View to scan(). However that presents a few (solvable) issues:
- Composables don't have any implicit identity, so we'd probably need to do something like for filtering and use test tags or layout IDs to identify the root.
- The visitor infra doesn't currently support filtering nodes above, only below, so that would have to be implemented. This could also make it possible to visit Groups directly instead of using the intermediate LayoutInfo type - I'm not sure we should, since that type lets us decouple a bit from compose APIs that might change a lot, but we'd have the option.
Having thought about this more, that API makes much more sense than this one. I'll take a stab at implementing it, but would like to not block this PR on it since this API is marked as unstable anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tracked: #58.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might eventually end up re-introducing this API, although I'm still for dropping it for now: #61
compose-tests/src/androidTest/java/radiography/test/compose/ComposeUiTest.kt
Show resolved
Hide resolved
I want to add at least one more thing, although I could do it as a follow-up. We should have integration tests that try use different versions of compose so we can validate that this library doesn't crash when a consumer updates their compose version without updating this library. Just because we can load one or two classes doesn't mean the rest of the classes will be what we expect, and we should degrade gracefully. Update: Added test and guards in this PR. |
51b59cc
to
1354b17
Compare
1354b17
to
0d9cf52
Compare
@@ -0,0 +1,132 @@ | |||
package radiography.compose |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of missing copyright blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not adding copyright blocks to new files in this repo. It's not actually required for Apache 2.0, and it's been a huge pain in the ass to keep adding them in Workflow. Anvil isn't doing this either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't say I read this as closely as I should, but since it's a WIP anyway…
I've got two approvals, and stuff is stacking up on top of this, so I'm going to go ahead and merge. Filed issues for the comments that need follow-up. |
Whoa! Does that mean I can rip them out of workflow?
…On Fri, Aug 21, 2020, 5:53 PM Zach Klippenstein ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In radiography/src/main/java/radiography/compose/ComposeLayoutRenderers.kt
<#33 (comment)>:
> @@ -0,0 +1,132 @@
+package radiography.compose
We are not adding copyright blocks to new files in this repo. It's not
actually required for Apache 2.0, and it's been a huge pain in the ass to
keep adding them in Workflow. Anvil isn't doing this either.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#33 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAOMCHNNTKZKSXQUCXAESQLSB4JJVANCNFSM4P33MBJA>
.
|
Based on #53.
The API could probably use some improvement, but it is very low-impact and all the Compose stuff is completely invisible if you're not using Compose, and automatic if you start using it. Where the View API lets you render and filter
View
s, the Compose API lets you renderModifier
s (including semantics, which is how Compose expresses accessibility and testing metadata), and filter by specific types of metadata:Modifier.testTag
andModifier.layoutId
.The output looks like this:
Added a live-updating view of the hierarchy directly in the sample screen.