MediatorLiveDataTest.java revision 6ca8525782f16bcb4403dc692a1fefd77934aa31
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.support.lifecycle; 18 19import static org.hamcrest.CoreMatchers.is; 20import static org.hamcrest.MatcherAssert.assertThat; 21import static org.mockito.Matchers.any; 22import static org.mockito.Mockito.mock; 23import static org.mockito.Mockito.never; 24import static org.mockito.Mockito.reset; 25import static org.mockito.Mockito.verify; 26import static org.mockito.Mockito.when; 27 28import android.support.test.filters.SmallTest; 29 30import com.android.support.executors.AppToolkitTaskExecutor; 31import com.android.support.lifecycle.util.InstantTaskExecutor; 32 33import org.junit.Before; 34import org.junit.Test; 35import org.junit.runner.RunWith; 36import org.junit.runners.JUnit4; 37 38@SuppressWarnings("unchecked") 39@SmallTest 40@RunWith(JUnit4.class) 41public class MediatorLiveDataTest { 42 43 private LifecycleOwner mOwner; 44 private LifecycleRegistry mRegistry; 45 private MediatorLiveData<String> mMediator; 46 private LiveData<String> mSource; 47 private boolean mSourceActive; 48 49 @Before 50 public void setup() { 51 mOwner = mock(LifecycleOwner.class); 52 mRegistry = new LifecycleRegistry(mOwner); 53 when(mOwner.getLifecycle()).thenReturn(mRegistry); 54 mMediator = new MediatorLiveData<>(); 55 mSource = new LiveData<String>() { 56 @Override 57 protected void onActive() { 58 mSourceActive = true; 59 } 60 61 @Override 62 protected void onInactive() { 63 mSourceActive = false; 64 } 65 }; 66 mSourceActive = false; 67 mMediator.observe(mOwner, mock(Observer.class)); 68 mRegistry.handleLifecycleEvent(Lifecycle.ON_CREATE); 69 mRegistry.handleLifecycleEvent(Lifecycle.ON_START); 70 } 71 72 @Before 73 public void swapExecutorDelegate() { 74 AppToolkitTaskExecutor.getInstance().setDelegate(new InstantTaskExecutor()); 75 } 76 77 @Test 78 public void testSingleDelivery() { 79 Observer observer = mock(Observer.class); 80 mMediator.addSource(mSource, observer); 81 mSource.setValue("flatfoot"); 82 verify(observer).onChanged("flatfoot"); 83 mRegistry.handleLifecycleEvent(Lifecycle.ON_STOP); 84 reset(observer); 85 verify(observer, never()).onChanged(any()); 86 } 87 88 @Test 89 public void testChangeWhileInactive() { 90 Observer observer = mock(Observer.class); 91 mMediator.addSource(mSource, observer); 92 mMediator.observe(mOwner, mock(Observer.class)); 93 mSource.setValue("one"); 94 verify(observer).onChanged("one"); 95 mRegistry.handleLifecycleEvent(Lifecycle.ON_STOP); 96 reset(observer); 97 mSource.setValue("flatfoot"); 98 mRegistry.handleLifecycleEvent(Lifecycle.ON_START); 99 verify(observer).onChanged("flatfoot"); 100 } 101 102 103 @Test 104 public void testAddSourceToActive() { 105 mSource.setValue("flatfoot"); 106 Observer observer = mock(Observer.class); 107 mMediator.addSource(mSource, observer); 108 verify(observer).onChanged("flatfoot"); 109 } 110 111 @Test 112 public void testAddSourceToInActive() { 113 mSource.setValue("flatfoot"); 114 mRegistry.handleLifecycleEvent(Lifecycle.ON_STOP); 115 Observer observer = mock(Observer.class); 116 mMediator.addSource(mSource, observer); 117 verify(observer, never()).onChanged(any()); 118 mRegistry.handleLifecycleEvent(Lifecycle.ON_START); 119 verify(observer).onChanged("flatfoot"); 120 } 121 122 @Test 123 public void testRemoveSource() { 124 mSource.setValue("flatfoot"); 125 Observer observer = mock(Observer.class); 126 mMediator.addSource(mSource, observer); 127 verify(observer).onChanged("flatfoot"); 128 mMediator.removeSource(mSource); 129 reset(observer); 130 mSource.setValue("failure"); 131 verify(observer, never()).onChanged(any()); 132 } 133 134 @Test 135 public void testSourceInactive() { 136 Observer observer = mock(Observer.class); 137 mMediator.addSource(mSource, observer); 138 assertThat(mSourceActive, is(true)); 139 mRegistry.handleLifecycleEvent(Lifecycle.ON_STOP); 140 assertThat(mSourceActive, is(false)); 141 mRegistry.handleLifecycleEvent(Lifecycle.ON_START); 142 assertThat(mSourceActive, is(true)); 143 } 144 145 @Test 146 public void testNoLeakObserver() { 147 // Imitates a destruction of a ViewModel: a listener of LiveData is destroyed, 148 // a reference to MediatorLiveData is cleaned up. In this case we shouldn't leak 149 // MediatorLiveData as an observer of mSource. 150 assertThat(mSource.getObserverCount(), is(0)); 151 Observer observer = mock(Observer.class); 152 mMediator.addSource(mSource, observer); 153 assertThat(mSource.getObserverCount(), is(1)); 154 mRegistry.handleLifecycleEvent(Lifecycle.ON_STOP); 155 mRegistry.handleLifecycleEvent(Lifecycle.ON_DESTROY); 156 mMediator = null; 157 assertThat(mSource.getObserverCount(), is(0)); 158 } 159 160 @Test 161 public void testMultipleSources() { 162 Observer observer1 = mock(Observer.class); 163 mMediator.addSource(mSource, observer1); 164 MutableLiveData<Integer> source2 = new MutableLiveData<>(); 165 Observer observer2 = mock(Observer.class); 166 mMediator.addSource(source2, observer2); 167 mSource.setValue("flatfoot"); 168 verify(observer1).onChanged("flatfoot"); 169 verify(observer2, never()).onChanged(any()); 170 reset(observer1, observer2); 171 source2.setValue(1703); 172 verify(observer1, never()).onChanged(any()); 173 verify(observer2).onChanged(1703); 174 reset(observer1, observer2); 175 mRegistry.handleLifecycleEvent(Lifecycle.ON_STOP); 176 mSource.setValue("failure"); 177 source2.setValue(0); 178 verify(observer1, never()).onChanged(any()); 179 verify(observer2, never()).onChanged(any()); 180 } 181} 182