@@ -16,7 +16,9 @@ import androidx.compose.ui.platform.LocalDensity
1616import androidx.compose.ui.test.assert
1717import androidx.compose.ui.test.onNodeWithContentDescription
1818import androidx.compose.ui.test.onNodeWithText
19+ import androidx.compose.ui.test.onRoot
1920import androidx.compose.ui.test.performClick
21+ import androidx.compose.ui.test.printToString
2022import androidx.compose.ui.unit.dp
2123import androidx.test.core.app.ApplicationProvider
2224import com.bumptech.glide.Glide
@@ -37,6 +39,9 @@ import java.util.concurrent.atomic.AtomicInteger
3739import java.util.concurrent.atomic.AtomicReference
3840import org.junit.Rule
3941import org.junit.Test
42+ import org.mockito.kotlin.any
43+ import org.mockito.kotlin.mock
44+ import org.mockito.kotlin.verify
4045
4146class GlideImageTest {
4247 private val context: Context = ApplicationProvider .getApplicationContext()
@@ -64,7 +69,7 @@ class GlideImageTest {
6469 GlideImage (
6570 model = resourceId,
6671 contentDescription = description,
67- modifier = Modifier .size(300 .dp, 300 .dp)
72+ modifier = Modifier .size(300 .dp, 300 .dp),
6873 )
6974 }
7075
@@ -95,7 +100,7 @@ class GlideImageTest {
95100 GlideImage (
96101 model = model.value,
97102 modifier = Modifier .size(100 .dp),
98- contentDescription = description
103+ contentDescription = description,
99104 )
100105 }
101106 }
@@ -119,7 +124,7 @@ class GlideImageTest {
119124 model = android.R .drawable.star_big_on,
120125 requestBuilderTransform = { it.fitCenter() },
121126 contentDescription = description,
122- modifier = Modifier .size(viewDimension.dp, viewDimension.dp)
127+ modifier = Modifier .size(viewDimension.dp, viewDimension.dp),
123128 )
124129
125130 with (LocalDensity .current) {
@@ -161,68 +166,47 @@ class GlideImageTest {
161166 val description = " test"
162167 glideComposeRule.setContent {
163168 Box (modifier = Modifier .size(0 .dp)) {
164- GlideImage (
165- model = android.R .drawable.star_big_on,
166- contentDescription = description,
167- )
169+ GlideImage (model = android.R .drawable.star_big_on, contentDescription = description)
168170 }
169171 }
170172 glideComposeRule.waitForIdle()
171- glideComposeRule
172- .onNodeWithContentDescription(description)
173- .assertDisplays(null )
173+ glideComposeRule.onNodeWithContentDescription(description).assertDisplays(null )
174174 }
175175
176-
177176 @Test
178177 fun glideImage_withNegativeSize_doesNotStartLoad () {
179178 val description = " test"
180179 glideComposeRule.setContent {
181180 Box (modifier = Modifier .size((- 10 ).dp)) {
182- GlideImage (
183- model = android.R .drawable.star_big_on,
184- contentDescription = description,
185- )
181+ GlideImage (model = android.R .drawable.star_big_on, contentDescription = description)
186182 }
187183 }
188184 glideComposeRule.waitForIdle()
189- glideComposeRule
190- .onNodeWithContentDescription(description)
191- .assertDisplays(null )
185+ glideComposeRule.onNodeWithContentDescription(description).assertDisplays(null )
192186 }
193187
194188 @Test
195189 fun glideImage_withZeroWidth_validHeight_doesNotStartLoad () {
196190 val description = " test"
197191 glideComposeRule.setContent {
198192 Box (modifier = Modifier .size(0 .dp, 10 .dp)) {
199- GlideImage (
200- model = android.R .drawable.star_big_on,
201- contentDescription = description,
202- )
193+ GlideImage (model = android.R .drawable.star_big_on, contentDescription = description)
203194 }
204195 }
205196 glideComposeRule.waitForIdle()
206- glideComposeRule
207- .onNodeWithContentDescription(description)
208- .assertDisplays(null )
197+ glideComposeRule.onNodeWithContentDescription(description).assertDisplays(null )
209198 }
210199
211200 @Test
212201 fun glideImage_withValidWidth_zeroHeight_doesNotStartLoad () {
213202 val description = " test"
214203 glideComposeRule.setContent {
215204 Box (modifier = Modifier .size(10 .dp, 0 .dp)) {
216- GlideImage (
217- model = android.R .drawable.star_big_on,
218- contentDescription = description,
219- )
205+ GlideImage (model = android.R .drawable.star_big_on, contentDescription = description)
220206 }
221207 }
222208 glideComposeRule.waitForIdle()
223- glideComposeRule
224- .onNodeWithContentDescription(description)
225- .assertDisplays(null )
209+ glideComposeRule.onNodeWithContentDescription(description).assertDisplays(null )
226210 }
227211
228212 @Test
@@ -238,10 +222,7 @@ class GlideImageTest {
238222
239223 TextButton (onClick = ::swapSize) { Text (text = " Swap" ) }
240224 Box (modifier = Modifier .size(currentSize.value)) {
241- GlideImage (
242- model = resourceId,
243- contentDescription = description,
244- )
225+ GlideImage (model = resourceId, contentDescription = description)
245226 }
246227 }
247228 glideComposeRule.waitForIdle()
@@ -268,10 +249,7 @@ class GlideImageTest {
268249
269250 TextButton (onClick = ::swapSize) { Text (text = " Swap" ) }
270251 Box (modifier = Modifier .size(currentSize.value)) {
271- GlideImage (
272- model = resourceId,
273- contentDescription = description,
274- )
252+ GlideImage (model = resourceId, contentDescription = description)
275253 }
276254 }
277255 repeat(validSizeDps.size) {
@@ -291,28 +269,29 @@ class GlideImageTest {
291269 @Test
292270 fun glideImage_withSuccessfulResource_callsOnResourceReadyOnce () {
293271 val onResourceReadyCounter = AtomicInteger ()
294- val requestListener = object : RequestListener <Drawable > {
295- override fun onLoadFailed (
296- e : GlideException ? ,
297- model : Any? ,
298- target : Target <Drawable >? ,
299- isFirstResource : Boolean ,
300- ): Boolean {
301- throw UnsupportedOperationException ()
272+ val requestListener =
273+ object : RequestListener <Drawable > {
274+ override fun onLoadFailed (
275+ e : GlideException ? ,
276+ model : Any? ,
277+ target : Target <Drawable >? ,
278+ isFirstResource : Boolean ,
279+ ): Boolean {
280+ throw UnsupportedOperationException ()
281+ }
282+
283+ override fun onResourceReady (
284+ resource : Drawable ? ,
285+ model : Any? ,
286+ target : Target <Drawable >? ,
287+ dataSource : DataSource ? ,
288+ isFirstResource : Boolean ,
289+ ): Boolean {
290+ onResourceReadyCounter.incrementAndGet()
291+ return false
292+ }
302293 }
303294
304- override fun onResourceReady (
305- resource : Drawable ? ,
306- model : Any? ,
307- target : Target <Drawable >? ,
308- dataSource : DataSource ? ,
309- isFirstResource : Boolean ,
310- ): Boolean {
311- onResourceReadyCounter.incrementAndGet()
312- return false
313- }
314- }
315-
316295 glideComposeRule.setContent {
317296 GlideImage (model = android.R .drawable.star_big_on, contentDescription = " " ) {
318297 it.listener(requestListener)
@@ -323,4 +302,31 @@ class GlideImageTest {
323302
324303 assertThat(onResourceReadyCounter.get()).isEqualTo(1 )
325304 }
305+
306+ @Test
307+ fun glideImage_loadImageFromFile_callsOnImageVisibleToUser () {
308+ val onImageVisibleToUser = mock< (Drawable ) -> Unit > ()
309+
310+ glideComposeRule.setContent {
311+ GlideImage (
312+ model = android.R .drawable.star_big_on,
313+ contentDescription = " star" ,
314+ onImageVisibleToUser = onImageVisibleToUser,
315+ )
316+ }
317+ glideComposeRule.waitUntilContentDescriptionWithinRootNode(" star" )
318+
319+ verify(onImageVisibleToUser).invoke(any())
320+ }
321+
322+ private fun GlideComposeRule.waitUntilContentDescriptionWithinRootNode (
323+ contentDescription : String
324+ ) {
325+ waitUntil(
326+ conditionDescription = " waitUntilContentDescriptionWithinRootNode" ,
327+ timeoutMillis = 10000 ,
328+ ) {
329+ onRoot(useUnmergedTree = false ).printToString().contains(contentDescription)
330+ }
331+ }
326332}
0 commit comments