package com.mindbodyonline.ironhide.Infrastructure.Extensions;
import android.support.test.espresso.matcher.BoundedMatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import static android.support.test.internal.util.Checks.checkNotNull;
import static org.hamcrest.Matchers.not;
/**
* Custom ViewMatchers used for BaseView elements
* These are already wrapped inside of elements, so there is little need to use them directly
*/
public class BaseViewMatchers {
/**
* Checks an ImageView to see if the displayed image corresponds to the image pointed to by a Drawable resource
* NOTE: see open issue #94 for Espresso (https://code.google.com/p/android-test-kit/issues/detail?id=94)
*
* @param drawableId The Drawable Resource ID to compare to the ImageView's content
* @return A Matcher to check using Espresso ViewAssertions.matches method
*/
public static Matcher<Object> withDrawableRes(int drawableId) {
checkNotNull(drawableId);
return withDrawable(drawableId);
}
private static Matcher<Object> withDrawable(final int drawableId) {
return new BoundedMatcher<Object, ImageView>(ImageView.class) {
@Override
public boolean matchesSafely(ImageView image) {
return image.getResources().getDrawable(drawableId).getConstantState().equals(image.getDrawable().getConstantState());
}
@Override
public void describeTo(Description description) {
description.appendText("with drawable ");
description.appendText(drawableId + "");
}
};
}
/**
* Checks to see if a View has a certain index
*
* @param index The index to compare to
* @return A Matcher to check using Espresso ViewAssertions.matches method
*/
public static Matcher<View> hasIndex(final int index) {
return checkHasIndex(index);
}
public static Matcher<View> doesNotHaveIndex(final int index) { return not(checkHasIndex(index));}
private static Matcher<View> checkHasIndex(final int index) {
return new BoundedMatcher<View, View>(View.class) {
@Override
public boolean matchesSafely(View view) {
assert (view.getParent()) != null;
return ((ViewGroup) view.getParent()).indexOfChild(view) == index;
}
@Override
public void describeTo(Description description) {
description.appendText("has index " + index);
}
};
}
/**
* Checks to see if a View is of a certain type
* NOTE: Espresso 2.0 provides ViewMatchers.isAssignableFrom(Class<? extends View> clazz),
* which may or may not be a substitute for this method.
*
* @param type The Class Type to compare the type of the View to
* @return A Matcher to check using Espresso ViewAssertions.matches method
*/
public static Matcher<View> instanceOf(final Class<?> type) {
return checkInstanceOf(type);
}
private static Matcher<View> checkInstanceOf(final Class<?> type) {
return new BoundedMatcher<View, View>(View.class) {
@Override
public boolean matchesSafely(View view) {
return type.isInstance(view);
}
@Override
public void describeTo(Description description) {
description.appendText("instance of " + type.toString());
}
};
}
/**
* Checks to see if a View has a certain number of children
* @param count The number of children to check the View has
* @return A Matcher to check using Espresso ViewAssertions.matches method
*/
public static Matcher<View> hasChildCount(final int count) {
return checkChildCount(count);
}
private static Matcher<View> checkChildCount(final int count) {
return new BoundedMatcher<View, View>(View.class) {
@Override
public boolean matchesSafely(View view) {
return view instanceof ViewGroup && ((ViewGroup) view).getChildCount() == count;
}
@Override
public void describeTo(Description description) {
description.appendText("Has " + count + " children");
}
};
}
}