/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.appcompat.testutils;
import android.database.sqlite.SQLiteCursor;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.support.test.espresso.matcher.BoundedMatcher;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import androidx.annotation.ColorInt;
import androidx.core.view.TintableBackgroundView;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import java.util.List;
public class TestUtilsMatchers {
/**
* Returns a matcher that matches ImageViews which have drawable flat-filled
* with the specific color.
*/
public static Matcher drawable(@ColorInt final int color) {
return new BoundedMatcher(ImageView.class) {
private String failedComparisonDescription;
@Override
public void describeTo(final Description description) {
description.appendText("with drawable of color: ");
description.appendText(failedComparisonDescription);
}
@Override
public boolean matchesSafely(final ImageView view) {
Drawable drawable = view.getDrawable();
if (drawable == null) {
return false;
}
// One option is to check if we have a ColorDrawable and then call getColor
// but that API is v11+. Instead, we call our helper method that checks whether
// all pixels in a Drawable are of the same specified color.
try {
TestUtils.assertAllPixelsOfColor("", drawable, view.getWidth(),
view.getHeight(), true, color, 0, true);
// If we are here, the color comparison has passed.
failedComparisonDescription = null;
return true;
} catch (Throwable t) {
// If we are here, the color comparison has failed.
failedComparisonDescription = t.getMessage();
return false;
}
}
};
}
/**
* Returns a matcher that matches Views which have background flat-filled
* with the specific color.
*/
public static Matcher isBackground(@ColorInt final int color) {
return isBackground(color, false);
}
/**
* Returns a matcher that matches Views which have background flat-filled
* with the specific color.
*/
public static Matcher isBackground(@ColorInt final int color, final boolean onlyTestCenter) {
return new BoundedMatcher(View.class) {
private String failedComparisonDescription;
@Override
public void describeTo(final Description description) {
description.appendText("with background of color: ");
description.appendText(failedComparisonDescription);
}
@Override
public boolean matchesSafely(final View view) {
Drawable drawable = view.getBackground();
if (drawable == null) {
return false;
}
try {
if (onlyTestCenter) {
TestUtils.assertCenterPixelOfColor("", drawable, view.getWidth(),
view.getHeight(), false, color, 0, true);
} else {
TestUtils.assertAllPixelsOfColor("", drawable, view.getWidth(),
view.getHeight(), false, color, 0, true);
}
// If we are here, the color comparison has passed.
failedComparisonDescription = null;
return true;
} catch (Throwable t) {
// If we are here, the color comparison has failed.
failedComparisonDescription = t.getMessage();
return false;
}
}
};
}
/**
* Returns a matcher that matches Views whose combined background starting
* from the view and up its ancestor chain matches the specified color.
*/
public static Matcher isCombinedBackground(@ColorInt final int color,
final boolean onlyTestCenterPixel) {
return new BoundedMatcher(View.class) {
private String failedComparisonDescription;
@Override
public void describeTo(final Description description) {
description.appendText("with ascendant background of color: ");
description.appendText(failedComparisonDescription);
}
@Override
public boolean matchesSafely(View view) {
// Create a bitmap with combined backgrounds of the view and its ancestors.
Bitmap combinedBackgroundBitmap = TestUtils.getCombinedBackgroundBitmap(view);
try {
if (onlyTestCenterPixel) {
TestUtils.assertCenterPixelOfColor("", combinedBackgroundBitmap,
color, 0, true);
} else {
TestUtils.assertAllPixelsOfColor("", combinedBackgroundBitmap,
combinedBackgroundBitmap.getWidth(),
combinedBackgroundBitmap.getHeight(), color, 0, true);
}
// If we are here, the color comparison has passed.
failedComparisonDescription = null;
return true;
} catch (Throwable t) {
failedComparisonDescription = t.getMessage();
return false;
} finally {
combinedBackgroundBitmap.recycle();
}
}
};
}
/**
* Returns a matcher that matches CheckedTextViews which are in checked state.
*/
public static Matcher isCheckedTextView() {
return new BoundedMatcher(CheckedTextView.class) {
private String failedDescription;
@Override
public void describeTo(final Description description) {
description.appendText("checked text view: ");
description.appendText(failedDescription);
}
@Override
public boolean matchesSafely(final CheckedTextView view) {
if (view.isChecked()) {
return true;
}
failedDescription = "not checked";
return false;
}
};
}
/**
* Returns a matcher that matches CheckedTextViews which are in checked state.
*/
public static Matcher isNonCheckedTextView() {
return new BoundedMatcher(CheckedTextView.class) {
private String failedDescription;
@Override
public void describeTo(final Description description) {
description.appendText("non checked text view: ");
description.appendText(failedDescription);
}
@Override
public boolean matchesSafely(final CheckedTextView view) {
if (!view.isChecked()) {
return true;
}
failedDescription = "checked";
return false;
}
};
}
/**
* Returns a matcher that matches data entry in SQLiteCursor that has
* the specified text in the specified column.
*/
public static Matcher