Extending background tinting tests to AppCompatImageView
Extract all the tint-related logic to a new generic class and
have AppCompatTextView / AppCompatImageView (and more in the next
CLs) inherit all that logic.
Then specific subclasses can add tests that are specific to one
component - such as all-caps in AppCompatTextView.
Change-Id: Ic4c00983feff58c435033bdc0e3ce67ec774439a
diff --git a/v7/appcompat/tests/AndroidManifest.xml b/v7/appcompat/tests/AndroidManifest.xml
index 0813954..1c6a855 100644
--- a/v7/appcompat/tests/AndroidManifest.xml
+++ b/v7/appcompat/tests/AndroidManifest.xml
@@ -55,6 +55,11 @@
android:label="@string/app_compat_text_view_activity"
android:theme="@style/Theme.AppCompat.Light" />
+ <activity
+ android:name="android.support.v7.widget.AppCompatImageViewActivity"
+ android:label="@string/app_compat_image_view_activity"
+ android:theme="@style/Theme.AppCompat.Light" />
+
</application>
<instrumentation
diff --git a/v7/appcompat/tests/res/layout/appcompat_imageview_activity.xml b/v7/appcompat/tests/res/layout/appcompat_imageview_activity.xml
new file mode 100644
index 0000000..fed24b1
--- /dev/null
+++ b/v7/appcompat/tests/res/layout/appcompat_imageview_activity.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/view_tinted_no_background"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/test_drawable_blue"
+ app:backgroundTint="@color/color_state_list_lilac"
+ app:backgroundTintMode="src_in" />
+
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/view_tinted_background"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/test_drawable_blue"
+ android:background="@drawable/test_drawable"
+ app:backgroundTint="@color/color_state_list_lilac"
+ app:backgroundTintMode="src_in" />
+
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/view_untinted_no_background"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/test_drawable_blue" />
+
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/view_untinted_background"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/test_drawable_blue"
+ android:background="@drawable/test_background_green" />
+ </LinearLayout>
+
+</ScrollView>
diff --git a/v7/appcompat/tests/res/layout/appcompat_textview_activity.xml b/v7/appcompat/tests/res/layout/appcompat_textview_activity.xml
index a7b33e6..e093de9 100644
--- a/v7/appcompat/tests/res/layout/appcompat_textview_activity.xml
+++ b/v7/appcompat/tests/res/layout/appcompat_textview_activity.xml
@@ -40,7 +40,7 @@
android:text="@string/sample_text2" />
<android.support.v7.widget.AppCompatTextView
- android:id="@+id/text_view_tinted_no_background"
+ android:id="@+id/view_tinted_no_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/sample_text1"
@@ -48,7 +48,7 @@
app:backgroundTintMode="src_in" />
<android.support.v7.widget.AppCompatTextView
- android:id="@+id/text_view_tinted_background"
+ android:id="@+id/view_tinted_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/sample_text2"
@@ -57,13 +57,13 @@
app:backgroundTintMode="src_in" />
<android.support.v7.widget.AppCompatTextView
- android:id="@+id/text_view_untinted_no_background"
+ android:id="@+id/view_untinted_no_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/sample_text2" />
<android.support.v7.widget.AppCompatTextView
- android:id="@+id/text_view_untinted_background"
+ android:id="@+id/view_untinted_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/sample_text2"
diff --git a/v7/appcompat/tests/res/values/strings.xml b/v7/appcompat/tests/res/values/strings.xml
index bcbe38a..b7347a2 100644
--- a/v7/appcompat/tests/res/values/strings.xml
+++ b/v7/appcompat/tests/res/values/strings.xml
@@ -44,4 +44,5 @@
<string name="app_compat_text_view_activity">AppCompat text view</string>
<string name="sample_text1">Sample text 1</string>
<string name="sample_text2">Sample text 2</string>
+ <string name="app_compat_image_view_activity">AppCompat image view</string>
</resources>
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
new file mode 100644
index 0000000..b517fc3
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2016 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 android.support.v7.widget;
+
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
+import android.support.annotation.IdRes;
+import android.support.annotation.NonNull;
+import android.support.v4.content.res.ResourcesCompat;
+import android.support.v4.graphics.ColorUtils;
+import android.support.v7.appcompat.test.R;
+import android.support.v7.testutils.AppCompatTintableViewActions;
+import android.support.v7.testutils.BaseTestActivity;
+import android.support.v7.testutils.TestUtils;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.View;
+import android.view.ViewGroup;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+/**
+ * Base class for testing custom view extensions in appcompat-v7 that implement the
+ * <code>TintableBackgroundView</code> interface. Extensions of this class run all tests
+ * from here and add test cases specific to the functionality they add to the relevant
+ * base view class (such as <code>AppCompatTextView</code>'s all-caps support).
+ */
+public abstract class AppCompatBaseViewTest<A extends BaseTestActivity, T extends View>
+ extends ActivityInstrumentationTestCase2<A> {
+ protected ViewGroup mContainer;
+
+ public AppCompatBaseViewTest(Class clazz) {
+ super(clazz);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final A activity = getActivity();
+ mContainer = (ViewGroup) activity.findViewById(R.id.container);
+ }
+
+ private void verifyBackgroundIsColoredAs(String description, @NonNull View view,
+ @ColorInt int color, int allowedComponentVariance) {
+ Drawable background = view.getBackground();
+ TestUtils.assertAllPixelsOfColor(description,
+ background, view.getWidth(), view.getHeight(), true,
+ color, allowedComponentVariance, false);
+ }
+
+ /**
+ * This method tests that background tinting is not applied when the
+ * tintable view has no background.
+ */
+ @SmallTest
+ public void testBackgroundTintingWithNoBackground() {
+ final @IdRes int viewId = R.id.view_tinted_no_background;
+ final Resources res = getActivity().getResources();
+ final T view = (T) mContainer.findViewById(viewId);
+
+ // Note that all the asserts in this test check that the view background
+ // is null. This is because the matching child in the activity doesn't define any
+ // background on itself, and there is nothing to tint.
+
+ assertNull("No background after XML loading", view.getBackground());
+
+ // Disable the view and check that the background is still null.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ assertNull("No background after disabling", view.getBackground());
+
+ // Enable the view and check that the background is still null.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ assertNull("No background after re-enabling", view.getBackground());
+
+ // Load a new color state list, set it on the view and check that the background
+ // is still null.
+ final ColorStateList sandColor = ResourcesCompat.getColorStateList(
+ res, R.color.color_state_list_sand, null);
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintList(sandColor));
+
+ // Disable the view and check that the background is still null.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ assertNull("No background after disabling", view.getBackground());
+
+ // Enable the view and check that the background is still null.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ assertNull("No background after re-enabling", view.getBackground());
+ }
+
+ /**
+ * This method tests that background tinting is applied to tintable view
+ * in enabled and disabled state across a number of <code>ColorStateList</code>s set as
+ * background tint lists on the same background.
+ */
+ @SmallTest
+ public void testBackgroundTintingAcrossStateChange() {
+ final @IdRes int viewId = R.id.view_tinted_background;
+ final Resources res = getActivity().getResources();
+ final T view = (T) mContainer.findViewById(viewId);
+
+ @ColorInt int lilacDefault = ResourcesCompat.getColor(res, R.color.lilac_default, null);
+ @ColorInt int lilacDisabled = ResourcesCompat.getColor(res, R.color.lilac_disabled, null);
+ @ColorInt int sandDefault = ResourcesCompat.getColor(res, R.color.sand_default, null);
+ @ColorInt int sandDisabled = ResourcesCompat.getColor(res, R.color.sand_disabled, null);
+ @ColorInt int oceanDefault = ResourcesCompat.getColor(res, R.color.ocean_default, null);
+ @ColorInt int oceanDisabled = ResourcesCompat.getColor(res, R.color.ocean_disabled, null);
+
+ // Test the default state for tinting set up in the layout XML file.
+ verifyBackgroundIsColoredAs("Default lilac tinting in enabled state", view,
+ lilacDefault, 0);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("Default lilac tinting in disabled state", view,
+ lilacDisabled, 0);
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state", view,
+ lilacDefault, 0);
+
+ // Load a new color state list, set it on the view and check that the background has
+ // switched to the matching entry in newly set color state list.
+ final ColorStateList sandColor = ResourcesCompat.getColorStateList(
+ res, R.color.color_state_list_sand, null);
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintList(sandColor));
+ verifyBackgroundIsColoredAs("New sand tinting in enabled state", view,
+ sandDefault, 0);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("New sand tinting in disabled state", view,
+ sandDisabled, 0);
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("New sand tinting in re-enabled state", view,
+ sandDefault, 0);
+
+ // Load another color state list, set it on the view and check that the background has
+ // switched to the matching entry in newly set color state list.
+ final ColorStateList oceanColor = ResourcesCompat.getColorStateList(
+ res, R.color.color_state_list_ocean, null);
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintList(oceanColor));
+ verifyBackgroundIsColoredAs("New ocean tinting in enabled state", view,
+ oceanDefault, 0);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("New ocean tinting in disabled state", view,
+ oceanDisabled, 0);
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("New ocean tinting in re-enabled state", view,
+ oceanDefault, 0);
+ }
+
+ /**
+ * This method tests that background tinting applied to tintable view
+ * in enabled and disabled state across the same background respects the currently set
+ * background tinting mode.
+ */
+ @SmallTest
+ public void testBackgroundTintingAcrossModeChange() {
+ final @IdRes int viewId = R.id.view_untinted_background;
+ final Resources res = getActivity().getResources();
+ final T view = (T) mContainer.findViewById(viewId);
+
+ @ColorInt int emeraldDefault = ResourcesCompat.getColor(
+ res, R.color.emerald_translucent_default, null);
+ @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
+ res, R.color.emerald_translucent_disabled, null);
+ // This is the fill color of R.drawable.test_background_green set on our view
+ // that we'll be testing in this method
+ @ColorInt int backgroundColor = ResourcesCompat.getColor(
+ res, R.color.test_green, null);
+
+ // Test the default state for tinting set up in the layout XML file.
+ verifyBackgroundIsColoredAs("Default no tinting in enabled state", view,
+ backgroundColor, 0);
+
+ // From this point on in this method we're allowing a margin of error in checking the
+ // color of the view background. This is due to both translucent colors being used
+ // in the color state list and off-by-one discrepancies of SRC_OVER when it's compositing
+ // translucent color on top of solid fill color. This is where the allowed variance
+ // value of 2 comes from - one for compositing and one for color translucency.
+ final int allowedComponentVariance = 2;
+
+ // Set src_in tint mode on our view
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_IN));
+
+ // Load a new color state list, set it on the view and check that the background has
+ // switched to the matching entry in newly set color state list.
+ final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
+ res, R.color.color_state_list_emerald_translucent, null);
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintList(emeraldColor));
+ verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_in", view,
+ emeraldDefault, allowedComponentVariance);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_in", view,
+ emeraldDisabled, allowedComponentVariance);
+
+ // Set src_over tint mode on our view. As the currently set tint list is using
+ // translucent colors, we expect the actual background of the view to be different under
+ // this new mode (unlike src_in and src_over that behave identically when the destination is
+ // a fully filled rectangle and the source is an opaque color).
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_over", view,
+ ColorUtils.compositeColors(emeraldDefault, backgroundColor),
+ allowedComponentVariance);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_over",
+ view, ColorUtils.compositeColors(emeraldDisabled, backgroundColor),
+ allowedComponentVariance);
+ }
+
+ /**
+ * This method tests that opaque background tinting applied to tintable view
+ * is applied correctly after changing the background itself of the view.
+ */
+ @SmallTest
+ public void testBackgroundOpaqueTintingAcrossBackgroundChange() {
+ final @IdRes int viewId = R.id.view_tinted_no_background;
+ final Resources res = getActivity().getResources();
+ final T view = (T) mContainer.findViewById(viewId);
+
+ @ColorInt int lilacDefault = ResourcesCompat.getColor(res, R.color.lilac_default, null);
+ @ColorInt int lilacDisabled = ResourcesCompat.getColor(res, R.color.lilac_disabled, null);
+
+ assertNull("No background after XML loading", view.getBackground());
+
+ // Set background on our view
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setBackgroundDrawable(
+ ResourcesCompat.getDrawable(res, R.drawable.test_background_green, null)));
+
+ // Test the default state for tinting set up in the layout XML file.
+ verifyBackgroundIsColoredAs("Default lilac tinting in enabled state on green background",
+ view, lilacDefault, 0);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("Default lilac tinting in disabled state on green background",
+ view, lilacDisabled, 0);
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state on green background",
+ view, lilacDefault, 0);
+
+ // Set a different background on our view based on resource ID
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setBackgroundResource(
+ R.drawable.test_background_red));
+
+ // Test the default state for tinting set up in the layout XML file.
+ verifyBackgroundIsColoredAs("Default lilac tinting in enabled state on red background",
+ view, lilacDefault, 0);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("Default lilac tinting in disabled state on red background",
+ view, lilacDisabled, 0);
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state on red background",
+ view, lilacDefault, 0);
+ }
+
+ /**
+ * This method tests that translucent background tinting applied to tintable view
+ * is applied correctly after changing the background itself of the view.
+ */
+ @SmallTest
+ public void testBackgroundTranslucentTintingAcrossBackgroundChange() {
+ final @IdRes int viewId = R.id.view_untinted_no_background;
+ final Resources res = getActivity().getResources();
+ final T view = (T) mContainer.findViewById(viewId);
+
+ @ColorInt int emeraldDefault = ResourcesCompat.getColor(
+ res, R.color.emerald_translucent_default, null);
+ @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
+ res, R.color.emerald_translucent_disabled, null);
+ // This is the fill color of R.drawable.test_background_green set on our view
+ // that we'll be testing in this method
+ @ColorInt int backgroundColorGreen = ResourcesCompat.getColor(
+ res, R.color.test_green, null);
+ @ColorInt int backgroundColorRed = ResourcesCompat.getColor(
+ res, R.color.test_red, null);
+
+ assertNull("No background after XML loading", view.getBackground());
+
+ // Set src_over tint mode on our view. As the currently set tint list is using
+ // translucent colors, we expect the actual background of the view to be different under
+ // this new mode (unlike src_in and src_over that behave identically when the destination is
+ // a fully filled rectangle and the source is an opaque color).
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
+ // Load and set a translucent color state list as the background tint list
+ final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
+ res, R.color.color_state_list_emerald_translucent, null);
+ onView(withId(viewId)).perform(
+ AppCompatTintableViewActions.setBackgroundTintList(emeraldColor));
+
+ // Set background on our view
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setBackgroundDrawable(
+ ResourcesCompat.getDrawable(res, R.drawable.test_background_green, null)));
+
+ // From this point on in this method we're allowing a margin of error in checking the
+ // color of the view background. This is due to both translucent colors being used
+ // in the color state list and off-by-one discrepancies of SRC_OVER when it's compositing
+ // translucent color on top of solid fill color. This is where the allowed variance
+ // value of 2 comes from - one for compositing and one for color translucency.
+ final int allowedComponentVariance = 2;
+
+ // Test the default state for tinting set up with the just loaded tint list.
+ verifyBackgroundIsColoredAs("Emerald tinting in enabled state on green background",
+ view, ColorUtils.compositeColors(emeraldDefault, backgroundColorGreen),
+ allowedComponentVariance);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("Emerald tinting in disabled state on green background",
+ view, ColorUtils.compositeColors(emeraldDisabled, backgroundColorGreen),
+ allowedComponentVariance);
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the default color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("Emerald tinting in re-enabled state on green background",
+ view, ColorUtils.compositeColors(emeraldDefault, backgroundColorGreen),
+ allowedComponentVariance);
+
+ // Set a different background on our view based on resource ID
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setBackgroundResource(
+ R.drawable.test_background_red));
+
+ // Test the default state for tinting the new background with the same color state list
+ verifyBackgroundIsColoredAs("Emerald tinting in enabled state on red background",
+ view, ColorUtils.compositeColors(emeraldDefault, backgroundColorRed),
+ allowedComponentVariance);
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in our current color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ verifyBackgroundIsColoredAs("Emerald tinting in disabled state on red background",
+ view, ColorUtils.compositeColors(emeraldDisabled, backgroundColorRed),
+ allowedComponentVariance);
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in our current color state list.
+ onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ verifyBackgroundIsColoredAs("Emerald tinting in re-enabled state on red background",
+ view, ColorUtils.compositeColors(emeraldDefault, backgroundColorRed),
+ allowedComponentVariance);
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewActivity.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewActivity.java
new file mode 100644
index 0000000..f41f7a3
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewActivity.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 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 android.support.v7.widget;
+
+import android.support.v7.appcompat.test.R;
+import android.support.v7.testutils.BaseTestActivity;
+
+public class AppCompatImageViewActivity extends BaseTestActivity {
+ @Override
+ protected int getContentViewLayoutResId() {
+ return R.layout.appcompat_imageview_activity;
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
new file mode 100644
index 0000000..d2abe95
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 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 android.support.v7.widget;
+
+import android.content.res.Resources;
+import android.support.v7.appcompat.test.R;
+import android.support.v7.testutils.AppCompatTextViewActions;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+/**
+ * In addition to all tinting-related tests done by the base class, this class provides
+ * tests specific to <code>AppCompatImageView</code> class.
+ */
+public class AppCompatImageViewTest
+ extends AppCompatBaseViewTest<AppCompatImageViewActivity, AppCompatImageView> {
+ public AppCompatImageViewTest() {
+ super(AppCompatImageViewActivity.class);
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatTextViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatTextViewTest.java
index d31ce90..6448e7d 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatTextViewTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatTextViewTest.java
@@ -15,42 +15,24 @@
*/
package android.support.v7.widget;
-import android.content.res.ColorStateList;
import android.content.res.Resources;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.ColorInt;
-import android.support.annotation.IdRes;
-import android.support.annotation.NonNull;
-import android.support.v4.content.res.ResourcesCompat;
-import android.support.v4.graphics.ColorUtils;
import android.support.v7.appcompat.test.R;
import android.support.v7.testutils.AppCompatTextViewActions;
-import android.support.v7.testutils.AppCompatTintableViewActions;
-import android.support.v7.testutils.TestUtils;
-import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
-import android.view.ViewGroup;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
+/**
+ * In addition to all tinting-related tests done by the base class, this class provides
+ * tests specific to <code>AppCompatTextView</code> class.
+ */
public class AppCompatTextViewTest
- extends ActivityInstrumentationTestCase2<AppCompatTextViewActivity> {
- private ViewGroup mContainer;
-
+ extends AppCompatBaseViewTest<AppCompatTextViewActivity, AppCompatTextView> {
public AppCompatTextViewTest() {
super(AppCompatTextViewActivity.class);
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- final AppCompatTextViewActivity activity = getActivity();
- mContainer = (ViewGroup) activity.findViewById(R.id.container);
- }
-
@SmallTest
public void testAllCaps() throws Throwable {
final Resources res = getActivity().getResources();
@@ -83,352 +65,4 @@
assertEquals("Text view is in all caps on", text2.toUpperCase(),
textView2.getLayout().getText());
}
-
- private void verifyBackgroundIsColoredAs(String description,
- @NonNull AppCompatTextView textView, @ColorInt int color,
- int allowedComponentVariance) {
- Drawable background = textView.getBackground();
- TestUtils.assertAllPixelsOfColor(description,
- background, textView.getWidth(), textView.getHeight(), true,
- color, allowedComponentVariance, false);
- }
-
- /**
- * This method tests that background tinting is not applied when the
- * <code>AppCompatTextView</code> has no background.
- */
- @SmallTest
- public void testBackgroundTintingWithNoBackground() {
- final @IdRes int textViewId = R.id.text_view_tinted_no_background;
- final AppCompatTextView textView =
- (AppCompatTextView) mContainer.findViewById(textViewId);
-
- // Note that all the asserts in this test check that the AppCompatTextView background
- // is null. This is because the matching child in the activity doesn't define any
- // background on itself, and there is nothing to tint.
-
- assertNull("No background after XML loading", textView.getBackground());
-
- // Disable the text view and check that the background is still null.
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setEnabled(false));
- assertNull("No background after disabling", textView.getBackground());
-
- // Enable the text view and check that the background is still null.
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setEnabled(true));
- assertNull("No background after re-enabling", textView.getBackground());
-
- // Load a new color state list, set it on the text view and check that the background
- // is still null.
- final ColorStateList sandColor = ResourcesCompat.getColorStateList(
- getActivity().getResources(), R.color.color_state_list_sand, null);
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(sandColor));
-
- // Disable the text view and check that the background is still null.
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setEnabled(false));
- assertNull("No background after disabling", textView.getBackground());
-
- // Enable the text view and check that the background is still null.
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setEnabled(true));
- assertNull("No background after re-enabling", textView.getBackground());
- }
-
- /**
- * This method tests that background tinting is applied to <code>AppCompatTextView</code>
- * in enabled and disabled state across a number of <code>ColorStateList</code>s set as
- * background tint lists on the same background.
- */
- @SmallTest
- public void testBackgroundTintingAcrossStateChange() {
- final @IdRes int textViewId = R.id.text_view_tinted_background;
- final Resources res = getActivity().getResources();
-
- @ColorInt int lilacDefault = ResourcesCompat.getColor(res, R.color.lilac_default, null);
- @ColorInt int lilacDisabled = ResourcesCompat.getColor(res, R.color.lilac_disabled, null);
- @ColorInt int sandDefault = ResourcesCompat.getColor(res, R.color.sand_default, null);
- @ColorInt int sandDisabled = ResourcesCompat.getColor(res, R.color.sand_disabled, null);
- @ColorInt int oceanDefault = ResourcesCompat.getColor(res, R.color.ocean_default, null);
- @ColorInt int oceanDisabled = ResourcesCompat.getColor(res, R.color.ocean_disabled, null);
-
- final AppCompatTextView textView =
- (AppCompatTextView) mContainer.findViewById(textViewId);
-
- // Test the default state for tinting set up in the layout XML file.
- verifyBackgroundIsColoredAs("Default lilac tinting in enabled state", textView,
- lilacDefault, 0);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("Default lilac tinting in disabled state", textView,
- lilacDisabled, 0);
-
- // Enable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state", textView,
- lilacDefault, 0);
-
- // Load a new color state list, set it on the text view and check that the background has
- // switched to the matching entry in newly set color state list.
- final ColorStateList sandColor = ResourcesCompat.getColorStateList(
- res, R.color.color_state_list_sand, null);
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(sandColor));
- verifyBackgroundIsColoredAs("New sand tinting in enabled state", textView,
- sandDefault, 0);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the newly set color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("New sand tinting in disabled state", textView,
- sandDisabled, 0);
-
- // Enable the text view and check that the background has switched to the matching entry
- // in the newly set color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("New sand tinting in re-enabled state", textView,
- sandDefault, 0);
-
- // Load another color state list, set it on the text view and check that the background has
- // switched to the matching entry in newly set color state list.
- final ColorStateList oceanColor = ResourcesCompat.getColorStateList(
- res, R.color.color_state_list_ocean, null);
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(oceanColor));
- verifyBackgroundIsColoredAs("New ocean tinting in enabled state", textView,
- oceanDefault, 0);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the newly set color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("New ocean tinting in disabled state", textView,
- oceanDisabled, 0);
-
- // Enable the text view and check that the background has switched to the matching entry
- // in the newly set color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("New ocean tinting in re-enabled state", textView,
- oceanDefault, 0);
- }
-
- /**
- * This method tests that background tinting applied to <code>AppCompatTextView</code>
- * in enabled and disabled state across the same background respects the currently set
- * background tinting mode.
- */
- @SmallTest
- public void testBackgroundTintingAcrossModeChange() {
- final @IdRes int textViewId = R.id.text_view_untinted_background;
- final Resources res = getActivity().getResources();
-
- @ColorInt int emeraldDefault = ResourcesCompat.getColor(
- res, R.color.emerald_translucent_default, null);
- @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
- res, R.color.emerald_translucent_disabled, null);
- // This is the fill color of R.drawable.test_background_green set on our text view
- // that we'll be testing in this method
- @ColorInt int backgroundColor = ResourcesCompat.getColor(
- res, R.color.test_green, null);
-
- final AppCompatTextView textView =
- (AppCompatTextView) mContainer.findViewById(textViewId);
-
- // Test the default state for tinting set up in the layout XML file.
- verifyBackgroundIsColoredAs("Default no tinting in enabled state", textView,
- backgroundColor, 0);
-
- // From this point on in this method we're allowing a margin of error in checking the
- // color of the text view background. This is due to both translucent colors being used
- // in the color state list and off-by-one discrepancies of SRC_OVER when it's compositing
- // translucent color on top of solid fill color. This is where the allowed variance
- // value of 2 comes from - one for compositing and one for color translucency.
- final int allowedComponentVariance = 2;
-
- // Set src_in tint mode on our text view
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_IN));
-
- // Load a new color state list, set it on the text view and check that the background has
- // switched to the matching entry in newly set color state list.
- final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
- res, R.color.color_state_list_emerald_translucent, null);
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(emeraldColor));
- verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_in", textView,
- emeraldDefault, allowedComponentVariance);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the newly set color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_in", textView,
- emeraldDisabled, allowedComponentVariance);
-
- // Set src_over tint mode on our text view. As the currently set tint list is using
- // translucent colors, we expect the actual background of the view to be different under
- // this new mode (unlike src_in and src_over that behave identically when the destination is
- // a fully filled rectangle and the source is an opaque color).
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
-
- // Enable the text view and check that the background has switched to the matching entry
- // in the color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_over", textView,
- ColorUtils.compositeColors(emeraldDefault, backgroundColor),
- allowedComponentVariance);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the newly set color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_over",
- textView, ColorUtils.compositeColors(emeraldDisabled, backgroundColor),
- allowedComponentVariance);
- }
-
- /**
- * This method tests that opaque background tinting applied to <code>AppCompatTextView</code>
- * is applied correctly after changing the background itself of the view.
- */
- @SmallTest
- public void testBackgroundOpaqueTintingAcrossBackgroundChange() {
- final @IdRes int textViewId = R.id.text_view_tinted_no_background;
- final Resources res = getActivity().getResources();
-
- @ColorInt int lilacDefault = ResourcesCompat.getColor(res, R.color.lilac_default, null);
- @ColorInt int lilacDisabled = ResourcesCompat.getColor(res, R.color.lilac_disabled, null);
-
- final AppCompatTextView textView =
- (AppCompatTextView) mContainer.findViewById(textViewId);
-
- assertNull("No background after XML loading", textView.getBackground());
-
- // Set background on our text view
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setBackgroundDrawable(
- ResourcesCompat.getDrawable(res, R.drawable.test_background_green, null)));
-
- // Test the default state for tinting set up in the layout XML file.
- verifyBackgroundIsColoredAs("Default lilac tinting in enabled state on green BG",
- textView, lilacDefault, 0);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("Default lilac tinting in disabled state on green BG",
- textView, lilacDisabled, 0);
-
- // Enable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state on green BG",
- textView, lilacDefault, 0);
-
- // Set a different background on our view based on resource ID
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setBackgroundResource(
- R.drawable.test_background_red));
-
- // Test the default state for tinting set up in the layout XML file.
- verifyBackgroundIsColoredAs("Default lilac tinting in enabled state on red BG",
- textView, lilacDefault, 0);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("Default lilac tinting in disabled state on red BG",
- textView, lilacDisabled, 0);
-
- // Enable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state on red BG",
- textView, lilacDefault, 0);
- }
-
- /**
- * This method tests that translucent background tinting applied to <code>AppCompatTextView</code>
- * is applied correctly after changing the background itself of the view.
- */
- @SmallTest
- public void testBackgroundTranslucentTintingAcrossBackgroundChange() {
- final @IdRes int textViewId = R.id.text_view_untinted_no_background;
- final Resources res = getActivity().getResources();
-
- @ColorInt int emeraldDefault = ResourcesCompat.getColor(
- res, R.color.emerald_translucent_default, null);
- @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
- res, R.color.emerald_translucent_disabled, null);
- // This is the fill color of R.drawable.test_background_green set on our text view
- // that we'll be testing in this method
- @ColorInt int backgroundColorGreen = ResourcesCompat.getColor(
- res, R.color.test_green, null);
- @ColorInt int backgroundColorRed = ResourcesCompat.getColor(
- res, R.color.test_red, null);
-
- final AppCompatTextView textView =
- (AppCompatTextView) mContainer.findViewById(textViewId);
-
- assertNull("No background after XML loading", textView.getBackground());
-
- // Set src_over tint mode on our text view. As the currently set tint list is using
- // translucent colors, we expect the actual background of the view to be different under
- // this new mode (unlike src_in and src_over that behave identically when the destination is
- // a fully filled rectangle and the source is an opaque color).
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
- // Load and set a translucent color state list as the background tint list
- final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
- res, R.color.color_state_list_emerald_translucent, null);
- onView(withId(textViewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(emeraldColor));
-
- // Set background on our text view
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setBackgroundDrawable(
- ResourcesCompat.getDrawable(res, R.drawable.test_background_green, null)));
-
- // From this point on in this method we're allowing a margin of error in checking the
- // color of the text view background. This is due to both translucent colors being used
- // in the color state list and off-by-one discrepancies of SRC_OVER when it's compositing
- // translucent color on top of solid fill color. This is where the allowed variance
- // value of 2 comes from - one for compositing and one for color translucency.
-
- // Test the default state for tinting set up with the just loaded tint list.
- verifyBackgroundIsColoredAs("Emerald tinting in enabled state on green BG",
- textView, ColorUtils.compositeColors(emeraldDefault, backgroundColorGreen), 2);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("Emerald tinting in disabled state on green BG",
- textView, ColorUtils.compositeColors(emeraldDisabled, backgroundColorGreen), 2);
-
- // Enable the text view and check that the background has switched to the matching entry
- // in the default color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("Emerald tinting in re-enabled state on green BG",
- textView, ColorUtils.compositeColors(emeraldDefault, backgroundColorGreen), 2);
-
- // Set a different background on our view based on resource ID
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setBackgroundResource(
- R.drawable.test_background_red));
-
- // Test the default state for tinting the new background with the same color state list
- verifyBackgroundIsColoredAs("Emerald tinting in enabled state on red BG",
- textView, ColorUtils.compositeColors(emeraldDefault, backgroundColorRed), 2);
-
- // Disable the text view and check that the background has switched to the matching entry
- // in our current color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(false));
- verifyBackgroundIsColoredAs("Emerald tinting in disabled state on red BG",
- textView, ColorUtils.compositeColors(emeraldDisabled, backgroundColorRed), 2);
-
- // Enable the text view and check that the background has switched to the matching entry
- // in our current color state list.
- onView(withId(textViewId)).perform(AppCompatTintableViewActions.setEnabled(true));
- verifyBackgroundIsColoredAs("Emerald tinting in re-enabled state on red BG",
- textView, ColorUtils.compositeColors(emeraldDefault, backgroundColorRed), 2);
- }
}