/*
* 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());
}
}