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