1 /* 2 * Copyright 2020 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 */ 16 17 package androidx.lifecycle 18 19 import androidx.kruth.assertWithMessage 20 import androidx.testutils.lifecycle.FakeLifecycleOwner 21 import kotlin.test.Test 22 import kotlin.test.assertEquals 23 import kotlin.test.assertFailsWith 24 import kotlinx.coroutines.async 25 import kotlinx.coroutines.launch 26 import kotlinx.coroutines.yield 27 28 class WithLifecycleStateTest { 29 @Test <lambda>null30 fun testInitialResumed() = runLifecycleTest { 31 val owner = FakeLifecycleOwner(Lifecycle.State.RESUMED) 32 33 val expected = "initial value" 34 var toRead = expected 35 launch { toRead = "value set by launch" } 36 val readByWithStarted = owner.withStarted { toRead } 37 assertEquals(expected, readByWithStarted) 38 } 39 40 @Test <lambda>null41 fun testBlockRunsWithLifecycleStateChange() = runLifecycleTest { 42 val owner = FakeLifecycleOwner() 43 44 val initial = "initial value" 45 val afterSetState = "value set after setState" 46 var toRead = initial 47 launch { 48 owner.setState(Lifecycle.State.RESUMED) 49 toRead = afterSetState 50 } 51 val readByWithStarted = owner.withStarted { toRead } 52 val readAfterResumed = toRead 53 assertEquals(initial, readByWithStarted) 54 assertEquals(afterSetState, readAfterResumed) 55 } 56 57 @Test <lambda>null58 fun testBlockCancelledWhenInitiallyDestroyed() = runLifecycleTest { 59 val owner = FakeLifecycleOwner(Lifecycle.State.CREATED) 60 owner.setState(Lifecycle.State.DESTROYED) 61 62 assertFailsWith<LifecycleDestroyedException> { owner.withStarted {} } 63 } 64 65 @Test <lambda>null66 fun testBlockCancelledWhenDestroyedWhileSuspended() = runLifecycleTest { 67 val owner = FakeLifecycleOwner(Lifecycle.State.CREATED) 68 69 var launched = false 70 val resultTask = async { 71 launched = true 72 runCatching { owner.withStarted {} } 73 } 74 yield() 75 76 assertWithMessage("test ran to first suspension after successfully launching") 77 .that(launched) 78 .isTrue() 79 assertWithMessage("withStarted is still active").that(resultTask.isActive).isTrue() 80 81 owner.setState(Lifecycle.State.DESTROYED) 82 83 assertWithMessage("result threw LifecycleDestroyedException") 84 .that(resultTask.await().exceptionOrNull()) 85 .isInstanceOf<LifecycleDestroyedException>() 86 } 87 } 88