1c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar/* 264db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar * Copyright (C) 2017 The Android Open Source Project 3c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * 4c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * you may not use this file except in compliance with the License. 6c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * You may obtain a copy of the License at 7c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * 8c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * 10c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * Unless required by applicable law or agreed to in writing, software 11c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * See the License for the specific language governing permissions and 14c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * limitations under the License. 15c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar */ 16c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 17ba069d50913c3fb250bb60ec310439db36895337Alan Viverettepackage androidx.lifecycle; 18c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 19ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport static androidx.lifecycle.Lifecycle.Event.ON_CREATE; 20ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport static androidx.lifecycle.Lifecycle.Event.ON_DESTROY; 21ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport static androidx.lifecycle.Lifecycle.Event.ON_PAUSE; 22ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport static androidx.lifecycle.Lifecycle.Event.ON_RESUME; 23ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport static androidx.lifecycle.Lifecycle.Event.ON_START; 24ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport static androidx.lifecycle.Lifecycle.Event.ON_STOP; 25c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 26c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.hamcrest.CoreMatchers.instanceOf; 27c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.hamcrest.CoreMatchers.is; 28c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.hamcrest.MatcherAssert.assertThat; 29c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Matchers.anyBoolean; 30c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Matchers.anyString; 31c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.mock; 32c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.never; 33406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinetsimport static org.mockito.Mockito.only; 34c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.reset; 354d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyarimport static org.mockito.Mockito.spy; 36c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.verify; 37c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.verifyNoMoreInteractions; 38c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.when; 39c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 40ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.annotation.Nullable; 41ddee2b5170ae257a7b2494f8aaa8459ebed806dcAurimas Liutikasimport androidx.arch.core.executor.ArchTaskExecutor; 42ddee2b5170ae257a7b2494f8aaa8459ebed806dcAurimas Liutikasimport androidx.arch.core.executor.testing.InstantTaskExecutorRule; 4334e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar 4434e5031083f735db3a395b0f6aa430880b072d71Yigit Boyarimport org.junit.After; 45c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport org.junit.Before; 46c0b801c3d8522e411411ae65e474ee3106cd908aIan Lakeimport org.junit.Rule; 47c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport org.junit.Test; 48d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinetsimport org.junit.runner.RunWith; 49d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinetsimport org.junit.runners.JUnit4; 500b5883440daa7d68a80c08625866952c86071028shepshapardimport org.mockito.ArgumentCaptor; 51d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinetsimport org.mockito.InOrder; 52c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinetsimport org.mockito.Mockito; 53c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 54c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar@SuppressWarnings({"unchecked"}) 55d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets@RunWith(JUnit4.class) 56c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarpublic class LiveDataTest { 57c0b801c3d8522e411411ae65e474ee3106cd908aIan Lake 58c0b801c3d8522e411411ae65e474ee3106cd908aIan Lake @Rule 59c0b801c3d8522e411411ae65e474ee3106cd908aIan Lake public InstantTaskExecutorRule mInstantTaskExecutorRule = new InstantTaskExecutorRule(); 60c0b801c3d8522e411411ae65e474ee3106cd908aIan Lake 61c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar private PublicLiveData<String> mLiveData; 620b5883440daa7d68a80c08625866952c86071028shepshapard private MethodExec mActiveObserversChanged; 630b5883440daa7d68a80c08625866952c86071028shepshapard 64e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets private LifecycleOwner mOwner; 65c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar private LifecycleRegistry mRegistry; 660b5883440daa7d68a80c08625866952c86071028shepshapard 670b5883440daa7d68a80c08625866952c86071028shepshapard private LifecycleOwner mOwner2; 685cfbb5dc6b92d9901a83628aec597acceb831916shepshapard private LifecycleRegistry mRegistry2; 690b5883440daa7d68a80c08625866952c86071028shepshapard 700b5883440daa7d68a80c08625866952c86071028shepshapard private LifecycleOwner mOwner3; 710b5883440daa7d68a80c08625866952c86071028shepshapard private Lifecycle mLifecycle3; 720b5883440daa7d68a80c08625866952c86071028shepshapard private Observer<String> mObserver3; 730b5883440daa7d68a80c08625866952c86071028shepshapard 740b5883440daa7d68a80c08625866952c86071028shepshapard private LifecycleOwner mOwner4; 750b5883440daa7d68a80c08625866952c86071028shepshapard private Lifecycle mLifecycle4; 760b5883440daa7d68a80c08625866952c86071028shepshapard private Observer<String> mObserver4; 770b5883440daa7d68a80c08625866952c86071028shepshapard 78c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets private boolean mInObserver; 79c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 80c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Before 81c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public void init() { 82c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData = new PublicLiveData<>(); 835cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 845cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mActiveObserversChanged = mock(MethodExec.class); 855cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.activeObserversChanged = mActiveObserversChanged; 865cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 87e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mOwner = mock(LifecycleOwner.class); 88e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mRegistry = new LifecycleRegistry(mOwner); 89e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets when(mOwner.getLifecycle()).thenReturn(mRegistry); 905cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 915cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mOwner2 = mock(LifecycleOwner.class); 925cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry2 = new LifecycleRegistry(mOwner2); 935cfbb5dc6b92d9901a83628aec597acceb831916shepshapard when(mOwner2.getLifecycle()).thenReturn(mRegistry2); 945cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 95c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mInObserver = false; 96c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 97c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 9834e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar @Before 990b5883440daa7d68a80c08625866952c86071028shepshapard public void initNonLifecycleRegistry() { 1000b5883440daa7d68a80c08625866952c86071028shepshapard mOwner3 = mock(LifecycleOwner.class); 1010b5883440daa7d68a80c08625866952c86071028shepshapard mLifecycle3 = mock(Lifecycle.class); 1020b5883440daa7d68a80c08625866952c86071028shepshapard mObserver3 = (Observer<String>) mock(Observer.class); 1030b5883440daa7d68a80c08625866952c86071028shepshapard when(mOwner3.getLifecycle()).thenReturn(mLifecycle3); 1040b5883440daa7d68a80c08625866952c86071028shepshapard 1050b5883440daa7d68a80c08625866952c86071028shepshapard mOwner4 = mock(LifecycleOwner.class); 1060b5883440daa7d68a80c08625866952c86071028shepshapard mLifecycle4 = mock(Lifecycle.class); 1070b5883440daa7d68a80c08625866952c86071028shepshapard mObserver4 = (Observer<String>) mock(Observer.class); 1080b5883440daa7d68a80c08625866952c86071028shepshapard when(mOwner4.getLifecycle()).thenReturn(mLifecycle4); 1090b5883440daa7d68a80c08625866952c86071028shepshapard } 1100b5883440daa7d68a80c08625866952c86071028shepshapard 11134e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar @After 11234e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar public void removeExecutorDelegate() { 113ae36c8b11a64d3cdc9ba6e37d9f3d1d250fdc4a8Yigit Boyar ArchTaskExecutor.getInstance().setDelegate(null); 11434e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar } 11534e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar 116c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 117c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public void testObserverToggle() { 118c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 119e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 120c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 121c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 122abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 123abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 124c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 125c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData.removeObserver(observer); 126c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 127abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 128abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 129c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 130c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 131c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 132c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public void testActiveObserverToggle() { 133c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 134e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 135c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 136c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 137abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 138abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 139c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 140c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 141c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged).onCall(true); 142abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(true)); 1434d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar reset(mActiveObserversChanged); 144c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 145c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_STOP); 146c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged).onCall(false); 147abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 148abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 149c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 1504d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar reset(mActiveObserversChanged); 151c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 152c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged).onCall(true); 153abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(true)); 154abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 155c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 1564d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar reset(mActiveObserversChanged); 157c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData.removeObserver(observer); 158c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged).onCall(false); 159abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 160abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 161c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 1624d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar verifyNoMoreInteractions(mActiveObserversChanged); 163c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 164c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 165c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 166c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public void testReAddSameObserverTuple() { 167c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 168e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 169e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 170abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 171c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 172c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 173c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 174e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets public void testAdd2ObserversWithSameOwnerAndRemove() { 175c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> o1 = (Observer<String>) mock(Observer.class); 176c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> o2 = (Observer<String>) mock(Observer.class); 177e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, o1); 178e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, o2); 179abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 180c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 181c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 182c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 183c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged).onCall(true); 184c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData.setValue("a"); 185c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(o1).onChanged("a"); 186c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(o2).onChanged("a"); 187c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 188e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.removeObservers(mOwner); 189c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 190abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 19180f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets assertThat(mRegistry.getObserverCount(), is(0)); 192c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 193c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 194c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 195e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets public void testAddSameObserverIn2LifecycleOwners() { 196c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 197c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 198e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 199c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Throwable throwable = null; 200c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar try { 2015cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner2, observer); 202c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } catch (Throwable t) { 203c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar throwable = t; 204c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 205c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar assertThat(throwable, instanceOf(IllegalArgumentException.class)); 206c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets //noinspection ConstantConditions 207c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar assertThat(throwable.getMessage(), 208c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets is("Cannot add the same observer with different lifecycles")); 209c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 210c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 211c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 212c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public void testRemoveDestroyedObserver() { 213c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 214e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 215c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 216c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged).onCall(true); 217abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 218abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(true)); 2194d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar 2204d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar reset(mActiveObserversChanged); 221c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 222c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_DESTROY); 223abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 224abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 225c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(mActiveObserversChanged).onCall(false); 226c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 227c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 228c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 229c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public void testInactiveRegistry() { 230c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 231c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_DESTROY); 232e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 233abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 234c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 235c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 236c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 237c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public void testNotifyActiveInactive() { 238c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 239c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_CREATE); 240e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 241c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData.setValue("a"); 242c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(observer, never()).onChanged(anyString()); 243c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 244c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(observer).onChanged("a"); 245c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 246c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData.setValue("b"); 247c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(observer).onChanged("b"); 248c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 249c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_STOP); 250c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData.setValue("c"); 251c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(observer, never()).onChanged("c"); 252c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 253c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 254c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(observer).onChanged("c"); 255c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 256c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar reset(observer); 257c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_STOP); 258c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 259c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar verify(observer, never()).onChanged(anyString()); 260c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 261c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 262c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 263e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets public void testStopObservingOwner_onDestroy() { 264c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 265c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_CREATE); 266e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 26780f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets assertThat(mRegistry.getObserverCount(), is(1)); 268c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_DESTROY); 26980f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets assertThat(mRegistry.getObserverCount(), is(0)); 270c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 271c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 272c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Test 273e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets public void testStopObservingOwner_onStopObserving() { 274c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 275c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mRegistry.handleLifecycleEvent(ON_CREATE); 276e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 27780f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets assertThat(mRegistry.getObserverCount(), is(1)); 278c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 279c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar mLiveData.removeObserver(observer); 28080f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets assertThat(mRegistry.getObserverCount(), is(0)); 281c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 282c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 2834d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar @Test 2844d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar public void testActiveChangeInCallback() { 2854d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar mRegistry.handleLifecycleEvent(ON_START); 286c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets Observer<String> observer1 = spy(new Observer<String>() { 2874d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar @Override 2884d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar public void onChanged(@Nullable String s) { 2894d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar mRegistry.handleLifecycleEvent(ON_STOP); 290abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 291abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 2924d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar } 2934d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar }); 294c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets final Observer observer2 = mock(Observer.class); 295e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer1); 296e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer2); 2974d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar mLiveData.setValue("bla"); 298c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer1).onChanged(anyString()); 299c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer2, Mockito.never()).onChanged(anyString()); 300abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 301abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 3024d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar } 3034d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar 3044d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar @Test 305c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets public void testActiveChangeInCallback2() { 306c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets Observer<String> observer1 = spy(new Observer<String>() { 307c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets @Override 308c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets public void onChanged(@Nullable String s) { 309c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets assertThat(mInObserver, is(false)); 310c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mInObserver = true; 311c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mRegistry.handleLifecycleEvent(ON_START); 312abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(true)); 313c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mInObserver = false; 314c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets } 315c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets }); 316c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets final Observer observer2 = spy(new FailReentranceObserver()); 317d3449ae5a2f97b3654a9e5945a3365acb316891bSergey Vasilinets mLiveData.observeForever(observer1); 318e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer2); 319c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mLiveData.setValue("bla"); 320c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer1).onChanged(anyString()); 321c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer2).onChanged(anyString()); 322abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 323abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(true)); 324c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets } 325c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets 326c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets @Test 3274d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar public void testObserverRemovalInCallback() { 3284d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar mRegistry.handleLifecycleEvent(ON_START); 3294d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar Observer<String> observer = spy(new Observer<String>() { 3304d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar @Override 3314d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar public void onChanged(@Nullable String s) { 332abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 333c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mLiveData.removeObserver(this); 334abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 3354d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar } 3364d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar }); 337e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 3384d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar mLiveData.setValue("bla"); 3394d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar verify(observer).onChanged(anyString()); 340abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 3414d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar } 3424d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar 3434d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar @Test 3444d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar public void testObserverAdditionInCallback() { 3454d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar mRegistry.handleLifecycleEvent(ON_START); 346c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets final Observer observer2 = spy(new FailReentranceObserver()); 347c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets Observer<String> observer1 = spy(new Observer<String>() { 3484d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar @Override 3494d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar public void onChanged(@Nullable String s) { 350c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets assertThat(mInObserver, is(false)); 351c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mInObserver = true; 352e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer2); 353abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 354abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(true)); 355c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mInObserver = false; 3564d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar } 3574d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar }); 358e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer1); 3594d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar mLiveData.setValue("bla"); 360c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer1).onChanged(anyString()); 361c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer2).onChanged(anyString()); 362abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasObservers(), is(true)); 363abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(true)); 3644d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar } 3654d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar 3667c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets @Test 367e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets public void testObserverWithoutLifecycleOwner() { 3687c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets Observer<String> observer = (Observer<String>) mock(Observer.class); 3697c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets mLiveData.setValue("boring"); 370d3449ae5a2f97b3654a9e5945a3365acb316891bSergey Vasilinets mLiveData.observeForever(observer); 3717c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets verify(mActiveObserversChanged).onCall(true); 3727c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets verify(observer).onChanged("boring"); 3737c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets mLiveData.setValue("tihs"); 3747c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets verify(observer).onChanged("tihs"); 3757c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets mLiveData.removeObserver(observer); 3767c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets verify(mActiveObserversChanged).onCall(false); 3777c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets mLiveData.setValue("boring"); 3787c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets reset(observer); 3797c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets verify(observer, never()).onChanged(anyString()); 3807c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets } 3817c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets 382c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets @Test 383c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets public void testSetValueDuringSetValue() { 384c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mRegistry.handleLifecycleEvent(ON_START); 385c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets final Observer observer1 = spy(new Observer<String>() { 386c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets @Override 387c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets public void onChanged(String o) { 388c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets assertThat(mInObserver, is(false)); 389c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mInObserver = true; 390c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets if (o.equals(("bla"))) { 391c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mLiveData.setValue("gt"); 392c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets } 393c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mInObserver = false; 394c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets } 395c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets }); 396c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets final Observer observer2 = spy(new FailReentranceObserver()); 397e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer1); 398e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer2); 399c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets mLiveData.setValue("bla"); 400c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer1, Mockito.atMost(2)).onChanged("gt"); 401c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets verify(observer2, Mockito.atMost(2)).onChanged("gt"); 402c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets } 403c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets 4045dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar @Test 4053facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets public void testRemoveDuringSetValue() { 4063facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets mRegistry.handleLifecycleEvent(ON_START); 4073facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets final Observer observer1 = spy(new Observer<String>() { 4083facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets @Override 4093facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets public void onChanged(String o) { 4103facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets mLiveData.removeObserver(this); 4113facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets } 4123facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets }); 4133facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets Observer<String> observer2 = (Observer<String>) mock(Observer.class); 4143facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets mLiveData.observeForever(observer1); 4153facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets mLiveData.observe(mOwner, observer2); 4163facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets mLiveData.setValue("gt"); 4173facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets verify(observer2).onChanged("gt"); 4183facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets } 4193facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets 4203facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets @Test 4215dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar public void testDataChangeDuringStateChange() { 4225dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar mRegistry.handleLifecycleEvent(ON_START); 4235dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar mRegistry.addObserver(new LifecycleObserver() { 4245dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar @OnLifecycleEvent(ON_STOP) 4255dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar public void onStop() { 4265dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar // change data in onStop, observer should not be called! 4275dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar mLiveData.setValue("b"); 4285dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar } 4295dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar }); 4305dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar Observer<String> observer = (Observer<String>) mock(Observer.class); 4315dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar mLiveData.setValue("a"); 432e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets mLiveData.observe(mOwner, observer); 4335dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar verify(observer).onChanged("a"); 4345dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar mRegistry.handleLifecycleEvent(ON_PAUSE); 4355dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar mRegistry.handleLifecycleEvent(ON_STOP); 4365dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar verify(observer, never()).onChanged("b"); 4375dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar 4385dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar mRegistry.handleLifecycleEvent(ON_RESUME); 4395dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar verify(observer).onChanged("b"); 4405dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar } 4415dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar 4420da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets @Test 4430da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets public void testNotCallInactiveWithObserveForever() { 4440da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets mRegistry.handleLifecycleEvent(ON_START); 4450da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets Observer<String> observer = (Observer<String>) mock(Observer.class); 4460da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets Observer<String> observer2 = (Observer<String>) mock(Observer.class); 4470da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets mLiveData.observe(mOwner, observer); 4480da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets mLiveData.observeForever(observer2); 4490da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets verify(mActiveObserversChanged).onCall(true); 4500da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets reset(mActiveObserversChanged); 4510da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets mRegistry.handleLifecycleEvent(ON_STOP); 4520da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 4530da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets mRegistry.handleLifecycleEvent(ON_START); 4540da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 4550da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets } 4560da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets 457d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets @Test 458d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets public void testRemoveDuringAddition() { 459d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mRegistry.handleLifecycleEvent(ON_START); 460d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mLiveData.setValue("bla"); 461d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mLiveData.observeForever(new Observer<String>() { 462d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets @Override 463d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets public void onChanged(@Nullable String s) { 464d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mLiveData.removeObserver(this); 465d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets } 466d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets }); 467d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 468d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets InOrder inOrder = Mockito.inOrder(mActiveObserversChanged); 469d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets inOrder.verify(mActiveObserversChanged).onCall(true); 470d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets inOrder.verify(mActiveObserversChanged).onCall(false); 471d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets inOrder.verifyNoMoreInteractions(); 472d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets } 473d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets 474d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets @Test 475d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets public void testRemoveDuringBringingUpToState() { 476d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mLiveData.setValue("bla"); 477d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mLiveData.observeForever(new Observer<String>() { 478d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets @Override 479d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets public void onChanged(@Nullable String s) { 480d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mLiveData.removeObserver(this); 481d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets } 482d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets }); 483d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets mRegistry.handleLifecycleEvent(ON_RESUME); 484d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets assertThat(mLiveData.hasActiveObservers(), is(false)); 485d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets InOrder inOrder = Mockito.inOrder(mActiveObserversChanged); 486d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets inOrder.verify(mActiveObserversChanged).onCall(true); 487d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets inOrder.verify(mActiveObserversChanged).onCall(false); 488d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets inOrder.verifyNoMoreInteractions(); 489d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets } 490d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets 4915cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 4925cfbb5dc6b92d9901a83628aec597acceb831916shepshapard public void setValue_neverActive_observerOnChangedNotCalled() { 4935cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer = (Observer<String>) mock(Observer.class); 4945cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner, observer); 4955cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 4965cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.setValue("1"); 4975cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 4985cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer, never()).onChanged(anyString()); 4995cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 5005cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5015cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 5025cfbb5dc6b92d9901a83628aec597acceb831916shepshapard public void setValue_twoObserversTwoStartedOwners_onChangedCalledOnBoth() { 5035cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer1 = mock(Observer.class); 5045cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer2 = mock(Observer.class); 5055cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5065cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner, observer1); 5075cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner2, observer2); 5085cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5095cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 5105cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START); 5115cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5125cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.setValue("1"); 5135cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5145cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer1).onChanged("1"); 5155cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer2).onChanged("1"); 5165cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 5175cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5185cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 5195cfbb5dc6b92d9901a83628aec597acceb831916shepshapard public void setValue_twoObserversOneStartedOwner_onChangedCalledOnOneCorrectObserver() { 5205cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer1 = mock(Observer.class); 5215cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer2 = mock(Observer.class); 5225cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5235cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner, observer1); 5245cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner2, observer2); 5255cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5265cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 5275cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5285cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.setValue("1"); 5295cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5305cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer1).onChanged("1"); 5315cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer2, never()).onChanged(anyString()); 5325cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 5335cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5345cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 5355cfbb5dc6b92d9901a83628aec597acceb831916shepshapard public void setValue_twoObserversBothStartedAfterSetValue_onChangedCalledOnBoth() { 5365cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer1 = mock(Observer.class); 5375cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer2 = mock(Observer.class); 5385cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5395cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner, observer1); 5405cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner2, observer2); 5415cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5425cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.setValue("1"); 5435cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5445cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 5455cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START); 5465cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5475cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer1).onChanged("1"); 5485cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer1).onChanged("1"); 5495cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 5505cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5515cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 5525cfbb5dc6b92d9901a83628aec597acceb831916shepshapard public void setValue_twoObserversOneStartedAfterSetValue_onChangedCalledOnCorrectObserver() { 5535cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer1 = mock(Observer.class); 5545cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer2 = mock(Observer.class); 5555cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5565cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner, observer1); 5575cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner2, observer2); 5585cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5595cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.setValue("1"); 5605cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5615cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 5625cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5635cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer1).onChanged("1"); 5645cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(observer2, never()).onChanged(anyString()); 5655cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 5665cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5675cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 5685cfbb5dc6b92d9901a83628aec597acceb831916shepshapard public void setValue_twoObserversOneStarted_liveDataBecomesActive() { 5695cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer1 = mock(Observer.class); 5705cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer2 = mock(Observer.class); 5715cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5725cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner, observer1); 5735cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner2, observer2); 5745cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5755cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 5765cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5775cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(mActiveObserversChanged).onCall(true); 5785cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 5795cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5805cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 5815cfbb5dc6b92d9901a83628aec597acceb831916shepshapard public void setValue_twoObserversOneStopped_liveDataStaysActive() { 5825cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer1 = mock(Observer.class); 5835cfbb5dc6b92d9901a83628aec597acceb831916shepshapard Observer<String> observer2 = mock(Observer.class); 5845cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5855cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner, observer1); 5865cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.observe(mOwner2, observer2); 5875cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5885cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 5895cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START); 5905cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5915cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(mActiveObserversChanged).onCall(true); 5925cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5935cfbb5dc6b92d9901a83628aec597acceb831916shepshapard reset(mActiveObserversChanged); 5945cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 5955cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5965cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 5975cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 5985cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 5995cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 6000b5883440daa7d68a80c08625866952c86071028shepshapard public void setValue_lifecycleIsCreatedNoEvent_liveDataBecomesInactiveAndObserverNotCalled() { 6015cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6020b5883440daa7d68a80c08625866952c86071028shepshapard // Arrange. 6030b5883440daa7d68a80c08625866952c86071028shepshapard 6040b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner3, mObserver3); 6050b5883440daa7d68a80c08625866952c86071028shepshapard 6060b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver = getGenericLifecycleObserver(mLifecycle3); 6070b5883440daa7d68a80c08625866952c86071028shepshapard 6080b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 6090b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver.onStateChanged(mOwner3, Lifecycle.Event.ON_START); 6100b5883440daa7d68a80c08625866952c86071028shepshapard 6110b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.CREATED); 6125cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 613a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar reset(mActiveObserversChanged); 6140b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver3); 6150b5883440daa7d68a80c08625866952c86071028shepshapard 6160b5883440daa7d68a80c08625866952c86071028shepshapard // Act. 6175cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6185cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.setValue("1"); 619a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar 6200b5883440daa7d68a80c08625866952c86071028shepshapard // Assert. 6210b5883440daa7d68a80c08625866952c86071028shepshapard 6220b5883440daa7d68a80c08625866952c86071028shepshapard verify(mActiveObserversChanged).onCall(false); 6230b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver3, never()).onChanged(anyString()); 6240b5883440daa7d68a80c08625866952c86071028shepshapard } 6250b5883440daa7d68a80c08625866952c86071028shepshapard 6260b5883440daa7d68a80c08625866952c86071028shepshapard /* 6270b5883440daa7d68a80c08625866952c86071028shepshapard * Arrange: LiveData was made inactive via SetValue (because the Lifecycle it was 6280b5883440daa7d68a80c08625866952c86071028shepshapard * observing was in the CREATED state and no event was dispatched). 6290b5883440daa7d68a80c08625866952c86071028shepshapard * Act: Lifecycle enters Started state and dispatches event. 6300b5883440daa7d68a80c08625866952c86071028shepshapard * Assert: LiveData becomes active and dispatches new value to observer. 6310b5883440daa7d68a80c08625866952c86071028shepshapard */ 6320b5883440daa7d68a80c08625866952c86071028shepshapard @Test 6330b5883440daa7d68a80c08625866952c86071028shepshapard public void test_liveDataInactiveViaSetValueThenLifecycleResumes() { 6340b5883440daa7d68a80c08625866952c86071028shepshapard 6350b5883440daa7d68a80c08625866952c86071028shepshapard // Arrange. 6360b5883440daa7d68a80c08625866952c86071028shepshapard 6370b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner3, mObserver3); 6380b5883440daa7d68a80c08625866952c86071028shepshapard 6390b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver = getGenericLifecycleObserver(mLifecycle3); 6400b5883440daa7d68a80c08625866952c86071028shepshapard 6410b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 6420b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver.onStateChanged(mOwner3, Lifecycle.Event.ON_START); 6430b5883440daa7d68a80c08625866952c86071028shepshapard 6440b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.CREATED); 6450b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.setValue("1"); 6465cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6475cfbb5dc6b92d9901a83628aec597acceb831916shepshapard reset(mActiveObserversChanged); 6480b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver3); 6490b5883440daa7d68a80c08625866952c86071028shepshapard 6500b5883440daa7d68a80c08625866952c86071028shepshapard // Act. 6510b5883440daa7d68a80c08625866952c86071028shepshapard 6520b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 6530b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver.onStateChanged(mOwner3, Lifecycle.Event.ON_START); 6540b5883440daa7d68a80c08625866952c86071028shepshapard 6550b5883440daa7d68a80c08625866952c86071028shepshapard // Assert. 6560b5883440daa7d68a80c08625866952c86071028shepshapard 6575cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(mActiveObserversChanged).onCall(true); 6580b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver3).onChanged("1"); 6595cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 6605cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6610b5883440daa7d68a80c08625866952c86071028shepshapard /* 6620b5883440daa7d68a80c08625866952c86071028shepshapard * Arrange: One of two Lifecycles enter the CREATED state without sending an event. 6630b5883440daa7d68a80c08625866952c86071028shepshapard * Act: Lifecycle's setValue method is called with new value. 6640b5883440daa7d68a80c08625866952c86071028shepshapard * Assert: LiveData stays active and new value is dispatched to Lifecycle that is still at least 6650b5883440daa7d68a80c08625866952c86071028shepshapard * STARTED. 6665cfbb5dc6b92d9901a83628aec597acceb831916shepshapard */ 6675cfbb5dc6b92d9901a83628aec597acceb831916shepshapard @Test 6680b5883440daa7d68a80c08625866952c86071028shepshapard public void setValue_oneOfTwoLifecyclesAreCreatedNoEvent() { 6695cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6700b5883440daa7d68a80c08625866952c86071028shepshapard // Arrange. 6715cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6720b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner3, mObserver3); 6730b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner4, mObserver4); 6740b5883440daa7d68a80c08625866952c86071028shepshapard 6750b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver3 = getGenericLifecycleObserver(mLifecycle3); 6760b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver4 = getGenericLifecycleObserver(mLifecycle4); 6770b5883440daa7d68a80c08625866952c86071028shepshapard 6780b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 6790b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle4.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 6800b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver3.onStateChanged(mOwner3, Lifecycle.Event.ON_START); 6810b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver4.onStateChanged(mOwner4, Lifecycle.Event.ON_START); 6820b5883440daa7d68a80c08625866952c86071028shepshapard 6830b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.CREATED); 6845cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6855cfbb5dc6b92d9901a83628aec597acceb831916shepshapard reset(mActiveObserversChanged); 6860b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver3); 6870b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver4); 6880b5883440daa7d68a80c08625866952c86071028shepshapard 6890b5883440daa7d68a80c08625866952c86071028shepshapard // Act. 6905cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 6915cfbb5dc6b92d9901a83628aec597acceb831916shepshapard mLiveData.setValue("1"); 6920b5883440daa7d68a80c08625866952c86071028shepshapard 6930b5883440daa7d68a80c08625866952c86071028shepshapard // Assert. 6940b5883440daa7d68a80c08625866952c86071028shepshapard 6955cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(mActiveObserversChanged, never()).onCall(anyBoolean()); 6960b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver3, never()).onChanged(anyString()); 6970b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver4).onChanged("1"); 6980b5883440daa7d68a80c08625866952c86071028shepshapard } 6995cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 7000b5883440daa7d68a80c08625866952c86071028shepshapard /* 7010b5883440daa7d68a80c08625866952c86071028shepshapard * Arrange: Two observed Lifecycles enter the CREATED state without sending an event. 7020b5883440daa7d68a80c08625866952c86071028shepshapard * Act: Lifecycle's setValue method is called with new value. 7030b5883440daa7d68a80c08625866952c86071028shepshapard * Assert: LiveData becomes inactive and nothing is dispatched to either observer. 7040b5883440daa7d68a80c08625866952c86071028shepshapard */ 7050b5883440daa7d68a80c08625866952c86071028shepshapard @Test 7060b5883440daa7d68a80c08625866952c86071028shepshapard public void setValue_twoLifecyclesAreCreatedNoEvent() { 7070b5883440daa7d68a80c08625866952c86071028shepshapard 7080b5883440daa7d68a80c08625866952c86071028shepshapard // Arrange. 7090b5883440daa7d68a80c08625866952c86071028shepshapard 7100b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner3, mObserver3); 7110b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner4, mObserver4); 7120b5883440daa7d68a80c08625866952c86071028shepshapard 7130b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver3 = getGenericLifecycleObserver(mLifecycle3); 7140b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver4 = getGenericLifecycleObserver(mLifecycle4); 7150b5883440daa7d68a80c08625866952c86071028shepshapard 7160b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 7170b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle4.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 7180b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver3.onStateChanged(mOwner3, Lifecycle.Event.ON_START); 7190b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver4.onStateChanged(mOwner4, Lifecycle.Event.ON_START); 7200b5883440daa7d68a80c08625866952c86071028shepshapard 7210b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.CREATED); 7220b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle4.getCurrentState()).thenReturn(Lifecycle.State.CREATED); 7235cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 724a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar reset(mActiveObserversChanged); 7250b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver3); 7260b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver4); 7270b5883440daa7d68a80c08625866952c86071028shepshapard 7280b5883440daa7d68a80c08625866952c86071028shepshapard // Act. 7290b5883440daa7d68a80c08625866952c86071028shepshapard 7300b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.setValue("1"); 7310b5883440daa7d68a80c08625866952c86071028shepshapard 7320b5883440daa7d68a80c08625866952c86071028shepshapard // Assert. 7330b5883440daa7d68a80c08625866952c86071028shepshapard 7340b5883440daa7d68a80c08625866952c86071028shepshapard verify(mActiveObserversChanged).onCall(false); 7350b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver3, never()).onChanged(anyString()); 7360b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver3, never()).onChanged(anyString()); 7370b5883440daa7d68a80c08625866952c86071028shepshapard } 7380b5883440daa7d68a80c08625866952c86071028shepshapard 7390b5883440daa7d68a80c08625866952c86071028shepshapard /* 7400b5883440daa7d68a80c08625866952c86071028shepshapard * Arrange: LiveData was made inactive via SetValue (because both Lifecycles it was 7410b5883440daa7d68a80c08625866952c86071028shepshapard * observing were in the CREATED state and no event was dispatched). 7420b5883440daa7d68a80c08625866952c86071028shepshapard * Act: One Lifecycle enters STARTED state and dispatches lifecycle event. 7430b5883440daa7d68a80c08625866952c86071028shepshapard * Assert: LiveData becomes active and dispatches new value to observer associated with started 7440b5883440daa7d68a80c08625866952c86071028shepshapard * Lifecycle. 7450b5883440daa7d68a80c08625866952c86071028shepshapard */ 7460b5883440daa7d68a80c08625866952c86071028shepshapard @Test 7470b5883440daa7d68a80c08625866952c86071028shepshapard public void test_liveDataInactiveViaSetValueThenOneLifecycleResumes() { 7480b5883440daa7d68a80c08625866952c86071028shepshapard 7490b5883440daa7d68a80c08625866952c86071028shepshapard // Arrange. 7500b5883440daa7d68a80c08625866952c86071028shepshapard 7510b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner3, mObserver3); 7520b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.observe(mOwner4, mObserver4); 7530b5883440daa7d68a80c08625866952c86071028shepshapard 7540b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver3 = getGenericLifecycleObserver(mLifecycle3); 7550b5883440daa7d68a80c08625866952c86071028shepshapard GenericLifecycleObserver lifecycleObserver4 = getGenericLifecycleObserver(mLifecycle4); 7560b5883440daa7d68a80c08625866952c86071028shepshapard 7570b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 7580b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle4.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 7590b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver3.onStateChanged(mOwner3, Lifecycle.Event.ON_START); 7600b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver4.onStateChanged(mOwner4, Lifecycle.Event.ON_START); 7610b5883440daa7d68a80c08625866952c86071028shepshapard 7620b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.CREATED); 7630b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle4.getCurrentState()).thenReturn(Lifecycle.State.CREATED); 7640b5883440daa7d68a80c08625866952c86071028shepshapard 7650b5883440daa7d68a80c08625866952c86071028shepshapard mLiveData.setValue("1"); 7665cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 767a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar reset(mActiveObserversChanged); 7680b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver3); 7690b5883440daa7d68a80c08625866952c86071028shepshapard reset(mObserver4); 7700b5883440daa7d68a80c08625866952c86071028shepshapard 7710b5883440daa7d68a80c08625866952c86071028shepshapard // Act. 7720b5883440daa7d68a80c08625866952c86071028shepshapard 7730b5883440daa7d68a80c08625866952c86071028shepshapard when(mLifecycle3.getCurrentState()).thenReturn(Lifecycle.State.STARTED); 7740b5883440daa7d68a80c08625866952c86071028shepshapard lifecycleObserver3.onStateChanged(mOwner3, Lifecycle.Event.ON_START); 7750b5883440daa7d68a80c08625866952c86071028shepshapard 7760b5883440daa7d68a80c08625866952c86071028shepshapard // Assert. 7770b5883440daa7d68a80c08625866952c86071028shepshapard 7785cfbb5dc6b92d9901a83628aec597acceb831916shepshapard verify(mActiveObserversChanged).onCall(true); 7790b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver3).onChanged("1"); 7800b5883440daa7d68a80c08625866952c86071028shepshapard verify(mObserver4, never()).onChanged(anyString()); 7810b5883440daa7d68a80c08625866952c86071028shepshapard } 7820b5883440daa7d68a80c08625866952c86071028shepshapard 783406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets @Test 784406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets public void nestedForeverObserver() { 785406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets mLiveData.setValue("."); 786406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets mLiveData.observeForever(new Observer<String>() { 787406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets @Override 788406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets public void onChanged(@Nullable String s) { 789406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets mLiveData.observeForever(mock(Observer.class)); 790406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets mLiveData.removeObserver(this); 791406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets } 792406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets }); 793406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets verify(mActiveObserversChanged, only()).onCall(true); 794406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets } 795406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets 796406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets @Test 797406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets public void readdForeverObserver() { 798406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets Observer observer = mock(Observer.class); 799406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets mLiveData.observeForever(observer); 800406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets mLiveData.observeForever(observer); 801406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets mLiveData.removeObserver(observer); 802406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets assertThat(mLiveData.hasObservers(), is(false)); 803406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets } 804406dfb7a30f9fb785412cbe4d4e75503c58dafd9Sergey Vasilinets 8050b5883440daa7d68a80c08625866952c86071028shepshapard private GenericLifecycleObserver getGenericLifecycleObserver(Lifecycle lifecycle) { 8060b5883440daa7d68a80c08625866952c86071028shepshapard ArgumentCaptor<GenericLifecycleObserver> captor = 8070b5883440daa7d68a80c08625866952c86071028shepshapard ArgumentCaptor.forClass(GenericLifecycleObserver.class); 8080b5883440daa7d68a80c08625866952c86071028shepshapard verify(lifecycle).addObserver(captor.capture()); 8090b5883440daa7d68a80c08625866952c86071028shepshapard return (captor.getValue()); 8105cfbb5dc6b92d9901a83628aec597acceb831916shepshapard } 8115cfbb5dc6b92d9901a83628aec597acceb831916shepshapard 812c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @SuppressWarnings("WeakerAccess") 813c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar static class PublicLiveData<T> extends LiveData<T> { 814c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar // cannot spy due to internal calls 815c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar public MethodExec activeObserversChanged; 816c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 817c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Override 8184d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar protected void onActive() { 819c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar if (activeObserversChanged != null) { 8204d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar activeObserversChanged.onCall(true); 821c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 822c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 823c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 824c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar @Override 8254d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar protected void onInactive() { 8264d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar if (activeObserversChanged != null) { 8274d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar activeObserversChanged.onCall(false); 828c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 829c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 830c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 831c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar 832c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets private class FailReentranceObserver<T> implements Observer<T> { 833c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets @Override 834c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets public void onChanged(@Nullable T t) { 835c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets assertThat(mInObserver, is(false)); 836c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets } 837c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets } 838c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets 839c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar interface MethodExec { 840c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar void onCall(boolean value); 841c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar } 842c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar} 843