/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.drawee.testing; import java.util.concurrent.atomic.AtomicInteger; import android.graphics.drawable.Drawable; import com.facebook.common.internal.Supplier; import com.facebook.drawee.controller.AbstractDraweeController; import com.facebook.drawee.controller.ControllerListener; import com.facebook.drawee.controller.ForwardingControllerListener; import com.facebook.drawee.drawable.DrawableTestUtils; import com.facebook.drawee.interfaces.DraweeController; import com.facebook.drawee.interfaces.DraweeHierarchy; import com.facebook.drawee.generic.GenericDraweeHierarchy; import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.mockito.Mockito.*; /** * Drawee mocks */ public class DraweeMocks { /** * Creates a mock DraweeController with some methods stubbed. * @return mock DraweeController */ public static DraweeController mockController() { DraweeController controller = mock(AbstractDraweeController.class); stubGetAndSetHierarchy(controller); return controller; } /** * Stubs setHierarchy and getHierarchy methods. * @param controller controller to stub methods of */ public static void stubGetAndSetHierarchy(DraweeController controller) { final DraweeHierarchy[] dhHolder = new DraweeHierarchy[1]; doAnswer( new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return dhHolder[0]; } }).when(controller).getHierarchy(); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return dhHolder[0] = (DraweeHierarchy) invocation.getArguments()[0]; } }).when(controller).setHierarchy(any(DraweeHierarchy.class)); } /** * Stubs addControllerListener * @param controller * @return forwarding listener */ public static ControllerListener stubControllerListener( final DraweeController controller) { final ForwardingControllerListener forwardingListener = new ForwardingControllerListener(); if (!(controller instanceof AbstractDraweeController)) { return null; } AbstractDraweeController abstractController = (AbstractDraweeController) controller; doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { forwardingListener.addListener((ControllerListener) invocation.getArguments()[0]); return null; } }).when(abstractController).addControllerListener(any(ControllerListener.class)); return forwardingListener; } /** * Creates a mock GenericDraweeHierarchy with some methods stubbed. * @param topLevelDrawable drawable to return on {@code getTopLevelDrawable()} * @return mock GenericDraweeHierarchy */ public static GenericDraweeHierarchy mockDraweeHierarchyOf(Drawable topLevelDrawable) { GenericDraweeHierarchy gdh = mock(GenericDraweeHierarchy.class); when(gdh.getTopLevelDrawable()).thenReturn(topLevelDrawable); return gdh; } /** * Creates a mock GenericDraweeHierarchy with some methods stubbed. * @return mock GenericDraweeHierarchy */ public static GenericDraweeHierarchy mockDraweeHierarchy() { return mockDraweeHierarchyOf(DrawableTestUtils.mockDrawable()); } /** * Creates a mock GenericDraweeHierarchyBuilder that builds a new DH instance each time. * @return mock GenericDraweeHierarchyBuilder */ public static GenericDraweeHierarchyBuilder mockGenericDraweeHierarchyBuilder() { GenericDraweeHierarchyBuilder builder = mock(GenericDraweeHierarchyBuilder.class, CALLS_REAL_METHODS); doAnswer( new Answer<Object>() { @Override public DraweeHierarchy answer(InvocationOnMock invocation) throws Throwable { return mockDraweeHierarchy(); } }).when(builder).build(); return builder; } /** * Creates a mock GenericDraweeHierarchyBuilder with stubbed build. * @param drawableHierarchies drawable hierarchies to return on {@code build()} * @return mock GenericDraweeHierarchyBuilder */ public static GenericDraweeHierarchyBuilder mockBuilderOf( GenericDraweeHierarchy... drawableHierarchies) { GenericDraweeHierarchyBuilder builder = mock(GenericDraweeHierarchyBuilder.class, CALLS_REAL_METHODS); final Supplier<GenericDraweeHierarchy> gdhProvider = supplierOf(drawableHierarchies); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return gdhProvider.get(); } }).when(builder).build(); return builder; } /** * Creates a supplier of T. * @param values values to return on {@code get()} * @return supplier of T */ public static <T> Supplier<T> supplierOf(final T... values) { final AtomicInteger index = new AtomicInteger(0); return new Supplier<T>() { @Override public T get() { if (index.get() < values.length) { return values[index.getAndIncrement()]; } else { return values[values.length - 1]; } } }; } }