diff options
Diffstat (limited to 'library/src')
14 files changed, 438 insertions, 130 deletions
diff --git a/library/src/main/java/com/bumptech/glide/RequestManager.java b/library/src/main/java/com/bumptech/glide/RequestManager.java index 1bc2bdad..5ac4167e 100644 --- a/library/src/main/java/com/bumptech/glide/RequestManager.java +++ b/library/src/main/java/com/bumptech/glide/RequestManager.java @@ -2,6 +2,8 @@ package com.bumptech.glide; import android.content.Context; import android.net.Uri; +import android.os.Handler; +import android.os.Looper; import android.os.ParcelFileDescriptor; import com.bumptech.glide.load.model.ModelLoader; @@ -11,6 +13,8 @@ import com.bumptech.glide.load.model.stream.StreamByteArrayLoader; import com.bumptech.glide.load.model.stream.StreamModelLoader; import com.bumptech.glide.manager.ConnectivityMonitor; import com.bumptech.glide.manager.ConnectivityMonitorFactory; +import com.bumptech.glide.manager.Lifecycle; +import com.bumptech.glide.manager.LifecycleListener; import com.bumptech.glide.manager.RequestTracker; import com.bumptech.glide.util.Util; @@ -30,25 +34,41 @@ import java.util.UUID; * @see Glide#with(android.support.v4.app.Fragment) * @see Glide#with(Context) */ -public class RequestManager { - private final ConnectivityMonitor connectivityMonitor; +public class RequestManager implements LifecycleListener { private final Context context; private final RequestTracker requestTracker; private final Glide glide; private final OptionsApplier optionsApplier; private DefaultOptions options; - public RequestManager(Context context) { - this(context, new RequestTracker(), new ConnectivityMonitorFactory()); + public RequestManager(Context context, Lifecycle lifecycle) { + this(context, lifecycle, new RequestTracker(), new ConnectivityMonitorFactory()); } - RequestManager(Context context, RequestTracker requestTracker, ConnectivityMonitorFactory factory) { + RequestManager(Context context, final Lifecycle lifecycle, RequestTracker requestTracker, + ConnectivityMonitorFactory factory) { this.context = context; this.requestTracker = requestTracker; - this.connectivityMonitor = factory.build(context, new RequestManagerConnectivityListener(requestTracker)); - connectivityMonitor.register(); this.glide = Glide.get(context); this.optionsApplier = new OptionsApplier(); + + ConnectivityMonitor connectivityMonitor = factory.build(context, + new RequestManagerConnectivityListener(requestTracker)); + + // If we're the application level request manager, we may be created on a background thread. In that case we + // cannot risk synchronously pausing or resuming requests, so we hack around the issue by delaying adding + // ourselves as a lifecycle listener by posting to the main thread. This should be entirely safe. + if (Util.isOnBackgroundThread()) { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + lifecycle.addListener(RequestManager.this); + } + }); + } else { + lifecycle.addListener(this); + } + lifecycle.addListener(connectivityMonitor); } /** @@ -103,9 +123,9 @@ public class RequestManager { * Lifecycle callback that registers for connectivity events (if the android.permission.ACCESS_NETWORK_STATE * permission is present) and restarts failed or paused requests. */ + @Override public void onStart() { // onStart might not be called because this object may be created after the fragment/activity's onStart method. - connectivityMonitor.register(); resumeRequests(); } @@ -113,8 +133,8 @@ public class RequestManager { * Lifecycle callback that unregisters for connectivity events (if the android.permission.ACCESS_NETWORK_STATE * permission is present) and pauses in progress loads. */ + @Override public void onStop() { - connectivityMonitor.unregister(); pauseRequests(); } @@ -122,6 +142,7 @@ public class RequestManager { * Lifecycle callback that cancels all in progress requests and clears and recycles resources for all completed * requests. */ + @Override public void onDestroy() { requestTracker.clearRequests(); } diff --git a/library/src/main/java/com/bumptech/glide/manager/ConnectivityMonitor.java b/library/src/main/java/com/bumptech/glide/manager/ConnectivityMonitor.java index a30c0cc0..3e219850 100644 --- a/library/src/main/java/com/bumptech/glide/manager/ConnectivityMonitor.java +++ b/library/src/main/java/com/bumptech/glide/manager/ConnectivityMonitor.java @@ -3,7 +3,7 @@ package com.bumptech.glide.manager; /** * An interface for monitoring network connectivity events. */ -public interface ConnectivityMonitor { +public interface ConnectivityMonitor extends LifecycleListener { /** * An interface for listening to network connectivity events picked up by the monitor. @@ -16,14 +16,4 @@ public interface ConnectivityMonitor { */ public void onConnectivityChanged(boolean isConnected); } - - /** - * Indicates the monitor should register itself to listen to connectivity events. - */ - public void register(); - - /** - * Indicates the monitor should unregister itself and stop listening to connectivity events. - */ - public void unregister(); } diff --git a/library/src/main/java/com/bumptech/glide/manager/DefaultConnectivityMonitor.java b/library/src/main/java/com/bumptech/glide/manager/DefaultConnectivityMonitor.java index 8d993f17..aa194c4c 100644 --- a/library/src/main/java/com/bumptech/glide/manager/DefaultConnectivityMonitor.java +++ b/library/src/main/java/com/bumptech/glide/manager/DefaultConnectivityMonitor.java @@ -30,8 +30,7 @@ class DefaultConnectivityMonitor implements ConnectivityMonitor { this.listener = listener; } - @Override - public void register() { + private void register() { if (isRegistered) { return; } @@ -41,8 +40,7 @@ class DefaultConnectivityMonitor implements ConnectivityMonitor { isRegistered = true; } - @Override - public void unregister() { + private void unregister() { if (!isRegistered) { return; } @@ -57,4 +55,19 @@ class DefaultConnectivityMonitor implements ConnectivityMonitor { NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } + + @Override + public void onStart() { + register(); + } + + @Override + public void onStop() { + unregister(); + } + + @Override + public void onDestroy() { + // Do nothing. + } } diff --git a/library/src/main/java/com/bumptech/glide/manager/Lifecycle.java b/library/src/main/java/com/bumptech/glide/manager/Lifecycle.java new file mode 100644 index 00000000..cc2bd8c4 --- /dev/null +++ b/library/src/main/java/com/bumptech/glide/manager/Lifecycle.java @@ -0,0 +1,64 @@ +package com.bumptech.glide.manager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * A class for tracking and notifying listeners of {@link android.app.Fragment} and {@link android.app.Activity} + * lifecycle events. + */ +public class Lifecycle { + private final List<LifecycleListener> lifecycleListeners = + Collections.synchronizedList(new ArrayList<LifecycleListener>()); + private boolean isStarted; + private boolean isDestroyed; + + /** + * Adds the given listener to the list of listeners to be notified on each lifecycle event. + * + * <p> + * The latest lifecycle event will be called on the given listener synchronously in this method. If the + * activity or fragment is stopped, {@link LifecycleListener#onStop()}} will be called, and same for onStart and + * onDestroy. + * </p> + * + * <p> + * Note - {@link com.bumptech.glide.manager.LifecycleListener}s that are added more than once will have their + * lifecycle methods called more than once. It is the caller's responsibility to avoid adding listeners + * multiple times. + * </p> + */ + public void addListener(LifecycleListener listener) { + lifecycleListeners.add(listener); + + if (isDestroyed) { + listener.onDestroy(); + } else if (isStarted) { + listener.onStart(); + } else { + listener.onStop(); + } + } + + void onStart() { + isStarted = true; + for (LifecycleListener lifecycleListener : lifecycleListeners) { + lifecycleListener.onStart(); + } + } + + void onStop() { + isStarted = false; + for (LifecycleListener lifecycleListener : lifecycleListeners) { + lifecycleListener.onStop(); + } + } + + void onDestroy() { + isDestroyed = true; + for (LifecycleListener lifecycleListener : lifecycleListeners) { + lifecycleListener.onDestroy(); + } + } +} diff --git a/library/src/main/java/com/bumptech/glide/manager/LifecycleListener.java b/library/src/main/java/com/bumptech/glide/manager/LifecycleListener.java new file mode 100644 index 00000000..38614c2e --- /dev/null +++ b/library/src/main/java/com/bumptech/glide/manager/LifecycleListener.java @@ -0,0 +1,23 @@ +package com.bumptech.glide.manager; + +/** + * An interface for listener to {@link android.app.Fragment} and {@link android.app.Activity} lifecycle events. + */ +public interface LifecycleListener { + + /** + * Callback for when {@link android.app.Fragment#onStart()}} or {@link android.app.Activity#onStart()} is called. + */ + public void onStart(); + + /** + * Callback for when {@link android.app.Fragment#onStop()}} or {@link android.app.Activity#onStop()}} is called. + */ + public void onStop(); + + /** + * Callback for when {@link android.app.Fragment#onDestroy()}} or {@link android.app.Activity#onDestroy()} is + * called. + */ + public void onDestroy(); +} diff --git a/library/src/main/java/com/bumptech/glide/manager/NullConnectivityMonitor.java b/library/src/main/java/com/bumptech/glide/manager/NullConnectivityMonitor.java index 115ca52c..debb03fa 100644 --- a/library/src/main/java/com/bumptech/glide/manager/NullConnectivityMonitor.java +++ b/library/src/main/java/com/bumptech/glide/manager/NullConnectivityMonitor.java @@ -6,12 +6,17 @@ package com.bumptech.glide.manager; class NullConnectivityMonitor implements ConnectivityMonitor { @Override - public void register() { + public void onStart() { } @Override - public void unregister() { + public void onStop() { + + } + + @Override + public void onDestroy() { } } diff --git a/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java b/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java index 931b62bc..82e5789f 100644 --- a/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java +++ b/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java @@ -1,5 +1,6 @@ package com.bumptech.glide.manager; +import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Fragment; import com.bumptech.glide.RequestManager; @@ -15,8 +16,19 @@ import com.bumptech.glide.RequestManager; */ @TargetApi(11) public class RequestManagerFragment extends Fragment { + private final Lifecycle lifecycle; private RequestManager requestManager; + public RequestManagerFragment() { + this(new Lifecycle()); + } + + // For testing only. + @SuppressLint("ValidFragment") + RequestManagerFragment(Lifecycle lifecycle) { + this.lifecycle = lifecycle; + } + /** * Sets the current {@link com.bumptech.glide.RequestManager}. * @@ -26,6 +38,10 @@ public class RequestManagerFragment extends Fragment { this.requestManager = requestManager; } + public Lifecycle getLifecycle() { + return lifecycle; + } + /** * Returns the current {@link com.bumptech.glide.RequestManager} or null if none exists. */ @@ -36,24 +52,18 @@ public class RequestManagerFragment extends Fragment { @Override public void onStart() { super.onStart(); - if (requestManager != null) { - requestManager.onStart(); - } + lifecycle.onStart(); } @Override public void onStop() { super.onStop(); - if (requestManager != null) { - requestManager.onStop(); - } + lifecycle.onStop(); } @Override public void onDestroy() { super.onDestroy(); - if (requestManager != null) { - requestManager.onDestroy(); - } + lifecycle.onDestroy(); } } diff --git a/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java b/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java index 95e21868..4e3ee702 100644 --- a/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java +++ b/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java @@ -32,7 +32,7 @@ public class RequestManagerRetriever { // Either a context or we're on a background thread. if (applicationManager == null) { - applicationManager = new RequestManager(context.getApplicationContext()); + applicationManager = new RequestManager(context.getApplicationContext(), new Lifecycle()); } return applicationManager; } @@ -112,7 +112,7 @@ public class RequestManagerRetriever { } RequestManager requestManager = current.getRequestManager(); if (requestManager == null) { - requestManager = new RequestManager(context); + requestManager = new RequestManager(context, current.getLifecycle()); current.setRequestManager(requestManager); } return requestManager; @@ -132,7 +132,7 @@ public class RequestManagerRetriever { } RequestManager requestManager = current.getRequestManager(); if (requestManager == null) { - requestManager = new RequestManager(context); + requestManager = new RequestManager(context, current.getLifecycle()); current.setRequestManager(requestManager); } return requestManager; diff --git a/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java b/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java index 2fc46577..1d49b05f 100644 --- a/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java +++ b/library/src/main/java/com/bumptech/glide/manager/SupportRequestManagerFragment.java @@ -1,5 +1,6 @@ package com.bumptech.glide.manager; +import android.annotation.SuppressLint; import android.support.v4.app.Fragment; import com.bumptech.glide.RequestManager; @@ -14,6 +15,17 @@ import com.bumptech.glide.RequestManager; */ public class SupportRequestManagerFragment extends Fragment { private RequestManager requestManager; + private final Lifecycle lifecycle; + + public SupportRequestManagerFragment() { + this(new Lifecycle()); + } + + // For testing only. + @SuppressLint("ValidFragment") + public SupportRequestManagerFragment(Lifecycle lifecycle) { + this.lifecycle = lifecycle; + } /** * Sets the current {@link com.bumptech.glide.RequestManager}. @@ -24,6 +36,10 @@ public class SupportRequestManagerFragment extends Fragment { this.requestManager = requestManager; } + public Lifecycle getLifecycle() { + return lifecycle; + } + /** * Returns the current {@link com.bumptech.glide.RequestManager} or null if none is set. */ @@ -34,24 +50,18 @@ public class SupportRequestManagerFragment extends Fragment { @Override public void onStart() { super.onStart(); - if (requestManager != null) { - requestManager.onStart(); - } + lifecycle.onStart(); } @Override public void onStop() { super.onStop(); - if (requestManager != null) { - requestManager.onStop(); - } + lifecycle.onStop(); } @Override public void onDestroy() { super.onDestroy(); - if (requestManager != null) { - requestManager.onDestroy(); - } + lifecycle.onDestroy(); } } diff --git a/library/src/test/java/com/bumptech/glide/RequestManagerTest.java b/library/src/test/java/com/bumptech/glide/RequestManagerTest.java index 782dc2f6..4a834410 100644 --- a/library/src/test/java/com/bumptech/glide/RequestManagerTest.java +++ b/library/src/test/java/com/bumptech/glide/RequestManagerTest.java @@ -3,6 +3,7 @@ package com.bumptech.glide; import android.content.Context; import android.graphics.Bitmap; import android.net.Uri; + import com.bumptech.glide.load.model.GenericLoaderFactory; import com.bumptech.glide.load.model.ModelLoader; import com.bumptech.glide.load.model.ModelLoaderFactory; @@ -11,6 +12,7 @@ import com.bumptech.glide.load.model.stream.StreamByteArrayLoader; import com.bumptech.glide.load.model.stream.StreamModelLoader; import com.bumptech.glide.manager.ConnectivityMonitor; import com.bumptech.glide.manager.ConnectivityMonitorFactory; +import com.bumptech.glide.manager.Lifecycle; import com.bumptech.glide.manager.RequestTracker; import com.bumptech.glide.tests.BackgroundUtil; import com.bumptech.glide.tests.GlideShadowLooper; @@ -33,7 +35,6 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -45,6 +46,7 @@ public class RequestManagerTest { private RequestTracker requestTracker; private ConnectivityMonitor.ConnectivityListener connectivityListener; private RequestManager.DefaultOptions options; + private Lifecycle lifecycle = mock(Lifecycle.class); @Before public void setUp() { @@ -59,7 +61,7 @@ public class RequestManagerTest { } }); requestTracker = mock(RequestTracker.class); - manager = new RequestManager(Robolectric.application, requestTracker, factory); + manager = new RequestManager(Robolectric.application, lifecycle, requestTracker, factory); options = mock(RequestManager.DefaultOptions.class); manager.setDefaultOptions(options); } @@ -220,22 +222,13 @@ public class RequestManagerTest { } @Test - public void testRegistersConnectivityReceiverWhenConstructed() { - verify(connectivityMonitor).register(); - } - - @Test - public void testRegistersConnectivityReceiverOnStart() { - manager.onStart(); - - verify(connectivityMonitor, times(2)).register(); + public void testAddsConnectivityMonitorToLifecycleWhenConstructed() { + verify(lifecycle).addListener(eq(connectivityMonitor)); } @Test - public void testUnregistersConnectivityReceiverOnStop() { - manager.onStop(); - - verify(connectivityMonitor).unregister(); + public void testAddsSelfToLifecycleWhenConstructed() { + verify(lifecycle).addListener(eq(manager)); } @Test diff --git a/library/src/test/java/com/bumptech/glide/manager/DefaultConnectivityMonitorTest.java b/library/src/test/java/com/bumptech/glide/manager/DefaultConnectivityMonitorTest.java index 5a0afe91..82cfa0b7 100644 --- a/library/src/test/java/com/bumptech/glide/manager/DefaultConnectivityMonitorTest.java +++ b/library/src/test/java/com/bumptech/glide/manager/DefaultConnectivityMonitorTest.java @@ -31,32 +31,32 @@ public class DefaultConnectivityMonitorTest { } @Test - public void testRegistersReceiverOnRegister() { - monitor.register(); + public void testRegistersReceiverOnStart() { + monitor.onStart(); assertEquals(1, getConnectivityReceiverCount()); } @Test - public void testDoesNotRegisterTwiceOnRegister() { - monitor.register(); - monitor.register(); + public void testDoesNotRegisterTwiceOnStart() { + monitor.onStart(); + monitor.onStart(); assertEquals(1, getConnectivityReceiverCount()); } @Test - public void testUnregistersReceiverOnUnregister() { - monitor.register(); - monitor.unregister(); + public void testUnregistersReceiverOnStop() { + monitor.onStart(); + monitor.onStop(); assertEquals(0, getConnectivityReceiverCount()); } @Test public void testHandlesUnregisteringTwiceInARow() { - monitor.unregister(); - monitor.unregister(); + monitor.onStop(); + monitor.onStop(); assertEquals(0, getConnectivityReceiverCount()); } @@ -66,7 +66,7 @@ public class DefaultConnectivityMonitorTest { ConnectivityHarness harness = new ConnectivityHarness(); harness.connect(); - monitor.register(); + monitor.onStart(); harness.broadcast(); verify(listener, never()).onConnectivityChanged(anyBoolean()); @@ -77,7 +77,7 @@ public class DefaultConnectivityMonitorTest { ConnectivityHarness harness = new ConnectivityHarness(); harness.connect(); - monitor.register(); + monitor.onStart(); harness.disconnect(); harness.broadcast(); @@ -89,7 +89,7 @@ public class DefaultConnectivityMonitorTest { ConnectivityHarness harness = new ConnectivityHarness(); harness.disconnect(); - monitor.register(); + monitor.onStart(); harness.connect(); harness.broadcast(); @@ -101,8 +101,8 @@ public class DefaultConnectivityMonitorTest { ConnectivityHarness harness = new ConnectivityHarness(); harness.disconnect(); - monitor.register(); - monitor.unregister(); + monitor.onStart(); + monitor.onStop(); harness.connect(); harness.broadcast(); diff --git a/library/src/test/java/com/bumptech/glide/manager/LifecycleTest.java b/library/src/test/java/com/bumptech/glide/manager/LifecycleTest.java new file mode 100644 index 00000000..91f47cd7 --- /dev/null +++ b/library/src/test/java/com/bumptech/glide/manager/LifecycleTest.java @@ -0,0 +1,124 @@ +package com.bumptech.glide.manager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +@RunWith(RobolectricTestRunner.class) +public class LifecycleTest { + + private Lifecycle lifecycle; + private LifecycleListener listener; + + @Before + public void setUp() { + lifecycle = new Lifecycle(); + listener = mock(LifecycleListener.class); + } + + @Test + public void testNotifiesAddedListenerOnStart() { + lifecycle.addListener(listener); + lifecycle.onStart(); + verify(listener).onStart(); + } + + @Test + public void testNotifiesAddedListenerOfStartIfStarted() { + lifecycle.onStart(); + lifecycle.addListener(listener); + verify(listener).onStart(); + } + + @Test + public void testDoesNotNotifyAddedListenerOfStartIfDestroyed() { + lifecycle.onStart(); + lifecycle.onStop(); + lifecycle.onDestroy(); + lifecycle.addListener(listener); + + verify(listener, never()).onStart(); + } + + @Test + public void testDoesNotNotifyListenerOfStartIfStartedThenStopped() { + lifecycle.onStart(); + lifecycle.onStop(); + lifecycle.addListener(listener); + verify(listener, never()).onStart(); + } + + @Test + public void testNotifiesAddedListenerOnStop() { + lifecycle.onStart(); + lifecycle.addListener(listener); + lifecycle.onStop(); + verify(listener).onStop(); + } + + @Test + public void testNotifiesAddedListenerOfStopIfStopped() { + lifecycle.onStop(); + lifecycle.addListener(listener); + verify(listener).onStop(); + } + + @Test + public void testDoesNotNotifyAddedListenerOfStopIfDestroyed() { + lifecycle.onStart(); + lifecycle.onStop(); + lifecycle.onDestroy(); + lifecycle.addListener(listener); + verify(listener, never()).onStop(); + } + + @Test + public void testDoesNotNotifyListenerOfStopIfStoppedThenStarted() { + lifecycle.onStop(); + lifecycle.onStart(); + lifecycle.addListener(listener); + verify(listener, never()).onStop(); + } + + @Test + public void testNotifiesAddedListenerOnDestroy() { + lifecycle.addListener(listener); + lifecycle.onDestroy(); + verify(listener).onDestroy(); + } + + @Test + public void testNotifiesAddedListenerOfDestroyIfDestroyed() { + lifecycle.onDestroy(); + lifecycle.addListener(listener); + verify(listener).onDestroy(); + } + + @Test + public void testNotifiesMultipleListeners() { + lifecycle.onStart(); + int toNotify = 20; + List<LifecycleListener> listeners = new ArrayList<LifecycleListener>(); + for (int i = 0; i < toNotify; i++) { + listeners.add(mock(LifecycleListener.class)); + } + for (LifecycleListener lifecycleListener : listeners) { + lifecycle.addListener(lifecycleListener); + } + lifecycle.onStop(); + lifecycle.onDestroy(); + for (LifecycleListener lifecycleListener : listeners) { + verify(lifecycleListener).onStart(); + verify(lifecycleListener).onStop(); + verify(lifecycleListener).onDestroy(); + } + } +}
\ No newline at end of file diff --git a/library/src/test/java/com/bumptech/glide/manager/RequestManagerFragmentTest.java b/library/src/test/java/com/bumptech/glide/manager/RequestManagerFragmentTest.java index db3245c1..4d561893 100644 --- a/library/src/test/java/com/bumptech/glide/manager/RequestManagerFragmentTest.java +++ b/library/src/test/java/com/bumptech/glide/manager/RequestManagerFragmentTest.java @@ -2,17 +2,22 @@ package com.bumptech.glide.manager; import android.app.Activity; import android.support.v4.app.FragmentActivity; + import com.bumptech.glide.RequestManager; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.exceptions.base.MockitoAssertionError; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.util.ActivityController; import static junit.framework.Assert.assertEquals; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @RunWith(RobolectricTestRunner.class) @@ -31,79 +36,106 @@ public class RequestManagerFragmentTest { @Test public void testSupportCanSetAndGetRequestManager() { - for (Harness harness : harnesses) { - RequestManager manager = mock(RequestManager.class); - harness.setRequestManager(manager); - assertEquals(manager, harness.getManager()); - } + runTest(new TestCase() { + @Override + public void runTest(Harness harness) { + RequestManager manager = mock(RequestManager.class); + harness.setRequestManager(manager); + assertEquals(manager, harness.getManager()); + } + }); } @Test - public void testCallsRequestManagerStart() { - for (Harness harness : harnesses) { - harness.getController().start(); - - verify(harness.getManager()).onStart(); - } + public void testReturnsLifecycle() { + runTest(new TestCase() { + @Override + public void runTest(Harness harness) { + assertEquals(harness.getHarnessLifecycle(), harness.getFragmentLifecycle()); + } + }); } @Test - public void testIgnoresNullRequestManagerOnStart() { - for (Harness harness : harnesses) { - harness.setRequestManager(null); - harness.getController().start(); - } + public void testDoesNotAddNullRequestManagerToLifecycleWhenSet() { + runTest(new TestCase() { + @Override + public void runTest(Harness harness) { + harness.setRequestManager(null); + verify(harness.getHarnessLifecycle(), never()).addListener(any(LifecycleListener.class)); + } + }); } @Test - public void testCallsRequestManagerStop() { - for (Harness harness : harnesses) { - harness.getController().start().resume().pause().stop(); - - verify(harness.getManager()).onStop(); - } + public void testCallsLifecycleStart() { + runTest(new TestCase() { + @Override + public void runTest(Harness harness) { + harness.getController().start(); + + verify(harness.getHarnessLifecycle()).onStart(); + } + }); } @Test - public void testIgnoresNullRequestManagerOnStop() { - for (Harness harness : harnesses) { - harness.setRequestManager(null); - harness.getController().start().stop(); - } + public void testCallsRequestManagerStop() { + runTest(new TestCase() { + @Override + public void runTest(Harness harness) { + harness.getController().start().resume().pause().stop(); + + verify(harness.getHarnessLifecycle()).onStop(); + } + }); } @Test public void testCallsRequestManagerDestroy() { - for (Harness harness : harnesses) { - harness.getController().start().resume().pause().stop().destroy(); - - verify(harness.getManager()).onDestroy(); - } + runTest(new TestCase() { + @Override + public void runTest(Harness harness) { + harness.getController().start().resume().pause().stop().destroy(); + + verify(harness.getHarnessLifecycle()).onDestroy(); + } + }); } - @Test - public void testIgnoresNullRequestManagerOnDestroy() { + private void runTest(TestCase testCase) { for (Harness harness : harnesses) { - harness.setRequestManager(null); - harness.getController().start().resume().pause().stop().destroy(); + try { + testCase.runTest(harness); + } catch (MockitoAssertionError e) { + throw new Error("Failed to get expected call on " + harness, e); + } } } + private interface TestCase { + public void runTest(Harness harness); + } + private interface Harness { public RequestManager getManager(); public void setRequestManager(RequestManager manager); + public Lifecycle getHarnessLifecycle(); + + public Lifecycle getFragmentLifecycle(); + public ActivityController getController(); } private static class RequestManagerHarness implements Harness { private final ActivityController<Activity> controller; private final RequestManagerFragment fragment; - private final RequestManager manager; + private final Lifecycle lifecycle = mock(Lifecycle.class); public RequestManagerHarness() { - fragment = new RequestManagerFragment(); + fragment = new RequestManagerFragment(lifecycle); controller = Robolectric.buildActivity(Activity.class).create(); controller.get() .getFragmentManager() @@ -111,9 +143,11 @@ public class RequestManagerFragmentTest { .add(fragment, TAG) .commit(); controller.get().getFragmentManager().executePendingTransactions(); + } - this.manager = mock(RequestManager.class); - fragment.setRequestManager(manager); + @Override + public String toString() { + return "DefaultHarness"; } @Override @@ -127,6 +161,16 @@ public class RequestManagerFragmentTest { } @Override + public Lifecycle getHarnessLifecycle() { + return lifecycle; + } + + @Override + public Lifecycle getFragmentLifecycle() { + return fragment.getLifecycle(); + } + + @Override public ActivityController getController() { return controller; } @@ -135,10 +179,10 @@ public class RequestManagerFragmentTest { private static class SupportRequestManagerHarness implements Harness { private final SupportRequestManagerFragment supportFragment; private final ActivityController<FragmentActivity> supportController; - private final RequestManager manager; + private final Lifecycle lifecycle = mock(Lifecycle.class); public SupportRequestManagerHarness() { - supportFragment = new SupportRequestManagerFragment(); + supportFragment = new SupportRequestManagerFragment(lifecycle); supportController = Robolectric.buildActivity(FragmentActivity.class).create(); supportController.get() @@ -147,10 +191,11 @@ public class RequestManagerFragmentTest { .add(supportFragment, TAG) .commit(); supportController.get().getSupportFragmentManager().executePendingTransactions(); + } - this.manager = mock(RequestManager.class); - supportFragment.setRequestManager(manager); - + @Override + public String toString() { + return "SupportHarness"; } @Override @@ -164,6 +209,16 @@ public class RequestManagerFragmentTest { } @Override + public Lifecycle getHarnessLifecycle() { + return lifecycle; + } + + @Override + public Lifecycle getFragmentLifecycle() { + return supportFragment.getLifecycle(); + } + + @Override public ActivityController getController() { return supportController; } diff --git a/library/src/test/java/com/bumptech/glide/manager/RequestTrackerTest.java b/library/src/test/java/com/bumptech/glide/manager/RequestTrackerTest.java index dc14cd92..e0b18f16 100644 --- a/library/src/test/java/com/bumptech/glide/manager/RequestTrackerTest.java +++ b/library/src/test/java/com/bumptech/glide/manager/RequestTrackerTest.java @@ -18,7 +18,7 @@ public class RequestTrackerTest { } @Test - public void testClearRequestsClearsAddedRequests() { + public void testClearsAddedRequestsOnDestroy() { Request request = mock(Request.class); tracker.addRequest(request); @@ -52,7 +52,7 @@ public class RequestTrackerTest { } @Test - public void testClearsInProgressRequestsOnPause() { + public void testClearsInProgressRequestsWhenPaused() { Request request = mock(Request.class); when(request.isRunning()).thenReturn(true); tracker.addRequest(request); @@ -63,7 +63,7 @@ public class RequestTrackerTest { } @Test - public void testDoesNotClearCompleteRequestsOnPause() { + public void testDoesNotClearCompleteRequestsWhenPaused() { Request request = mock(Request.class); when(request.isComplete()).thenReturn(true); tracker.addRequest(request); @@ -74,7 +74,7 @@ public class RequestTrackerTest { } @Test - public void testDoesNotClearFailedRequestsOnPause() { + public void testDoesNotClearFailedRequestsWhenPaused() { Request request = mock(Request.class); when(request.isFailed()).thenReturn(true); tracker.addRequest(request); @@ -85,7 +85,7 @@ public class RequestTrackerTest { } @Test - public void testRestartsStoppedRequestOnResume() { + public void testRestartsStoppedRequestWhenResumed() { Request request = mock(Request.class); tracker.addRequest(request); @@ -95,7 +95,7 @@ public class RequestTrackerTest { } @Test - public void testDoesNotRestartCompletedRequestsOnResume() { + public void testDoesNotRestartCompletedRequestsWhenResumed() { Request request = mock(Request.class); when(request.isComplete()).thenReturn(true); tracker.addRequest(request); @@ -106,7 +106,7 @@ public class RequestTrackerTest { } @Test - public void testDoesRestartFailedRequestsOnResume() { + public void testDoesRestartFailedRequestsWhenResumed() { Request request = mock(Request.class); when(request.isFailed()).thenReturn(true); tracker.addRequest(request); @@ -117,7 +117,7 @@ public class RequestTrackerTest { } @Test - public void testDoesNotStartStartedRequestsOnResume() { + public void testDoesNotStartStartedRequestsWhenResumed() { Request request = mock(Request.class); when(request.isRunning()).thenReturn(true); tracker.addRequest(request); |