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