blob: c43f429842e17eacafab6cc6ee4316fb30db908b [file] [log] [blame]
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.fragment.app
import androidx.fragment.app.test.TestViewModel
import androidx.fragment.app.test.ViewModelActivity
import androidx.fragment.app.test.ViewModelActivity.ViewModelFragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@LargeTest
@RunWith(AndroidJUnit4::class)
class ViewModelTest {
@Test(expected = IllegalStateException::class)
@UiThreadTest
fun testNotAttachedFragment() {
// This is similar to calling getViewModelStore in Fragment's constructor
Fragment().viewModelStore
}
@Test
fun testSameActivityViewModels() {
with(ActivityScenario.launch(ViewModelActivity::class.java)) {
val activityModel = withActivity { activityModel }
val defaultActivityModel = withActivity { defaultActivityModel }
assertThat(defaultActivityModel).isNotSameInstanceAs(activityModel)
var fragment1 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_1) }
var fragment2 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_2) }
assertThat(fragment1).isNotNull()
assertThat(fragment2).isNotNull()
assertThat(fragment1.activityModel).isSameInstanceAs(activityModel)
assertThat(fragment2.activityModel).isSameInstanceAs(activityModel)
assertThat(fragment1.defaultActivityModel).isSameInstanceAs(defaultActivityModel)
assertThat(fragment2.defaultActivityModel).isSameInstanceAs(defaultActivityModel)
recreate()
assertThat(withActivity { activityModel }).isSameInstanceAs(activityModel)
assertThat(withActivity { defaultActivityModel }).isSameInstanceAs(defaultActivityModel)
fragment1 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_1) }
fragment2 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_2) }
assertThat(fragment1).isNotNull()
assertThat(fragment2).isNotNull()
assertThat(fragment1.activityModel).isSameInstanceAs(activityModel)
assertThat(fragment2.activityModel).isSameInstanceAs(activityModel)
assertThat(fragment1.defaultActivityModel).isSameInstanceAs(defaultActivityModel)
assertThat(fragment2.defaultActivityModel).isSameInstanceAs(defaultActivityModel)
}
}
@Test
fun testSameFragmentViewModels() {
with(ActivityScenario.launch(ViewModelActivity::class.java)) {
var fragment1 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_1) }
var fragment2 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_2) }
assertThat(fragment1).isNotNull()
assertThat(fragment2).isNotNull()
assertThat(fragment1.fragmentModel).isNotSameInstanceAs(fragment2.fragmentModel)
val fragment1Model = fragment1.fragmentModel
val fragment2Model = fragment2.fragmentModel
recreate()
fragment1 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_1) }
fragment2 = withActivity { getFragment(ViewModelActivity.FRAGMENT_TAG_2) }
assertThat(fragment1).isNotNull()
assertThat(fragment2).isNotNull()
assertThat(fragment1.fragmentModel).isSameInstanceAs(fragment1Model)
assertThat(fragment2.fragmentModel).isSameInstanceAs(fragment2Model)
}
}
@Test
fun testFragmentOnClearedWhenFinished() {
with(ActivityScenario.launch(ViewModelActivity::class.java)) {
val fragmentModel = withActivity {
getFragment(ViewModelActivity.FRAGMENT_TAG_1).fragmentModel
}
val fragmentAndroidModel = withActivity {
getFragment(ViewModelActivity.FRAGMENT_TAG_1).androidModel
}
val backStackFragmentModel = withActivity {
getFragment(ViewModelActivity.FRAGMENT_TAG_BACK_STACK).fragmentModel
}
assertThat(fragmentModel.cleared).isFalse()
assertThat(fragmentAndroidModel.cleared).isFalse()
assertThat(backStackFragmentModel.cleared).isFalse()
recreate()
// recreate shouldn't clear the ViewModels
assertThat(fragmentModel.cleared).isFalse()
assertThat(fragmentAndroidModel.cleared).isFalse()
assertThat(backStackFragmentModel.cleared).isFalse()
moveToState(Lifecycle.State.DESTROYED)
// But destroying the Activity should
assertThat(fragmentModel.cleared).isTrue()
assertThat(fragmentAndroidModel.cleared).isTrue()
assertThat(backStackFragmentModel.cleared).isTrue()
}
}
@Test
fun testFragmentOnCleared() {
with(ActivityScenario.launch(ViewModelActivity::class.java)) {
val fragment = withActivity {
Fragment().also {
supportFragmentManager.beginTransaction().add(it, "temp").commitNow()
}
}
val viewModelProvider = ViewModelProvider(fragment)
val vm = viewModelProvider.get(TestViewModel::class.java)
assertThat(vm.cleared).isFalse()
onActivity { activity ->
activity.supportFragmentManager.beginTransaction().remove(fragment).commitNow()
}
assertThat(vm.cleared).isTrue()
}
}
}
private fun FragmentActivity.getFragment(tag: String) =
supportFragmentManager.findFragmentByTag(tag) as ViewModelFragment