[go: nahoru, domu]

blob: cbff0c7c5c7e365b8287dc4cf8e52cdff182d0d6 [file] [log] [blame]
Connie Shi69897da2021-10-08 14:59:36 -04001/*
2 * Copyright 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package androidx.compose.material3
17
18import android.os.Build
19import androidx.compose.foundation.layout.size
20import androidx.compose.material.icons.Icons
21import androidx.compose.material.icons.filled.Favorite
Mariano Martin49ce2172022-01-11 16:27:06 -050022import androidx.compose.material3.tokens.BadgeTokens
Connie Shi69897da2021-10-08 14:59:36 -040023import androidx.compose.testutils.assertShape
24import androidx.compose.ui.Modifier
25import androidx.compose.ui.graphics.Color
26import androidx.compose.ui.platform.testTag
27import androidx.compose.ui.semantics.contentDescription
28import androidx.compose.ui.semantics.semantics
29import androidx.compose.ui.test.assertContentDescriptionEquals
30import androidx.compose.ui.test.assertHeightIsEqualTo
31import androidx.compose.ui.test.assertPositionInRootIsEqualTo
32import androidx.compose.ui.test.assertWidthIsAtLeast
33import androidx.compose.ui.test.assertWidthIsEqualTo
34import androidx.compose.ui.test.captureToImage
35import androidx.compose.ui.test.getUnclippedBoundsInRoot
36import androidx.compose.ui.test.junit4.createComposeRule
37import androidx.compose.ui.test.onNodeWithTag
38import androidx.compose.ui.test.onSibling
39import androidx.compose.ui.unit.dp
40import androidx.compose.ui.unit.height
41import androidx.compose.ui.unit.max
42import androidx.compose.ui.unit.width
43import androidx.test.ext.junit.runners.AndroidJUnit4
44import androidx.test.filters.LargeTest
45import androidx.test.filters.SdkSuppress
46import org.junit.Rule
47import org.junit.Test
48import org.junit.runner.RunWith
49
50@LargeTest
51@RunWith(AndroidJUnit4::class)
52class BadgeTest {
53
54 private val icon = Icons.Filled.Favorite
55
56 @get:Rule
57 val rule = createComposeRule()
58
59 @Test
60 fun badge_noContent_size() {
61 rule
62 .setMaterialContentForSizeAssertions {
63 Badge()
64 }
Mariano Martin49ce2172022-01-11 16:27:06 -050065 .assertHeightIsEqualTo(BadgeTokens.Size)
66 .assertWidthIsEqualTo(BadgeTokens.Size)
Connie Shi69897da2021-10-08 14:59:36 -040067 }
68
69 @Test
70 fun badge_shortContent_size() {
71 rule
72 .setMaterialContentForSizeAssertions {
73 Badge { Text("1") }
74 }
Mariano Martin49ce2172022-01-11 16:27:06 -050075 .assertHeightIsEqualTo(BadgeTokens.LargeSize)
76 .assertWidthIsEqualTo(BadgeTokens.LargeSize)
Connie Shi69897da2021-10-08 14:59:36 -040077 }
78
79 @Test
80 fun badge_longContent_size() {
81 rule
82 .setMaterialContentForSizeAssertions {
83 Badge { Text("999+") }
84 }
Mariano Martin49ce2172022-01-11 16:27:06 -050085 .assertHeightIsEqualTo(BadgeTokens.LargeSize)
86 .assertWidthIsAtLeast(BadgeTokens.LargeSize)
Connie Shi69897da2021-10-08 14:59:36 -040087 }
88
89 @Test
90 fun badge_shortContent_customSizeModifier_size() {
91 val customWidth = 24.dp
92 val customHeight = 6.dp
93 rule
94 .setMaterialContentForSizeAssertions {
95 Badge(modifier = Modifier.size(customWidth, customHeight)) {
96 Text("1")
97 }
98 }
99 .assertHeightIsEqualTo(customHeight)
100 .assertWidthIsEqualTo(customWidth)
101 }
102
103 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
104 @Test
105 fun badge_noContent_shape() {
106 var errorColor = Color.Unspecified
Shalom Gibly7d59ffd2021-12-16 15:58:06 -0800107 rule.setMaterialContent(lightColorScheme()) {
Mariano Martin49ce2172022-01-11 16:27:06 -0500108 errorColor = MaterialTheme.colorScheme.fromToken(BadgeTokens.Color)
Connie Shi69897da2021-10-08 14:59:36 -0400109 Badge(modifier = Modifier.testTag(TestBadgeTag))
110 }
111
112 rule.onNodeWithTag(TestBadgeTag)
113 .captureToImage()
114 .assertShape(
115 density = rule.density,
Mariano Martin49ce2172022-01-11 16:27:06 -0500116 shape = BadgeTokens.Shape,
Connie Shi69897da2021-10-08 14:59:36 -0400117 shapeColor = errorColor,
118 backgroundColor = Color.White,
119 shapeOverlapPixelCount = with(rule.density) { 1.dp.toPx() }
120 )
121 }
122
123 @Test
124 fun badgeBox_noContent_position() {
125 rule
Shalom Gibly7d59ffd2021-12-16 15:58:06 -0800126 .setMaterialContent(lightColorScheme()) {
Connie Shi69897da2021-10-08 14:59:36 -0400127 BadgedBox(badge = { Badge(Modifier.testTag(TestBadgeTag)) }) {
128 Icon(
129 icon,
130 null,
131 modifier = Modifier.testTag(TestAnchorTag)
132 )
133 }
134 }
135 val badge = rule.onNodeWithTag(TestBadgeTag)
136 val anchorBounds = rule.onNodeWithTag(TestAnchorTag).getUnclippedBoundsInRoot()
137 val badgeBounds = badge.getUnclippedBoundsInRoot()
138 badge.assertPositionInRootIsEqualTo(
139 expectedLeft =
Shalom Gibly7d59ffd2021-12-16 15:58:06 -0800140 anchorBounds.right + BadgeOffset +
Mariano Martin49ce2172022-01-11 16:27:06 -0500141 max((BadgeTokens.Size - badgeBounds.width) / 2, 0.dp),
Connie Shi69897da2021-10-08 14:59:36 -0400142 expectedTop = -badgeBounds.height / 2
143 )
144 }
145
146 @Test
147 fun badgeBox_shortContent_position() {
148 rule
Shalom Gibly7d59ffd2021-12-16 15:58:06 -0800149 .setMaterialContent(lightColorScheme()) {
Connie Shi69897da2021-10-08 14:59:36 -0400150 BadgedBox(badge = { Badge { Text("8") } }) {
151 Icon(
152 icon,
153 null,
154 modifier = Modifier.testTag(TestAnchorTag)
155 )
156 }
157 }
158 val badge = rule.onNodeWithTag(TestAnchorTag).onSibling()
159 val anchorBounds = rule.onNodeWithTag(TestAnchorTag).getUnclippedBoundsInRoot()
160 val badgeBounds = badge.getUnclippedBoundsInRoot()
161 badge.assertPositionInRootIsEqualTo(
162 expectedLeft = anchorBounds.right + BadgeWithContentHorizontalOffset + max
Shalom Gibly7d59ffd2021-12-16 15:58:06 -0800163 (
Connie Shi69897da2021-10-08 14:59:36 -0400164 (
Mariano Martin49ce2172022-01-11 16:27:06 -0500165 BadgeTokens.LargeSize - badgeBounds.width
Connie Shi69897da2021-10-08 14:59:36 -0400166 ) / 2,
167 0.dp
168 ),
169 expectedTop = -badgeBounds.height / 2 + BadgeWithContentVerticalOffset
170 )
171 }
172
173 @Test
174 fun badgeBox_longContent_position() {
175 rule
Shalom Gibly7d59ffd2021-12-16 15:58:06 -0800176 .setMaterialContent(lightColorScheme()) {
Connie Shi69897da2021-10-08 14:59:36 -0400177 BadgedBox(badge = { Badge { Text("999+") } }) {
178 Icon(
179 icon,
180 null,
181 modifier = Modifier.testTag(TestAnchorTag)
182 )
183 }
184 }
185 val badge = rule.onNodeWithTag(TestAnchorTag).onSibling()
186 val anchorBounds = rule.onNodeWithTag(TestAnchorTag).getUnclippedBoundsInRoot()
187 val badgeBounds = badge.getUnclippedBoundsInRoot()
188
189 val totalBadgeHorizontalOffset = BadgeWithContentHorizontalOffset +
190 BadgeWithContentHorizontalPadding
191 badge.assertPositionInRootIsEqualTo(
192 expectedLeft = anchorBounds.right + totalBadgeHorizontalOffset,
193 expectedTop = -badgeBounds.height / 2 + BadgeWithContentVerticalOffset
194 )
195 }
196
197 @Test
198 fun badge_notMergingDescendants_withOwnContentDescription() {
Shalom Gibly7d59ffd2021-12-16 15:58:06 -0800199 rule.setMaterialContent(lightColorScheme()) {
Connie Shi69897da2021-10-08 14:59:36 -0400200 BadgedBox(
201 badge = {
202 Badge { Text("99+") }
203 },
204 modifier = Modifier.testTag(TestBadgeTag).semantics {
205 this.contentDescription = "more than 99 new email"
206 }
207 ) {
208 Text(
209 "inbox",
210 Modifier.semantics {
211 this.contentDescription = "inbox"
212 }.testTag(TestAnchorTag)
213 )
214 }
215 }
216
217 rule.onNodeWithTag(TestBadgeTag).assertContentDescriptionEquals("more than 99 new email")
218 rule.onNodeWithTag(TestAnchorTag).assertContentDescriptionEquals("inbox")
219 }
220
221 @Test
222 fun badgeBox_size() {
223 rule.setMaterialContentForSizeAssertions {
224 BadgedBox(badge = { Badge { Text("999+") } }) {
225 Icon(icon, null)
226 }
227 }
228 .assertWidthIsEqualTo(icon.defaultWidth)
229 .assertHeightIsEqualTo(icon.defaultHeight)
230 }
231}
232
233private const val TestBadgeTag = "badge"
234private const val TestAnchorTag = "anchor"