-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enhancement - Add support for text color checking
- Loading branch information
Evgeny Meltsaykin
committed
Dec 17, 2023
1 parent
76e304f
commit bdd1913
Showing
11 changed files
with
306 additions
and
41 deletions.
There are no files selected for viewing
93 changes: 93 additions & 0 deletions
93
compose/src/main/kotlin/io/github/kakaocup/compose/node/assertion/TextColorAssertions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package io.github.kakaocup.compose.node.assertion | ||
|
||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.graphics.isSpecified | ||
import androidx.compose.ui.semantics.SemanticsActions | ||
import androidx.compose.ui.semantics.SemanticsNode | ||
import androidx.compose.ui.semantics.SemanticsProperties | ||
import androidx.compose.ui.semantics.SemanticsPropertyKey | ||
import androidx.compose.ui.semantics.getOrNull | ||
import androidx.compose.ui.test.SemanticsMatcher | ||
import androidx.compose.ui.test.assert | ||
import androidx.compose.ui.text.TextLayoutResult | ||
import io.github.kakaocup.compose.utilities.ColorAssertionsUtils | ||
|
||
interface TextColorAssertions : NodeAssertions { | ||
val textColorSemanticsPropertyKey: SemanticsPropertyKey<Color> | ||
|
||
/** | ||
* Asserts that the text color contains the given [color]. | ||
* | ||
* Throws [AssertionError] if the text color value is not equal to `color`. | ||
* Throws [IllegalStateException] if the compose view does not contain the [textColorSemanticsPropertyKey] modifier. | ||
*/ | ||
fun assertTextColorEquals(color: Color) { | ||
delegate.check(NodeAssertions.ComposeBaseAssertionType.ASSERT_VALUE_EQUALS) { | ||
assert(hasTextColor(color)) | ||
} | ||
} | ||
|
||
/** | ||
* Asserts that text color contains the given [color]. | ||
* | ||
* Throws [AssertionError] if the text color value is not equal to `color`. | ||
* Throws [IllegalStateException] if the compose view does not contain the [textColorSemanticsPropertyKey] modifier. | ||
* Throws [IllegalArgumentException] if the color value is incorrect. | ||
*/ | ||
fun assertTextColorEquals(color: String) { | ||
delegate.check(NodeAssertions.ComposeBaseAssertionType.ASSERT_VALUE_EQUALS) { | ||
assert(hasTextColor(color)) | ||
} | ||
} | ||
|
||
/** | ||
* Asserts that the text color contains the given [color]. | ||
* | ||
* Throws [AssertionError] if the text color value is not equal to `color`. | ||
* Throws [IllegalStateException] if the compose view does not contain the [textColorSemanticsPropertyKey] modifier. | ||
*/ | ||
fun assertTextColorEquals(color: Long) { | ||
delegate.check(NodeAssertions.ComposeBaseAssertionType.ASSERT_VALUE_EQUALS) { | ||
assert(hasTextColor(color)) | ||
} | ||
} | ||
|
||
private fun hasTextColor(expectedColor: Color): SemanticsMatcher = SemanticsMatcher( | ||
"${SemanticsProperties.Text.name} is of color '$expectedColor'" | ||
) { node -> | ||
return@SemanticsMatcher node.hasTextColor(expectedColor = expectedColor) | ||
} | ||
|
||
private fun hasTextColor(expectedColor: Long): SemanticsMatcher = SemanticsMatcher( | ||
"${SemanticsProperties.Text.name} is of color '$expectedColor'" | ||
) { node -> | ||
return@SemanticsMatcher node.hasTextColor(expectedColor = Color(expectedColor)) | ||
} | ||
|
||
private fun hasTextColor(expectedColor: String): SemanticsMatcher = SemanticsMatcher( | ||
"${SemanticsProperties.Text.name} is of color '$expectedColor'" | ||
) { node -> | ||
return@SemanticsMatcher node.hasTextColor(expectedColor = ColorAssertionsUtils.getComposeColor(expectedColor)) | ||
} | ||
|
||
private fun SemanticsNode.hasTextColor(expectedColor: Color): Boolean { | ||
val textLayoutResults = mutableListOf<TextLayoutResult>() | ||
config.getOrNull(SemanticsActions.GetTextLayoutResult)?.action?.invoke(textLayoutResults) | ||
|
||
val actualColorOfStyle = textLayoutResults.firstOrNull()?.layoutInput?.style?.color ?: Color.Unspecified | ||
val actualColorOfSemantic = config.getOrNull(textColorSemanticsPropertyKey) ?: Color.Unspecified | ||
|
||
/** | ||
* look at how the overrideColor parameter is used | ||
* @see [androidx.compose.foundation.text.modifiers.TextStringSimpleNode.draw] | ||
* @see [androidx.compose.foundation.text.modifiers.TextAnnotatedStringNode.draw] | ||
*/ | ||
val actualColor = when { | ||
actualColorOfSemantic.isSpecified -> actualColorOfSemantic | ||
actualColorOfStyle.isSpecified -> actualColorOfStyle | ||
else -> Color.Black | ||
} | ||
|
||
return actualColor == expectedColor | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
compose/src/main/kotlin/io/github/kakaocup/compose/node/element/KTextNode.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package io.github.kakaocup.compose.node.element | ||
|
||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider | ||
import io.github.kakaocup.compose.node.assertion.TextColorAssertions | ||
import io.github.kakaocup.compose.node.builder.NodeMatcher | ||
import io.github.kakaocup.compose.node.core.BaseNode | ||
|
||
abstract class KTextNode( | ||
semanticsProvider: SemanticsNodeInteractionsProvider, | ||
nodeMatcher: NodeMatcher, | ||
parentNode: BaseNode<*>?, | ||
useUnmergedTree: Boolean = false | ||
) : BaseNode<KTextNode>( | ||
semanticsProvider = semanticsProvider, | ||
nodeMatcher = nodeMatcher.copy(useUnmergedTree = useUnmergedTree), | ||
parentNode = parentNode | ||
), TextColorAssertions |
40 changes: 40 additions & 0 deletions
40
compose/src/main/kotlin/io/github/kakaocup/compose/utilities/ColorAssertionsUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package io.github.kakaocup.compose.utilities | ||
|
||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.semantics.SemanticsPropertyKey | ||
import androidx.compose.ui.semantics.getOrNull | ||
import androidx.compose.ui.test.SemanticsMatcher | ||
|
||
internal object ColorAssertionsUtils { | ||
fun hasColor(expectedColor: Color, semanticsPropertyKey: SemanticsPropertyKey<*>): SemanticsMatcher = SemanticsMatcher( | ||
"The color is expected to be $expectedColor, but the actual color is different" | ||
) { node -> | ||
val actualColor = node.config.getOrNull(semanticsPropertyKey) | ||
?: error("Compose view does not contain $semanticsPropertyKey modifier") | ||
|
||
return@SemanticsMatcher actualColor == expectedColor | ||
} | ||
|
||
fun hasColor(expectedColor: String, semanticsPropertyKey: SemanticsPropertyKey<*>): SemanticsMatcher = SemanticsMatcher( | ||
"The color is expected to be $expectedColor, but the actual color is different" | ||
) { node -> | ||
val actualColor = node.config.getOrNull(semanticsPropertyKey) | ||
?: error("Compose view does not contain $semanticsPropertyKey modifier") | ||
|
||
return@SemanticsMatcher actualColor == getComposeColor(expectedColor) | ||
} | ||
|
||
fun hasColor(expectedColor: Long, semanticsPropertyKey: SemanticsPropertyKey<*>): SemanticsMatcher = SemanticsMatcher( | ||
"The color is expected to be $expectedColor, but the actual color is different" | ||
) { node -> | ||
val actualColor = node.config.getOrNull(semanticsPropertyKey) | ||
?: error("Compose view does not contain $semanticsPropertyKey modifier") | ||
|
||
return@SemanticsMatcher actualColor == Color(expectedColor) | ||
} | ||
|
||
fun getComposeColor(color: String): Color { | ||
val colorString = if (color.contains("#")) color else "#$color" | ||
return Color(android.graphics.Color.parseColor(colorString)) | ||
} | ||
} |
8 changes: 0 additions & 8 deletions
8
compose/src/main/kotlin/io/github/kakaocup/compose/utilities/ColorUtils.kt
This file was deleted.
Oops, something went wrong.
22 changes: 22 additions & 0 deletions
22
sample/src/androidTest/java/io/github/kakaocup/compose/node/KAppTextNode.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package io.github.kakaocup.compose.node | ||
|
||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.semantics.SemanticsPropertyKey | ||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider | ||
import io.github.kakaocup.compose.node.builder.NodeMatcher | ||
import io.github.kakaocup.compose.node.core.BaseNode | ||
import io.github.kakaocup.compose.node.element.KTextNode | ||
import io.github.kakaocup.compose.sample.semantics.TextColorSemanticKey | ||
|
||
class KAppTextNode( | ||
semanticsProvider: SemanticsNodeInteractionsProvider, | ||
nodeMatcher: NodeMatcher, | ||
parentNode: BaseNode<*>? = null, | ||
) : KTextNode( | ||
semanticsProvider = semanticsProvider, | ||
nodeMatcher = nodeMatcher, | ||
parentNode = parentNode, | ||
useUnmergedTree = true | ||
) { | ||
override val textColorSemanticsPropertyKey: SemanticsPropertyKey<Color> = TextColorSemanticKey | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.