LoaderInfoTest.java revision 617e99e5839e535d95d51b8512366ca911a6519d
1/* 2 * Copyright 2018 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 androidx.loader.app; 18 19import static org.junit.Assert.assertFalse; 20import static org.junit.Assert.assertTrue; 21import static org.mockito.Mockito.mock; 22import static org.mockito.Mockito.when; 23 24import android.content.Context; 25import android.support.test.InstrumentationRegistry; 26import android.support.test.annotation.UiThreadTest; 27import android.support.test.filters.SmallTest; 28import android.support.test.runner.AndroidJUnit4; 29 30import androidx.lifecycle.Lifecycle; 31import androidx.lifecycle.LifecycleOwner; 32import androidx.lifecycle.LifecycleRegistry; 33import androidx.loader.app.test.DelayLoader; 34import androidx.loader.app.test.DummyLoaderCallbacks; 35import androidx.loader.content.Loader; 36 37import org.junit.Before; 38import org.junit.Test; 39import org.junit.runner.RunWith; 40 41import java.util.concurrent.CountDownLatch; 42import java.util.concurrent.TimeUnit; 43 44@RunWith(AndroidJUnit4.class) 45@SmallTest 46public class LoaderInfoTest { 47 48 private LifecycleOwner mOwner; 49 private LifecycleRegistry mRegistry; 50 51 @Before 52 public void setup() { 53 mOwner = mock(LifecycleOwner.class); 54 mRegistry = new LifecycleRegistry(mOwner); 55 when(mOwner.getLifecycle()).thenReturn(mRegistry); 56 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); 57 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 58 } 59 60 @Test 61 public void testIsCallbackWaitingForData() throws Throwable { 62 final DummyLoaderCallbacks loaderCallback = new DummyLoaderCallbacks(mock(Context.class)); 63 final CountDownLatch deliverResultLatch = new CountDownLatch(1); 64 Loader<Boolean> delayLoader = new DelayLoader(mock(Context.class), 65 deliverResultLatch); 66 final LoaderManagerImpl.LoaderInfo<Boolean> loaderInfo = new LoaderManagerImpl.LoaderInfo<>( 67 0, null, delayLoader, null); 68 assertFalse("isCallbackWaitingForData should be false before setCallback", 69 loaderInfo.isCallbackWaitingForData()); 70 71 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 72 @Override 73 public void run() { 74 loaderInfo.setCallback(mOwner, loaderCallback); 75 } 76 }); 77 assertTrue("isCallbackWaitingForData should be true immediately after setCallback", 78 loaderInfo.isCallbackWaitingForData()); 79 80 assertTrue("Loader timed out delivering results", 81 deliverResultLatch.await(1, TimeUnit.SECONDS)); 82 // Results are posted to the UI thread, so we wait for them there 83 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 84 @Override 85 public void run() { 86 assertTrue("onLoadFinished should be called after setCallback", 87 loaderCallback.mOnLoadFinished); 88 assertFalse("isCallbackWaitingForData should be false after onLoadFinished", 89 loaderInfo.isCallbackWaitingForData()); 90 } 91 }); 92 } 93 94 @UiThreadTest 95 @Test 96 public void testSetCallback() throws Throwable { 97 final DummyLoaderCallbacks loaderCallback = new DummyLoaderCallbacks(mock(Context.class)); 98 Loader<Boolean> loader = loaderCallback.onCreateLoader(0, null); 99 final LoaderManagerImpl.LoaderInfo<Boolean> loaderInfo = new LoaderManagerImpl.LoaderInfo<>( 100 0, null, loader, null); 101 assertFalse("onLoadFinished shouldn't be called before setCallback", 102 loaderCallback.mOnLoadFinished); 103 104 loaderInfo.setCallback(mOwner, loaderCallback); 105 assertTrue("onLoadFinished should be called after setCallback", 106 loaderCallback.mOnLoadFinished); 107 } 108 109 @UiThreadTest 110 @Test 111 public void testSetCallback_replace() throws Throwable { 112 final DummyLoaderCallbacks initialCallback = new DummyLoaderCallbacks(mock(Context.class)); 113 Loader<Boolean> loader = initialCallback.onCreateLoader(0, null); 114 LoaderManagerImpl.LoaderInfo<Boolean> loaderInfo = new LoaderManagerImpl.LoaderInfo<>( 115 0, null, loader, null); 116 assertFalse("onLoadFinished for initial shouldn't be called before setCallback initial", 117 initialCallback.mOnLoadFinished); 118 119 loaderInfo.setCallback(mOwner, initialCallback); 120 assertTrue("onLoadFinished for initial should be called after setCallback initial", 121 initialCallback.mOnLoadFinished); 122 123 final DummyLoaderCallbacks replacementCallback = 124 new DummyLoaderCallbacks(mock(Context.class)); 125 initialCallback.mOnLoadFinished = false; 126 127 loaderInfo.setCallback(mOwner, replacementCallback); 128 assertFalse("onLoadFinished for initial should not be called " 129 + "after setCallback replacement", 130 initialCallback.mOnLoadFinished); 131 assertTrue("onLoadFinished for replacement should be called " 132 + " after setCallback replacement", 133 replacementCallback.mOnLoadFinished); 134 } 135 136 @UiThreadTest 137 @Test 138 public void testMarkForRedelivery() throws Throwable { 139 DummyLoaderCallbacks loaderCallback = 140 new DummyLoaderCallbacks(mock(Context.class)); 141 Loader<Boolean> loader = loaderCallback.onCreateLoader(0, null); 142 LoaderManagerImpl.LoaderInfo<Boolean> loaderInfo = new LoaderManagerImpl.LoaderInfo<>( 143 0, null, loader, null); 144 loaderInfo.setCallback(mOwner, loaderCallback); 145 assertTrue("onLoadFinished should be called after setCallback", 146 loaderCallback.mOnLoadFinished); 147 148 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 149 loaderCallback.mOnLoadFinished = false; 150 loaderInfo.markForRedelivery(); 151 assertFalse("onLoadFinished should not be called when stopped after markForRedelivery", 152 loaderCallback.mOnLoadFinished); 153 154 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 155 assertTrue("onLoadFinished should be called after markForRedelivery", 156 loaderCallback.mOnLoadFinished); 157 } 158 159 @UiThreadTest 160 @Test 161 public void testMarkForRedelivery_replace() throws Throwable { 162 DummyLoaderCallbacks initialCallback = 163 new DummyLoaderCallbacks(mock(Context.class)); 164 Loader<Boolean> loader = initialCallback.onCreateLoader(0, null); 165 LoaderManagerImpl.LoaderInfo<Boolean> loaderInfo = new LoaderManagerImpl.LoaderInfo<>( 166 0, null, loader, null); 167 loaderInfo.setCallback(mOwner, initialCallback); 168 assertTrue("onLoadFinished for initial should be called after setCallback initial", 169 initialCallback.mOnLoadFinished); 170 171 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); 172 initialCallback.mOnLoadFinished = false; 173 loaderInfo.markForRedelivery(); 174 assertFalse("onLoadFinished should not be called when stopped after markForRedelivery", 175 initialCallback.mOnLoadFinished); 176 177 // Replace the callback 178 final DummyLoaderCallbacks replacementCallback = 179 new DummyLoaderCallbacks(mock(Context.class)); 180 loaderInfo.setCallback(mOwner, replacementCallback); 181 182 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); 183 assertFalse("onLoadFinished for initial should not be called " 184 + "after setCallback replacement", 185 initialCallback.mOnLoadFinished); 186 assertTrue("onLoadFinished for replacement should be called " 187 + " after setCallback replacement", 188 replacementCallback.mOnLoadFinished); 189 } 190 191 @UiThreadTest 192 @Test 193 public void testDestroy() throws Throwable { 194 final DummyLoaderCallbacks loaderCallback = new DummyLoaderCallbacks(mock(Context.class)); 195 final Loader<Boolean> loader = loaderCallback.onCreateLoader(0, null); 196 final LoaderManagerImpl.LoaderInfo<Boolean> loaderInfo = new LoaderManagerImpl.LoaderInfo<>( 197 0, null, loader, null); 198 199 loaderInfo.setCallback(mOwner, loaderCallback); 200 assertTrue("Loader should be started after setCallback", loader.isStarted()); 201 loaderInfo.destroy(true); 202 assertFalse("Loader should not be started after destroy", loader.isStarted()); 203 } 204} 205