Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- (Jetpack Compose) Modifier.sentryTag now uses Modifier.Node ([#4029](https://github.com/getsentry/sentry-java/pull/4029))

## 7.21.0-beta.1

### Fixes
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/java/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ object Config {
val javaFaker = "com.github.javafaker:javafaker:1.0.2"
val msgpack = "org.msgpack:msgpack-core:0.9.8"
val leakCanaryInstrumentation = "com.squareup.leakcanary:leakcanary-android-instrumentation:2.14"
val composeUiTestJunit4 = "androidx.compose.ui:ui-test-junit4:$composeVersion"
val composeUiTestManifest = "androidx.compose.ui:ui-test-manifest:$composeVersion"
}

object QualityPlugins {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ dependencies {
implementation(Config.TestLibs.espressoIdlingResource)
implementation(Config.Libs.leakCanary)

androidTestImplementation(Config.TestLibs.composeUiTestJunit4)
debugImplementation(Config.TestLibs.composeUiTestManifest)

compileOnly(Config.CompileOnly.nopen)
errorprone(Config.CompileOnly.nopenChecker)
errorprone(Config.CompileOnly.errorprone)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.sentry.uitest.android

import androidx.compose.foundation.layout.Box
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.sentry.compose.SentryModifier
import io.sentry.compose.SentryModifier.sentryTag
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class SentryModifierComposeTest : BaseUiTest() {

companion object {
private const val TAG_VALUE = "ExampleTagValue"
}

@get:Rule
val rule = createComposeRule()

@Test
fun sentryModifierAppliesTag() {
rule.setContent {
Box(modifier = Modifier.sentryTag(TAG_VALUE))
}
rule.onNode(
SemanticsMatcher(TAG_VALUE) {
it.config.find { (key, _) -> key.name == SentryModifier.TAG }?.value == TAG_VALUE
}
).assertExists()
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package io.sentry.compose

import androidx.compose.ui.Modifier
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.SemanticsModifierNode
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.semantics.SemanticsConfiguration
import androidx.compose.ui.semantics.SemanticsModifier
import androidx.compose.ui.semantics.SemanticsPropertyKey
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.SemanticsPropertyReceiver

public object SentryModifier {

Expand All @@ -19,11 +24,35 @@ public object SentryModifier {
)

@JvmStatic
public fun Modifier.sentryTag(tag: String): Modifier {
return semantics(
properties = {
this[SentryTag] = tag
public fun Modifier.sentryTag(tag: String): Modifier =
this then SentryTagModifierNodeElement(tag)

private data class SentryTagModifierNodeElement(val tag: String) :
ModifierNodeElement<SentryTagModifierNode>(), SemanticsModifier {

override val semanticsConfiguration: SemanticsConfiguration =
SemanticsConfiguration().also {
it[SentryTag] = tag
}
)

override fun create(): SentryTagModifierNode = SentryTagModifierNode(tag)

override fun update(node: SentryTagModifierNode) {
node.tag = tag
}

override fun InspectorInfo.inspectableProperties() {
name = "sentryTag"
properties["tag"] = tag
}
}

private class SentryTagModifierNode(var tag: String) :
Modifier.Node(),
SemanticsModifierNode {

override fun SemanticsPropertyReceiver.applySemantics() {
this[SentryTag] = tag
}
}
}