LiveDataTest.java revision a3e03220c47cf14088ac23de6eb535cf45012109
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
1764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarpackage android.arch.lifecycle;
18c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
19b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinetsimport static android.arch.lifecycle.Lifecycle.Event.ON_CREATE;
20b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinetsimport static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY;
21b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinetsimport static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
22b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinetsimport static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
23b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinetsimport static android.arch.lifecycle.Lifecycle.Event.ON_START;
24b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinetsimport static android.arch.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;
33c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.reset;
344d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyarimport static org.mockito.Mockito.spy;
35c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.verify;
36c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.verifyNoMoreInteractions;
37c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.when;
38c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
39ae36c8b11a64d3cdc9ba6e37d9f3d1d250fdc4a8Yigit Boyarimport android.arch.core.executor.ArchTaskExecutor;
4064db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.lifecycle.util.InstantTaskExecutor;
41b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinetsimport android.support.annotation.Nullable;
4234e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
4334e5031083f735db3a395b0f6aa430880b072d71Yigit Boyarimport org.junit.After;
44c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport org.junit.Before;
45c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport org.junit.Test;
46d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinetsimport org.junit.runner.RunWith;
47d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinetsimport org.junit.runners.JUnit4;
48d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinetsimport org.mockito.InOrder;
49c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinetsimport org.mockito.Mockito;
50c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
51c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar@SuppressWarnings({"unchecked"})
52d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets@RunWith(JUnit4.class)
53c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarpublic class LiveDataTest {
54c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    private PublicLiveData<String> mLiveData;
55e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets    private LifecycleOwner mOwner;
565cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    private LifecycleOwner mOwner2;
57c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    private LifecycleRegistry mRegistry;
585cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    private LifecycleRegistry mRegistry2;
59c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    private MethodExec mActiveObserversChanged;
60c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    private boolean mInObserver;
61c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
62c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Before
63c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void init() {
64c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData = new PublicLiveData<>();
655cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
665cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mActiveObserversChanged = mock(MethodExec.class);
675cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.activeObserversChanged = mActiveObserversChanged;
685cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
69e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mOwner = mock(LifecycleOwner.class);
705cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
71e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mRegistry = new LifecycleRegistry(mOwner);
72e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        when(mOwner.getLifecycle()).thenReturn(mRegistry);
735cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
745cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mOwner2 = mock(LifecycleOwner.class);
755cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
765cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry2 = new LifecycleRegistry(mOwner2);
775cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        when(mOwner2.getLifecycle()).thenReturn(mRegistry2);
785cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
79c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        mInObserver = false;
80c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
81c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
8234e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    @Before
8334e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    public void swapExecutorDelegate() {
84ae36c8b11a64d3cdc9ba6e37d9f3d1d250fdc4a8Yigit Boyar        ArchTaskExecutor.getInstance().setDelegate(new InstantTaskExecutor());
8534e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    }
8634e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
8734e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    @After
8834e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    public void removeExecutorDelegate() {
89ae36c8b11a64d3cdc9ba6e37d9f3d1d250fdc4a8Yigit Boyar        ArchTaskExecutor.getInstance().setDelegate(null);
9034e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    }
9134e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
92c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
93c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testObserverToggle() {
94c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
95e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
96c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
97c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
98abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
99abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
100c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
101c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
102c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
103abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(false));
104abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
105c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
106c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
107c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
108c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testActiveObserverToggle() {
109c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
110e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
111c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
112c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
113abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
114abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
115c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
116c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
117c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
118abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(true));
1194d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
120c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
121c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
122c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
123abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
124abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
125c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1264d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
127c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
128c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
129abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(true));
130abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
131c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1324d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
133c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
134c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
135abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
136abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(false));
137c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1384d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verifyNoMoreInteractions(mActiveObserversChanged);
139c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
140c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
141c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
142c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testReAddSameObserverTuple() {
143c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
144e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
145e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
146abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
147c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
148c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
149c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
150e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets    public void testAdd2ObserversWithSameOwnerAndRemove() {
151c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> o1 = (Observer<String>) mock(Observer.class);
152c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> o2 = (Observer<String>) mock(Observer.class);
153e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, o1);
154e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, o2);
155abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
156c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
157c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
158c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
159c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
160c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("a");
161c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(o1).onChanged("a");
162c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(o2).onChanged("a");
163c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
164e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.removeObservers(mOwner);
165c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
166abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(false));
16780f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets        assertThat(mRegistry.getObserverCount(), is(0));
168c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
169c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
170c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
171e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets    public void testAddSameObserverIn2LifecycleOwners() {
172c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
173c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
174e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
175c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Throwable throwable = null;
176c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        try {
1775cfbb5dc6b92d9901a83628aec597acceb831916shepshapard            mLiveData.observe(mOwner2, observer);
178c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        } catch (Throwable t) {
179c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            throwable = t;
180c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
181c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(throwable, instanceOf(IllegalArgumentException.class));
182c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        //noinspection ConstantConditions
183c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(throwable.getMessage(),
184c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                is("Cannot add the same observer with different lifecycles"));
185c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
186c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
187c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
188c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testRemoveDestroyedObserver() {
189c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
190e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
191c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
192c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
193abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
194abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(true));
1954d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
1964d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
197c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
198c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
199abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(false));
200abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
201c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
202c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
203c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
204c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
205c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testInactiveRegistry() {
206c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
207c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
208e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
209abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(false));
210c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
211c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
212c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
213c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testNotifyActiveInactive() {
214c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
215c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
216e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
217c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("a");
218c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged(anyString());
219c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
220c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("a");
221c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
222c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("b");
223c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("b");
224c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
225c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
226c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("c");
227c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged("c");
228c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
229c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
230c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("c");
231c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
232c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        reset(observer);
233c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
234c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
235c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged(anyString());
236c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
237c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
238c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
239e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets    public void testStopObservingOwner_onDestroy() {
240c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
241c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
242e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
24380f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets        assertThat(mRegistry.getObserverCount(), is(1));
244c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
24580f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets        assertThat(mRegistry.getObserverCount(), is(0));
246c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
247c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
248c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
249e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets    public void testStopObservingOwner_onStopObserving() {
250c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
251c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
252e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
25380f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets        assertThat(mRegistry.getObserverCount(), is(1));
254c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
255c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
25680f1ba3ad13ca7e35c524a20442fd895e034f625Sergey Vasilinets        assertThat(mRegistry.getObserverCount(), is(0));
257c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
258c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
2594d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
2604d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testActiveChangeInCallback() {
2614d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
262c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        Observer<String> observer1 = spy(new Observer<String>() {
2634d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
2644d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
2654d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                mRegistry.handleLifecycleEvent(ON_STOP);
266abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets                assertThat(mLiveData.hasObservers(), is(true));
267abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets                assertThat(mLiveData.hasActiveObservers(), is(false));
2684d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
2694d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
270c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        final Observer observer2 = mock(Observer.class);
271e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer1);
272e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer2);
2734d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
274c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer1).onChanged(anyString());
275c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer2, Mockito.never()).onChanged(anyString());
276abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
277abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
2784d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
2794d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
2804d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
281c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    public void testActiveChangeInCallback2() {
282c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        Observer<String> observer1 = spy(new Observer<String>() {
283c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets            @Override
284c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets            public void onChanged(@Nullable String s) {
285c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                assertThat(mInObserver, is(false));
286c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mInObserver = true;
287c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mRegistry.handleLifecycleEvent(ON_START);
288abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets                assertThat(mLiveData.hasActiveObservers(), is(true));
289c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mInObserver = false;
290c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets            }
291c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        });
292c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        final Observer observer2 = spy(new FailReentranceObserver());
293d3449ae5a2f97b3654a9e5945a3365acb316891bSergey Vasilinets        mLiveData.observeForever(observer1);
294e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer2);
295c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        mLiveData.setValue("bla");
296c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer1).onChanged(anyString());
297c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer2).onChanged(anyString());
298abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
299abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(true));
300c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    }
301c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets
302c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    @Test
3034d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testObserverRemovalInCallback() {
3044d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
3054d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        Observer<String> observer = spy(new Observer<String>() {
3064d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
3074d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
308abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets                assertThat(mLiveData.hasObservers(), is(true));
309c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mLiveData.removeObserver(this);
310abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets                assertThat(mLiveData.hasObservers(), is(false));
3114d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
3124d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
313e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
3144d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
3154d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verify(observer).onChanged(anyString());
316abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(false));
3174d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
3184d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
3194d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
3204d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testObserverAdditionInCallback() {
3214d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
322c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        final Observer observer2 = spy(new FailReentranceObserver());
323c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        Observer<String> observer1 = spy(new Observer<String>() {
3244d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
3254d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
326c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                assertThat(mInObserver, is(false));
327c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mInObserver = true;
328e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets                mLiveData.observe(mOwner, observer2);
329abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets                assertThat(mLiveData.hasObservers(), is(true));
330abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets                assertThat(mLiveData.hasActiveObservers(), is(true));
331c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mInObserver = false;
3324d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
3334d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
334e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer1);
3354d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
336c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer1).onChanged(anyString());
337c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer2).onChanged(anyString());
338abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasObservers(), is(true));
339abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(true));
3404d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
3414d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
3427c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets    @Test
343e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets    public void testObserverWithoutLifecycleOwner() {
3447c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        Observer<String> observer = (Observer<String>) mock(Observer.class);
3457c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.setValue("boring");
346d3449ae5a2f97b3654a9e5945a3365acb316891bSergey Vasilinets        mLiveData.observeForever(observer);
3477c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(mActiveObserversChanged).onCall(true);
3487c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(observer).onChanged("boring");
3497c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.setValue("tihs");
3507c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(observer).onChanged("tihs");
3517c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.removeObserver(observer);
3527c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(mActiveObserversChanged).onCall(false);
3537c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.setValue("boring");
3547c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        reset(observer);
3557c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(observer, never()).onChanged(anyString());
3567c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets    }
3577c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets
358c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    @Test
359c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    public void testSetValueDuringSetValue() {
360c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        mRegistry.handleLifecycleEvent(ON_START);
361c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        final Observer observer1 = spy(new Observer<String>() {
362c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets            @Override
363c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets            public void onChanged(String o) {
364c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                assertThat(mInObserver, is(false));
365c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mInObserver = true;
366c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                if (o.equals(("bla"))) {
367c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                    mLiveData.setValue("gt");
368c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                }
369c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets                mInObserver = false;
370c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets            }
371c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        });
372c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        final Observer observer2 = spy(new FailReentranceObserver());
373e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer1);
374e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer2);
375c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        mLiveData.setValue("bla");
376c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer1, Mockito.atMost(2)).onChanged("gt");
377c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        verify(observer2, Mockito.atMost(2)).onChanged("gt");
378c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    }
379c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets
3805dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar    @Test
3813facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets    public void testRemoveDuringSetValue() {
3823facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        mRegistry.handleLifecycleEvent(ON_START);
3833facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        final Observer observer1 = spy(new Observer<String>() {
3843facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets            @Override
3853facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets            public void onChanged(String o) {
3863facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets                mLiveData.removeObserver(this);
3873facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets            }
3883facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        });
3893facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        Observer<String> observer2 = (Observer<String>) mock(Observer.class);
3903facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        mLiveData.observeForever(observer1);
3913facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        mLiveData.observe(mOwner, observer2);
3923facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        mLiveData.setValue("gt");
3933facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets        verify(observer2).onChanged("gt");
3943facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets    }
3953facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets
3963facabd26326a3f4274b04dc7ab03442839c5601Sergey Vasilinets    @Test
3975dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar    public void testDataChangeDuringStateChange() {
3985dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
3995dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        mRegistry.addObserver(new LifecycleObserver() {
4005dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar            @OnLifecycleEvent(ON_STOP)
4015dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar            public void onStop() {
4025dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar                // change data in onStop, observer should not be called!
4035dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar                mLiveData.setValue("b");
4045dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar            }
4055dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        });
4065dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
4075dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        mLiveData.setValue("a");
408e13540a25fe5460240b6db0e18858c32d16f5399Sergey Vasilinets        mLiveData.observe(mOwner, observer);
4095dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        verify(observer).onChanged("a");
4105dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        mRegistry.handleLifecycleEvent(ON_PAUSE);
4115dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
4125dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        verify(observer, never()).onChanged("b");
4135dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar
4145dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        mRegistry.handleLifecycleEvent(ON_RESUME);
4155dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar        verify(observer).onChanged("b");
4165dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar    }
4175dcab68c2e390acfb016cb889604b85e1257b02fYigit Boyar
4180da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets    @Test
4190da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets    public void testNotCallInactiveWithObserveForever() {
4200da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        mRegistry.handleLifecycleEvent(ON_START);
4210da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        Observer<String> observer = (Observer<String>) mock(Observer.class);
4220da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        Observer<String> observer2 = (Observer<String>) mock(Observer.class);
4230da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        mLiveData.observe(mOwner, observer);
4240da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        mLiveData.observeForever(observer2);
4250da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        verify(mActiveObserversChanged).onCall(true);
4260da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        reset(mActiveObserversChanged);
4270da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        mRegistry.handleLifecycleEvent(ON_STOP);
4280da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
4290da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        mRegistry.handleLifecycleEvent(ON_START);
4300da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
4310da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets    }
4320da9764fa45b24977675265e04e8aff3fc889d04Sergey Vasilinets
433d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets    @Test
434d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets    public void testRemoveDuringAddition() {
435d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        mRegistry.handleLifecycleEvent(ON_START);
436d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        mLiveData.setValue("bla");
437d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        mLiveData.observeForever(new Observer<String>() {
438d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets            @Override
439d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets            public void onChanged(@Nullable String s) {
440d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets                mLiveData.removeObserver(this);
441d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets            }
442d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        });
443d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
444d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        InOrder inOrder = Mockito.inOrder(mActiveObserversChanged);
445d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        inOrder.verify(mActiveObserversChanged).onCall(true);
446d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        inOrder.verify(mActiveObserversChanged).onCall(false);
447d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        inOrder.verifyNoMoreInteractions();
448d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets    }
449d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets
450d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets    @Test
451d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets    public void testRemoveDuringBringingUpToState() {
452d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        mLiveData.setValue("bla");
453d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        mLiveData.observeForever(new Observer<String>() {
454d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets            @Override
455d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets            public void onChanged(@Nullable String s) {
456d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets                mLiveData.removeObserver(this);
457d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets            }
458d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        });
459d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        mRegistry.handleLifecycleEvent(ON_RESUME);
460d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        assertThat(mLiveData.hasActiveObservers(), is(false));
461d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        InOrder inOrder = Mockito.inOrder(mActiveObserversChanged);
462d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        inOrder.verify(mActiveObserversChanged).onCall(true);
463d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        inOrder.verify(mActiveObserversChanged).onCall(false);
464d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets        inOrder.verifyNoMoreInteractions();
465d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets    }
466d069a4c914b2b43912fa6267b2f4c65408b6a4dcSergey Vasilinets
4675cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
4685cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void setValue_neverActive_observerOnChangedNotCalled() {
4695cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer = (Observer<String>) mock(Observer.class);
4705cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer);
4715cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4725cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("1");
4735cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4745cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer, never()).onChanged(anyString());
4755cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
4765cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4775cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
4785cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void setValue_twoObserversTwoStartedOwners_onChangedCalledOnBoth() {
4795cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer1 = mock(Observer.class);
4805cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer2 = mock(Observer.class);
4815cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4825cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer1);
4835cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner2, observer2);
4845cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4855cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
4865cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START);
4875cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4885cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("1");
4895cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4905cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1).onChanged("1");
4915cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer2).onChanged("1");
4925cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
4935cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4945cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
4955cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void setValue_twoObserversOneStartedOwner_onChangedCalledOnOneCorrectObserver() {
4965cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer1 = mock(Observer.class);
4975cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer2 = mock(Observer.class);
4985cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
4995cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer1);
5005cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner2, observer2);
5015cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5025cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
5035cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5045cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("1");
5055cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5065cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1).onChanged("1");
5075cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer2, never()).onChanged(anyString());
5085cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
5095cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5105cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
5115cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void setValue_twoObserversBothStartedAfterSetValue_onChangedCalledOnBoth() {
5125cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer1 = mock(Observer.class);
5135cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer2 = mock(Observer.class);
5145cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5155cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer1);
5165cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner2, observer2);
5175cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5185cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("1");
5195cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5205cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
5215cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START);
5225cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5235cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1).onChanged("1");
5245cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1).onChanged("1");
5255cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
5265cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5275cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
5285cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void setValue_twoObserversOneStartedAfterSetValue_onChangedCalledOnCorrectObserver() {
5295cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer1 = mock(Observer.class);
5305cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer2 = mock(Observer.class);
5315cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5325cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer1);
5335cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner2, observer2);
5345cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5355cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("1");
5365cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5375cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
5385cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5395cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1).onChanged("1");
5405cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer2, never()).onChanged(anyString());
5415cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
5425cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5435cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
5445cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void setValue_twoObserversOneStarted_liveDataBecomesActive() {
5455cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer1 = mock(Observer.class);
5465cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer2 = mock(Observer.class);
5475cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5485cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer1);
5495cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner2, observer2);
5505cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5515cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
5525cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5535cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(mActiveObserversChanged).onCall(true);
5545cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
5555cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5565cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
5575cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void setValue_twoObserversOneStopped_liveDataStaysActive() {
5585cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer1 = mock(Observer.class);
5595cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer2 = mock(Observer.class);
5605cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5615cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer1);
5625cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner2, observer2);
5635cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5645cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
5655cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START);
5665cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5675cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(mActiveObserversChanged).onCall(true);
5685cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5695cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(mActiveObserversChanged);
5705cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
5715cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5725cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
5735cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
5745cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5755cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    /**
5765cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     * Verifies that if a lifecycle's state changes without an event, and changes to something that
5775cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     * LiveData would become inactive in response to, LiveData will detect the change upon new data
5785cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     * being set and become inactive.  Also verifies that once the lifecycle enters into a state
5795cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     * that LiveData should become active to, that it does indeed become active.
5805cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     */
5815cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
5825cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void liveDataActiveStateIsManagedCorrectlyWithoutEvent_oneObserver() {
5835cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer = (Observer<String>) mock(Observer.class);
5845cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer);
5855cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5865cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
5875cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
588a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        // Marking state as CREATED should call onInactive.
5895cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(mActiveObserversChanged);
5905cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.markState(Lifecycle.State.CREATED);
591a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        verify(mActiveObserversChanged).onCall(false);
592a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        reset(mActiveObserversChanged);
5935cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
5945cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // Setting a new value should trigger LiveData to realize the Lifecycle it is observing
5955cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // is in a state where the LiveData should be inactive, so the LiveData will call onInactive
5965cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // and the Observer shouldn't be affected.
5975cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("1");
598a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar
599a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        // state is already CREATED so should not call again
600a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
6015cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer, never()).onChanged(anyString());
6025cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
603a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        // Sanity check.  Because we've only marked the state as CREATED, sending ON_START
604a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        // should re-dispatch events.
6055cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(mActiveObserversChanged);
6065cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(observer);
6075cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
6085cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(mActiveObserversChanged).onCall(true);
6095cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer).onChanged("1");
6105cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
6115cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
6125cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    /**
6135cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     *  This test verifies that LiveData will detect changes in LifecycleState that would make it
6145cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     *  inactive upon the setting of new data, but only if all of the Lifecycles it's observing
6155cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     *  are all in those states.  It also makes sure that once it is inactive, that it will become
6165cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     *  active again once one of the lifecycles it's observing moves to an appropriate state.
6175cfbb5dc6b92d9901a83628aec597acceb831916shepshapard     */
6185cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    @Test
6195cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    public void liveDataActiveStateIsManagedCorrectlyWithoutEvent_twoObservers() {
6205cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer1 = mock(Observer.class);
6215cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        Observer<String> observer2 = mock(Observer.class);
6225cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
6235cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner, observer1);
6245cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.observe(mOwner2, observer2);
6255cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
6265cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
6275cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START);
6285cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
6295cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // Marking the state to created won't change LiveData to be inactive.
6305cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(mActiveObserversChanged);
6315cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.markState(Lifecycle.State.CREATED);
6325cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
6335cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
6345cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // After setting a value, the LiveData will stay active because there is still a STARTED
6355cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // lifecycle being observed.  The one Observer associated with the STARTED lifecycle will
6365cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // also have been called, but the other Observer will not have been called.
6375cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(observer1);
6385cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(observer2);
6395cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("1");
6405cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
6415cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1, never()).onChanged(anyString());
6425cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer2).onChanged("1");
6435cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
644a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        // Now we set the other Lifecycle to be inactive, live data should become inactive.
6455cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(observer1);
6465cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        reset(observer2);
6475cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry2.markState(Lifecycle.State.CREATED);
648a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        verify(mActiveObserversChanged).onCall(false);
6495cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1, never()).onChanged(anyString());
6505cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer2, never()).onChanged(anyString());
6515cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
652a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        // Now we post another value, because both lifecycles are in the Created state, live data
653a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        // will not dispatch any values
654a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        reset(mActiveObserversChanged);
6555cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mLiveData.setValue("2");
656a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
6575cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1, never()).onChanged(anyString());
6585cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer2, never()).onChanged(anyString());
6595cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
6605cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // Now that the first Lifecycle has been moved back to the Resumed state, the LiveData will
6615cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // be made active and it's associated Observer will be called with the new value, but the
6625cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // Observer associated with the Lifecycle that is still in the Created state won't be
6635cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        // called.
664a3e03220c47cf14088ac23de6eb535cf45012109Yigit Boyar        reset(mActiveObserversChanged);
6655cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
6665cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(mActiveObserversChanged).onCall(true);
6675cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer1).onChanged("2");
6685cfbb5dc6b92d9901a83628aec597acceb831916shepshapard        verify(observer2, never()).onChanged(anyString());
6695cfbb5dc6b92d9901a83628aec597acceb831916shepshapard    }
6705cfbb5dc6b92d9901a83628aec597acceb831916shepshapard
671c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @SuppressWarnings("WeakerAccess")
672c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    static class PublicLiveData<T> extends LiveData<T> {
673c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        // cannot spy due to internal calls
674c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        public MethodExec activeObserversChanged;
675c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
676c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        @Override
6774d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        protected void onActive() {
678c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            if (activeObserversChanged != null) {
6794d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                activeObserversChanged.onCall(true);
680c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            }
681c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
682c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
683c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        @Override
6844d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        protected void onInactive() {
6854d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            if (activeObserversChanged != null) {
6864d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                activeObserversChanged.onCall(false);
687c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            }
688c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
689c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
690c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
691c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    private class FailReentranceObserver<T> implements Observer<T> {
692c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        @Override
693c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        public void onChanged(@Nullable T t) {
694c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets            assertThat(mInObserver, is(false));
695c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets        }
696c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets    }
697c43ce90b803cdfa033dfc94fa4161371ed6f3ec6Sergey Vasilinets
698c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    interface MethodExec {
699c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        void onCall(boolean value);
700c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
701c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar}
702