LiveDataTest.java revision 34e5031083f735db3a395b0f6aa430880b072d71
1c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar/*
2c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar * Copyright (C) 2016 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
17c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarpackage com.android.support.lifecycle;
18c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
19c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static com.android.support.lifecycle.Lifecycle.ON_CREATE;
20c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static com.android.support.lifecycle.Lifecycle.ON_DESTROY;
21c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static com.android.support.lifecycle.Lifecycle.ON_START;
22c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static com.android.support.lifecycle.Lifecycle.ON_STOP;
23c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
24c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.hamcrest.CoreMatchers.instanceOf;
25c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.hamcrest.CoreMatchers.is;
26c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.hamcrest.MatcherAssert.assertThat;
27c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Matchers.anyBoolean;
28c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Matchers.anyString;
29c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.mock;
30c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.never;
31c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.reset;
324d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyarimport static org.mockito.Mockito.spy;
33c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.verify;
34c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.verifyNoMoreInteractions;
35c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport static org.mockito.Mockito.when;
36c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
374d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyarimport android.support.annotation.Nullable;
384d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
3934e5031083f735db3a395b0f6aa430880b072d71Yigit Boyarimport com.android.support.executors.AppToolkitTaskExecutor;
4034e5031083f735db3a395b0f6aa430880b072d71Yigit Boyarimport com.android.support.executors.TaskExecutor;
4134e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
4234e5031083f735db3a395b0f6aa430880b072d71Yigit Boyarimport org.junit.After;
43c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport org.junit.Before;
44c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarimport org.junit.Test;
45c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
46c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar@SuppressWarnings({"unchecked"})
47c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyarpublic class LiveDataTest {
48c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    private PublicLiveData<String> mLiveData;
49c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    private LifecycleProvider mProvider;
50c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    private LifecycleRegistry mRegistry;
51c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    private MethodExec mActiveObserversChanged;
52c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
53c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Before
54c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void init() {
55c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData = new PublicLiveData<>();
56c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mProvider = mock(LifecycleProvider.class);
57c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry = new LifecycleRegistry(mProvider);
58c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        when(mProvider.getLifecycle()).thenReturn(mRegistry);
59c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mActiveObserversChanged = mock(MethodExec.class);
60c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.activeObserversChanged = mActiveObserversChanged;
61c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
62c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
6334e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    @Before
6434e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    public void swapExecutorDelegate() {
6534e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar        TaskExecutor taskExecutor = new TaskExecutor() {
6634e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            @Override
6734e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            public void executeOnDiskIO(Runnable runnable) {
6834e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar                runnable.run();
6934e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            }
7034e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
7134e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            @Override
7234e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            public void executeOnMainThread(Runnable runnable) {
7334e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar                runnable.run();
7434e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            }
7534e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
7634e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            @Override
7734e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            public boolean isMainThread() {
7834e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar                return true;
7934e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar            }
8034e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar        };
8134e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar        AppToolkitTaskExecutor.getInstance().setDelegate(taskExecutor);
8234e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    }
8334e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
8434e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    @After
8534e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    public void removeExecutorDelegate() {
8634e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar        AppToolkitTaskExecutor.getInstance().setDelegate(null);
8734e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    }
8834e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
89c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
90c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testObserverToggle() {
91c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
92c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
93c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
94c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
954d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
964d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
97c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
98c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
99c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
1004d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
1014d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
102c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
103c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
104c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
105c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testActiveObserverToggle() {
106c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
107c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
108c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
109c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
1104d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
1114d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
112c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
113c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
114c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
1154d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(1));
1164d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
117c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
118c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
119c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
1204d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
1214d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
122c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1234d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
124c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
125c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
1264d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(1));
1274d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
128c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1294d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
130c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
131c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
1324d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
1334d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
134c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1354d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verifyNoMoreInteractions(mActiveObserversChanged);
136c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
137c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
138c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
139c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testReAddSameObserverTuple() {
140c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
141c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
142c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
1434d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
144c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
145c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
146c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
147c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testAdd2ObserversWithSameProviderAndRemove() {
148c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> o1 = (Observer<String>) mock(Observer.class);
149c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> o2 = (Observer<String>) mock(Observer.class);
150c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, o1);
151c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, o2);
1524d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(2));
153c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
154c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
155c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
156c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
157c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("a");
158c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(o1).onChanged("a");
159c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(o2).onChanged("a");
160c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
161c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObservers(mProvider);
162c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1634d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
164c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(0));
165c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
166c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
167c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
168c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testAddSameObserverIn2LifecycleProviders() {
169c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
170c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        LifecycleProvider provider2 = mock(LifecycleProvider.class);
171c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        LifecycleRegistry registry2 = new LifecycleRegistry(provider2);
172c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        when(provider2.getLifecycle()).thenReturn(registry2);
173c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
174c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
175c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Throwable throwable = null;
176c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        try {
177c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            mLiveData.observe(provider2, observer);
178c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        } catch (Throwable t) {
179c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            throwable = t;
180c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
181c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(throwable, instanceOf(IllegalArgumentException.class));
182c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(throwable.getMessage(),
183c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar                is("Cannot add the same observer twice to the LiveData"));
184c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
185c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
186c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
187c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testRemoveDestroyedObserver() {
188c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
189c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
190c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
191c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
1924d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
1934d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(1));
1944d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
1954d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
196c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
197c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
1984d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
1994d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
200c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
201c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
202c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
203c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
204c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testInactiveRegistry() {
205c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
206c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
207c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
2084d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
209c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
210c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
211c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
212c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testNotifyActiveInactive() {
213c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
214c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
215c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
216c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("a");
217c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged(anyString());
218c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
219c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("a");
220c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
221c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("b");
222c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("b");
223c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
224c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
225c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("c");
226c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged("c");
227c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
228c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
229c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("c");
230c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
231c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        reset(observer);
232c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
233c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
234c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged(anyString());
235c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
236c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
237c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
238c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testStopObservingProvider_onDestroy() {
239c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
240c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
241c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
242c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(1));
243c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
244c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(0));
245c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
246c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
247c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
248c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testStopObservingProvider_onStopObserving() {
249c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
250c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
251c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
252c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(1));
253c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
254c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
255c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(0));
256c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
257c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
2584d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
2594d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testActiveChangeInCallback() {
2604d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
2614d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        Observer<String> observer = spy(new Observer<String>() {
2624d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
2634d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
2644d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                mRegistry.handleLifecycleEvent(ON_STOP);
2654d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getObserverCount(), is(1));
2664d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getActiveObserverCount(), is(1));
2674d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
2684d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
2694d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.observe(mProvider, observer);
2704d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
2714d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verify(observer).onChanged(anyString());
2724d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
2734d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
2744d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
2754d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
2764d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
2774d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testObserverRemovalInCallback() {
2784d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
2794d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        Observer<String> observer = spy(new Observer<String>() {
2804d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
2814d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
2824d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                mLiveData.removeObserver(this);
2834d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getObserverCount(), is(1));
2844d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
2854d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
2864d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.observe(mProvider, observer);
2874d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
2884d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verify(observer).onChanged(anyString());
2894d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
2904d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
2914d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
2924d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
2934d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testObserverAdditionInCallback() {
2944d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
2954d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        Observer<String> observer = spy(new Observer<String>() {
2964d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
2974d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
2984d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                mLiveData.observe(mProvider, mock(Observer.class));
2994d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getObserverCount(), is(1));
3004d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getActiveObserverCount(), is(1));
3014d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
3024d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
3034d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.observe(mProvider, observer);
3044d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
3054d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verify(observer).onChanged(anyString());
3064d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(2));
3074d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(2));
3084d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
3094d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
310c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @SuppressWarnings("WeakerAccess")
311c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    static class PublicLiveData<T> extends LiveData<T> {
312c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        // cannot spy due to internal calls
313c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        public MethodExec activeObserversChanged;
314c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        @Override
315c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        public void setValue(T value) {
316c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            super.setValue(value);
317c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
318c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
319c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        @Override
3204d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        protected void onActive() {
321c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            if (activeObserversChanged != null) {
3224d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                activeObserversChanged.onCall(true);
323c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            }
324c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
325c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
326c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        @Override
3274d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        protected void onInactive() {
3284d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            if (activeObserversChanged != null) {
3294d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                activeObserversChanged.onCall(false);
330c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            }
331c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
332c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
333c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
334c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    interface MethodExec {
335c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        void onCall(boolean value);
336c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
337c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar}
338