LiveDataTest.java revision 7c41ee306fc78feaa0043c65bf82e65935bd9d35
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;
4036436741fe52fa90bbeeddf7baa05f97d734f5f1Yigit Boyarimport com.android.support.lifecycle.util.InstantTaskExecutor;
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() {
6536436741fe52fa90bbeeddf7baa05f97d734f5f1Yigit Boyar        AppToolkitTaskExecutor.getInstance().setDelegate(new InstantTaskExecutor());
6634e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    }
6734e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
6834e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    @After
6934e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    public void removeExecutorDelegate() {
7034e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar        AppToolkitTaskExecutor.getInstance().setDelegate(null);
7134e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar    }
7234e5031083f735db3a395b0f6aa430880b072d71Yigit Boyar
73c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
74c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testObserverToggle() {
75c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
76c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
77c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
78c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
794d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
804d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
81c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
82c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
83c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
844d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
854d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
86c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
87c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
88c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
89c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testActiveObserverToggle() {
90c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
91c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
92c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
93c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
944d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
954d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
96c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
97c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
98c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
994d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(1));
1004d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
101c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
102c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
103c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
1044d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
1054d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
106c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1074d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
108c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
109c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
1104d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(1));
1114d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
112c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1134d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
114c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
115c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
1164d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
1174d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
118c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1194d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verifyNoMoreInteractions(mActiveObserversChanged);
120c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
121c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
122c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
123c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testReAddSameObserverTuple() {
124c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
125c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
126c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
1274d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
128c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
129c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
130c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
131c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testAdd2ObserversWithSameProviderAndRemove() {
132c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> o1 = (Observer<String>) mock(Observer.class);
133c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> o2 = (Observer<String>) mock(Observer.class);
134c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, o1);
135c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, o2);
1364d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(2));
137c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged, never()).onCall(anyBoolean());
138c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
139c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
140c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
141c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("a");
142c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(o1).onChanged("a");
143c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(o2).onChanged("a");
144c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
145c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObservers(mProvider);
146c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
1474d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
148c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(0));
149c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
150c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
151c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
152c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testAddSameObserverIn2LifecycleProviders() {
153c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
154c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        LifecycleProvider provider2 = mock(LifecycleProvider.class);
155c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        LifecycleRegistry registry2 = new LifecycleRegistry(provider2);
156c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        when(provider2.getLifecycle()).thenReturn(registry2);
157c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
158c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
159c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Throwable throwable = null;
160c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        try {
161c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            mLiveData.observe(provider2, observer);
162c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        } catch (Throwable t) {
163c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar            throwable = t;
164c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        }
165c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(throwable, instanceOf(IllegalArgumentException.class));
166c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(throwable.getMessage(),
167c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar                is("Cannot add the same observer twice to the LiveData"));
168c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
169c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
170c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
171c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testRemoveDestroyedObserver() {
172c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
173c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
174c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
175c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(true);
1764d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
1774d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(1));
1784d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
1794d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        reset(mActiveObserversChanged);
180c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
181c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
1824d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
1834d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
184c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(mActiveObserversChanged).onCall(false);
185c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
186c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
187c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
188c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testInactiveRegistry() {
189c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
190c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
191c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
1924d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
193c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
194c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
195c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
196c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testNotifyActiveInactive() {
197c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
198c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
199c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
200c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("a");
201c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged(anyString());
202c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
203c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("a");
204c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
205c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("b");
206c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("b");
207c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
208c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
209c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.setValue("c");
210c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged("c");
211c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
212c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
213c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer).onChanged("c");
214c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
215c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        reset(observer);
216c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_STOP);
217c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
218c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        verify(observer, never()).onChanged(anyString());
219c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
220c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
221c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
222c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testStopObservingProvider_onDestroy() {
223c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
224c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
225c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
226c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(1));
227c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_DESTROY);
228c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(0));
229c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
230c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
231c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    @Test
232c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    public void testStopObservingProvider_onStopObserving() {
233c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        Observer<String> observer = (Observer<String>) mock(Observer.class);
234c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mRegistry.handleLifecycleEvent(ON_CREATE);
235c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.observe(mProvider, observer);
236c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(1));
237c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
238c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        mLiveData.removeObserver(observer);
239c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar        assertThat(mRegistry.size(), is(0));
240c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar    }
241c1b53ee5d095a74b84c21257fb4cd00e33f748baYigit Boyar
2424d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
2434d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testActiveChangeInCallback() {
2444d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
2454d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        Observer<String> observer = spy(new Observer<String>() {
2464d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
2474d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
2484d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                mRegistry.handleLifecycleEvent(ON_STOP);
2494d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getObserverCount(), is(1));
2504d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getActiveObserverCount(), is(1));
2514d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
2524d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
2534d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.observe(mProvider, observer);
2544d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
2554d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verify(observer).onChanged(anyString());
2564d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(1));
2574d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(0));
2584d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
2594d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
2604d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
2614d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testObserverRemovalInCallback() {
2624d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mRegistry.handleLifecycleEvent(ON_START);
2634d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        Observer<String> observer = spy(new Observer<String>() {
2644d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            @Override
2654d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            public void onChanged(@Nullable String s) {
2664d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                mLiveData.removeObserver(this);
2674d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getObserverCount(), is(1));
2684d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
2694d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
2704d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.observe(mProvider, observer);
2714d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
2724d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verify(observer).onChanged(anyString());
2734d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(0));
2744d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
2754d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
2764d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    @Test
2774d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    public void testObserverAdditionInCallback() {
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.observe(mProvider, mock(Observer.class));
2834d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getObserverCount(), is(1));
2844d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar                assertThat(mLiveData.getActiveObserverCount(), is(1));
2854d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar            }
2864d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        });
2874d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.observe(mProvider, observer);
2884d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        mLiveData.setValue("bla");
2894d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        verify(observer).onChanged(anyString());
2904d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getObserverCount(), is(2));
2914d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar        assertThat(mLiveData.getActiveObserverCount(), is(2));
2924d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar    }
2934d4bf0391459bec361ec7843447ae60d38c99028Yigit Boyar
2947c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets    @Test
2957c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets    public void testObserverWithoutLifecycleProvider() {
2967c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        Observer<String> observer = (Observer<String>) mock(Observer.class);
2977c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.setValue("boring");
2987c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.observe(observer);
2997c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(mActiveObserversChanged).onCall(true);
3007c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(observer).onChanged("boring");
3017c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.setValue("tihs");
3027c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(observer).onChanged("tihs");
3037c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.removeObserver(observer);
3047c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(mActiveObserversChanged).onCall(false);
3057c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        mLiveData.setValue("boring");
3067c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        reset(observer);
3077c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets        verify(observer, never()).onChanged(anyString());
3087c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets    }
3097c41ee306fc78feaa0043c65bf82e65935bd9d35Sergey Vasilinets
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