16ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets/* 26ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * Copyright (C) 2017 The Android Open Source Project 36ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * 46ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * Licensed under the Apache License, Version 2.0 (the "License"); 56ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * you may not use this file except in compliance with the License. 66ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * You may obtain a copy of the License at 76ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * 86ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * http://www.apache.org/licenses/LICENSE-2.0 96ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * 106ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * Unless required by applicable law or agreed to in writing, software 116ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * distributed under the License is distributed on an "AS IS" BASIS, 126ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * See the License for the specific language governing permissions and 146ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets * limitations under the License. 156ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets */ 166ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 17ba069d50913c3fb250bb60ec310439db36895337Alan Viverettepackage androidx.lifecycle; 186ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 196ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.hamcrest.CoreMatchers.is; 206ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.hamcrest.MatcherAssert.assertThat; 216ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.mockito.Matchers.any; 226ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.mockito.Mockito.mock; 236ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.mockito.Mockito.never; 246ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.mockito.Mockito.reset; 256ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.mockito.Mockito.verify; 266ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport static org.mockito.Mockito.when; 276ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 28ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.annotation.Nullable; 29ddee2b5170ae257a7b2494f8aaa8459ebed806dcAurimas Liutikasimport androidx.arch.core.executor.ArchTaskExecutor; 30ddee2b5170ae257a7b2494f8aaa8459ebed806dcAurimas Liutikasimport androidx.arch.core.executor.testing.InstantTaskExecutorRule; 31ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.lifecycle.util.InstantTaskExecutor; 326ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 336ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport org.junit.Before; 341e6eadb9fb537c6bd81cc6a50ab685711cd84fd9Sergey Vasilinetsimport org.junit.Rule; 356ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport org.junit.Test; 366ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport org.junit.runner.RunWith; 376ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetsimport org.junit.runners.JUnit4; 386ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 396ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets@SuppressWarnings("unchecked") 406ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets@RunWith(JUnit4.class) 416ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinetspublic class MediatorLiveDataTest { 426ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 431e6eadb9fb537c6bd81cc6a50ab685711cd84fd9Sergey Vasilinets @Rule 441e6eadb9fb537c6bd81cc6a50ab685711cd84fd9Sergey Vasilinets public InstantTaskExecutorRule mInstantTaskExecutorRule = new InstantTaskExecutorRule(); 451e6eadb9fb537c6bd81cc6a50ab685711cd84fd9Sergey Vasilinets 466ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets private LifecycleOwner mOwner; 476ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets private LifecycleRegistry mRegistry; 486ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets private MediatorLiveData<String> mMediator; 496ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets private LiveData<String> mSource; 506ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets private boolean mSourceActive; 516ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 526ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Before 536ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void setup() { 546ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mOwner = mock(LifecycleOwner.class); 556ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mRegistry = new LifecycleRegistry(mOwner); 566ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets when(mOwner.getLifecycle()).thenReturn(mRegistry); 576ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator = new MediatorLiveData<>(); 586ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource = new LiveData<String>() { 596ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Override 606ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets protected void onActive() { 616ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSourceActive = true; 626ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 636ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 646ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Override 656ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets protected void onInactive() { 666ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSourceActive = false; 676ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 686ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets }; 696ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSourceActive = false; 706ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.observe(mOwner, mock(Observer.class)); 71b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); 72b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 736ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 746ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 756ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Before 766ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void swapExecutorDelegate() { 77ae36c8b11a64d3cdc9ba6e37d9f3d1d250fdc4a8Yigit Boyar ArchTaskExecutor.getInstance().setDelegate(new InstantTaskExecutor()); 786ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 796ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 806ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 816ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testSingleDelivery() { 826ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer = mock(Observer.class); 836ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer); 846ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("flatfoot"); 856ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer).onChanged("flatfoot"); 86b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 876ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets reset(observer); 886ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer, never()).onChanged(any()); 896ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 906ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 916ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 926ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testChangeWhileInactive() { 936ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer = mock(Observer.class); 946ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer); 956ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.observe(mOwner, mock(Observer.class)); 966ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("one"); 976ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer).onChanged("one"); 98b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 996ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets reset(observer); 1006ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("flatfoot"); 101b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 1026ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer).onChanged("flatfoot"); 1036ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 1046ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 1056ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 1066ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 1076ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testAddSourceToActive() { 1086ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("flatfoot"); 1096ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer = mock(Observer.class); 1106ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer); 1116ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer).onChanged("flatfoot"); 1126ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 1136ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 1146ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 1156ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testAddSourceToInActive() { 1166ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("flatfoot"); 117b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 1186ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer = mock(Observer.class); 1196ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer); 1206ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer, never()).onChanged(any()); 121b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 1226ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer).onChanged("flatfoot"); 1236ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 1246ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 1256ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 1266ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testRemoveSource() { 1276ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("flatfoot"); 1286ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer = mock(Observer.class); 1296ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer); 1306ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer).onChanged("flatfoot"); 1316ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.removeSource(mSource); 1326ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets reset(observer); 1336ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("failure"); 1346ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer, never()).onChanged(any()); 1356ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 1366ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 1376ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 1386ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testSourceInactive() { 1396ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer = mock(Observer.class); 1406ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer); 1416ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets assertThat(mSourceActive, is(true)); 142b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 1436ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets assertThat(mSourceActive, is(false)); 144b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 1456ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets assertThat(mSourceActive, is(true)); 1466ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 1476ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 1486ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 1496ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testNoLeakObserver() { 1506ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets // Imitates a destruction of a ViewModel: a listener of LiveData is destroyed, 1516ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets // a reference to MediatorLiveData is cleaned up. In this case we shouldn't leak 1526ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets // MediatorLiveData as an observer of mSource. 153abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mSource.hasObservers(), is(false)); 1546ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer = mock(Observer.class); 1556ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer); 156abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mSource.hasObservers(), is(true)); 157b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 158b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY); 1596ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator = null; 160abf6c87826e1a86fed71d945dc7e7f1aa643ea6cSergey Vasilinets assertThat(mSource.hasObservers(), is(false)); 1616ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 1626ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets 1636ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets @Test 1646ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets public void testMultipleSources() { 1656ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer1 = mock(Observer.class); 1666ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(mSource, observer1); 1676ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets MutableLiveData<Integer> source2 = new MutableLiveData<>(); 1686ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets Observer observer2 = mock(Observer.class); 1696ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mMediator.addSource(source2, observer2); 1706ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("flatfoot"); 1716ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer1).onChanged("flatfoot"); 1726ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer2, never()).onChanged(any()); 1736ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets reset(observer1, observer2); 1746ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets source2.setValue(1703); 1756ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer1, never()).onChanged(any()); 1766ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer2).onChanged(1703); 1776ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets reset(observer1, observer2); 178b86bef286718da421268bc52cf4fab7cccb3104cSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 1796ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets mSource.setValue("failure"); 1806ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets source2.setValue(0); 1816ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer1, never()).onChanged(any()); 1826ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets verify(observer2, never()).onChanged(any()); 1836ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets } 1847b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets 1857b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets @Test 1867b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets public void removeSourceDuringOnActive() { 1877b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets // to trigger ConcurrentModificationException, 1887b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets // we have to call remove from a collection during "for" loop. 1897b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets // ConcurrentModificationException is thrown from next() method of an iterator 1907b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets // so this modification shouldn't be at the last iteration, 1917b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets // because if it is a last iteration, then next() wouldn't be called. 1927b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets // And the last: an order of an iteration over sources is not defined, 1937b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets // so I have to call it remove operation from all observers. 1947b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 1957b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets Observer<String> removingObserver = new Observer<String>() { 1967b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets @Override 1977b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets public void onChanged(@Nullable String s) { 1987b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.removeSource(mSource); 1997b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets } 2007b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets }; 2017b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.addSource(mSource, removingObserver); 2027b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets MutableLiveData<String> source2 = new MutableLiveData<>(); 2037b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets source2.setValue("nana"); 2047b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.addSource(source2, removingObserver); 2057b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mSource.setValue("petjack"); 2067b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 2077b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets } 2087b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets 2097b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets @Test(expected = IllegalArgumentException.class) 2107b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets public void reAddSameSourceWithDifferentObserver() { 2117b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.addSource(mSource, mock(Observer.class)); 2127b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.addSource(mSource, mock(Observer.class)); 2137b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets } 2147b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets 2157b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets @Test 21694209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets public void addSameSourceWithSameObserver() { 21794209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets Observer observer = mock(Observer.class); 21894209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets mMediator.addSource(mSource, observer); 21994209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets mMediator.addSource(mSource, observer); 22094209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets // no exception was thrown 22194209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets } 22294209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets 22394209fa7c603b9b0e226ce7e351461a479b5b595Sergey Vasilinets @Test 2247b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets public void addSourceDuringOnActive() { 2257b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 2267b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mSource.setValue("a"); 2277b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.addSource(mSource, new Observer<String>() { 2287b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets @Override 2297b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets public void onChanged(@Nullable String s) { 2307b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets MutableLiveData<String> source = new MutableLiveData<>(); 2317b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets source.setValue("b"); 2327b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.addSource(source, new Observer<String>() { 2337b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets @Override 2347b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets public void onChanged(@Nullable String s) { 2357b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mMediator.setValue("c"); 2367b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets } 2377b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets }); 2387b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets } 2397b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets }); 2407b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 2417b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets assertThat(mMediator.getValue(), is("c")); 2427b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets } 2437b81f6101e2c1c68108243688f7d1d7302d1179eSergey Vasilinets 2446ca8525782f16bcb4403dc692a1fefd77934aa31Sergey Vasilinets} 245