/* * 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.drawable; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import android.annotation.TargetApi; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class DrawableTestUtils { public static abstract class FakeDrawable extends Drawable implements VisibilityAwareDrawable { @Override public void setVisibilityCallback(VisibilityCallback visibilityCallback) {} } /** * Creates a mock Drawable with some methods stubbed. * @return mock Drawable */ public static Drawable mockDrawable() { FakeDrawable drawable = mock(FakeDrawable.class); when(drawable.mutate()).thenReturn(drawable); stubGetAndSetBounds(drawable); stubGetAndSetCallback(drawable); stubSetVisibilityCallback(drawable); stubSetAlpha(drawable); return drawable; } /** * Stubs setBounds and getBounds methods. * @param drawable drawable to stub methods of */ public static void stubGetAndSetBounds(Drawable drawable) { final Rect rect = new Rect(); when(drawable.getBounds()).thenReturn(rect); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { rect.set( (Integer) invocation.getArguments()[0], (Integer) invocation.getArguments()[1], (Integer) invocation.getArguments()[2], (Integer) invocation.getArguments()[3]); return null; } }).when(drawable).setBounds(anyInt(), anyInt(), anyInt(), anyInt()); } /** * Stubs setCallback and getCallback methods. * @param drawable drawable to stub methods of */ @TargetApi(11) public static void stubGetAndSetCallback(final Drawable drawable) { final AtomicReference<Drawable.Callback> callback = new AtomicReference<Drawable.Callback>(); when(drawable.getCallback()).thenReturn(callback.get()); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { callback.set((Drawable.Callback) invocation.getArguments()[0]); return null; } }).when(drawable).setCallback(any(Drawable.Callback.class)); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { if (callback.get() != null) { callback.get().invalidateDrawable(drawable); } return null; } }).when(drawable).invalidateSelf(); } /** * Stubs setVisibilityCallback methods. * @param drawable drawable to stub methods of */ public static void stubSetVisibilityCallback(final Drawable drawable) { final AtomicBoolean isVisible = new AtomicBoolean(true); final AtomicReference<VisibilityCallback> callback = new AtomicReference<VisibilityCallback>(); if (!(drawable instanceof VisibilityAwareDrawable)) { return; } VisibilityAwareDrawable visibilityAwareDrawable = (VisibilityAwareDrawable) drawable; doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { callback.set((VisibilityCallback) invocation.getArguments()[0]); return null; } }).when(visibilityAwareDrawable).setVisibilityCallback(any(VisibilityCallback.class)); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { if (callback.get() != null) { isVisible.set((Boolean) invocation.getArguments()[0]); callback.get().onVisibilityChange(isVisible.get()); } return null; } }).when(drawable).setVisible(anyBoolean(), anyBoolean()); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return isVisible.get(); } }).when(drawable).isVisible(); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { if (callback.get() != null) { callback.get().onDraw(); } return null; } }).when(drawable).draw(any(Canvas.class)); } /** * Stubs setAlpha method. * @param drawable to stub method of */ public static void stubSetAlpha(final Drawable drawable) { final AtomicInteger atomicInteger = new AtomicInteger(255); doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Integer alpha = (Integer) invocation.getArguments()[0]; drawable.invalidateSelf(); atomicInteger.set(alpha); return null; } }).when(drawable).setAlpha(anyInt()); } }