/*
 * 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 androidx.appcompat.widget;

import static androidx.appcompat.testutils.AppCompatTintableViewActions.setBackgroundResource;
import static androidx.appcompat.testutils.AppCompatTintableViewActions.setBackgroundTintList;
import static androidx.appcompat.testutils.AppCompatTintableViewActions.setBackgroundTintMode;
import static androidx.appcompat.testutils.TestUtilsActions.setBackgroundTintListViewCompat;
import static androidx.appcompat.testutils.TestUtilsActions.setBackgroundTintModeViewCompat;
import static androidx.appcompat.testutils.TestUtilsActions.setEnabled;
import static androidx.appcompat.testutils.TestUtilsMatchers.isBackground;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;

import static org.junit.Assert.assertNull;

import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.ColorInt;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.appcompat.test.R;
import androidx.appcompat.testutils.AppCompatTintableViewActions;
import androidx.appcompat.testutils.BaseTestActivity;
import androidx.appcompat.testutils.TestUtils;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.ColorUtils;
import androidx.test.espresso.UiController;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * 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).
 */
@RunWith(AndroidJUnit4.class)
@MediumTest
public abstract class AppCompatBaseViewTest<A extends BaseTestActivity, T extends View> {
    @Rule
    public final ActivityTestRule<A> mActivityTestRule;

    protected ViewGroup mContainer;

    protected A mActivity;
    protected UiController mUiController;
    protected Resources mResources;

    public AppCompatBaseViewTest(Class<A> clazz) {
        mActivityTestRule = new ActivityTestRule<>(clazz);
    }

    @Before
    public void setUp() {
        mActivity = mActivityTestRule.getActivity();
        mContainer = mActivity.findViewById(R.id.container);
        mResources = mActivity.getResources();
    }

    /**
     * Subclasses should override this method to return true if by default the matching
     * view (such as, say, {@link AppCompatSpinner}) has background set it.
     */
    protected boolean hasBackgroundByDefault() {
        return false;
    }

    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.
     */
    @Test
    public void testBackgroundTintingWithNoBackground() {
        if (hasBackgroundByDefault()) {
            return;
        }

        final @IdRes int viewId = R.id.view_tinted_no_background;
        final T view = 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(setEnabled(false));
        assertNull("No background after disabling", view.getBackground());

        // Enable the view and check that the background is still null.
        onView(withId(viewId)).perform(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(
                mResources, R.color.color_state_list_sand, null);
        onView(withId(viewId)).perform(
                setBackgroundTintList(sandColor));

        // Disable the view and check that the background is still null.
        onView(withId(viewId)).perform(setEnabled(false));
        assertNull("No background after disabling", view.getBackground());

        // Enable the view and check that the background is still null.
        onView(withId(viewId)).perform(setEnabled(true));
        assertNull("No background after re-enabling", view.getBackground());
    }

    /**
     * This method tests that background tinting is not applied when the
     * tintable view has no background.
     */
    @Test
    public void testBackgroundTintingViewCompatWithNoBackground() {
        if (hasBackgroundByDefault()) {
            return;
        }

        final @IdRes int viewId = R.id.view_tinted_no_background;
        final T view = 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(setEnabled(false));
        assertNull("No background after disabling", view.getBackground());

        // Enable the view and check that the background is still null.
        onView(withId(viewId)).perform(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 lilacColor = ResourcesCompat.getColorStateList(
                mResources, R.color.color_state_list_lilac, null);
        onView(withId(viewId)).perform(setBackgroundTintListViewCompat(lilacColor));

        // Disable the view and check that the background is still null.
        onView(withId(viewId)).perform(setEnabled(false));
        assertNull("No background after disabling", view.getBackground());

        // Enable the view and check that the background is still null.
        onView(withId(viewId)).perform(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.
     */
    @Test
    public void testBackgroundTintingAcrossStateChange() {
        final @IdRes int viewId = R.id.view_tinted_background;
        final T view = mContainer.findViewById(viewId);

        final @ColorInt int lilacDefault = ResourcesCompat.getColor(
                mResources, R.color.lilac_default, null);
        final @ColorInt int lilacDisabled = ResourcesCompat.getColor(
                mResources, R.color.lilac_disabled, null);
        final @ColorInt int sandDefault = ResourcesCompat.getColor(
                mResources, R.color.sand_default, null);
        final @ColorInt int sandDisabled = ResourcesCompat.getColor(
                mResources, R.color.sand_disabled, null);
        final @ColorInt int oceanDefault = ResourcesCompat.getColor(
                mResources, R.color.ocean_default, null);
        final @ColorInt int oceanDisabled = ResourcesCompat.getColor(
                mResources, 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(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(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(
                mResources, R.color.color_state_list_sand, null);
        onView(withId(viewId)).perform(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(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(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(
                mResources, R.color.color_state_list_ocean, null);
        onView(withId(viewId)).perform(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(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(setEnabled(true));
        verifyBackgroundIsColoredAs("New ocean tinting in re-enabled state", view,
                oceanDefault, 0);
    }

    /**
     * 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.
     */
    @Test
    public void testBackgroundTintingViewCompatAcrossStateChange() {
        final @IdRes int viewId = R.id.view_tinted_background;
        final T view = mContainer.findViewById(viewId);

        final @ColorInt int lilacDefault = ResourcesCompat.getColor(
                mResources, R.color.lilac_default, null);
        final @ColorInt int lilacDisabled = ResourcesCompat.getColor(
                mResources, R.color.lilac_disabled, null);
        final @ColorInt int sandDefault = ResourcesCompat.getColor(
                mResources, R.color.sand_default, null);
        final @ColorInt int sandDisabled = ResourcesCompat.getColor(
                mResources, R.color.sand_disabled, null);
        final @ColorInt int oceanDefault = ResourcesCompat.getColor(
                mResources, R.color.ocean_default, null);
        final @ColorInt int oceanDisabled = ResourcesCompat.getColor(
                mResources, 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(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(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(
                mResources, R.color.color_state_list_sand, null);
        onView(withId(viewId)).perform(setBackgroundTintListViewCompat(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(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(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(
                mResources, R.color.color_state_list_ocean, null);
        onView(withId(viewId)).perform(
                setBackgroundTintListViewCompat(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(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(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.
     */
    @Test
    public void testBackgroundTintingAcrossModeChange() {
        final @IdRes int viewId = R.id.view_untinted_background;
        final T view = mContainer.findViewById(viewId);

        final @ColorInt int emeraldDefault = ResourcesCompat.getColor(
                mResources, R.color.emerald_translucent_default, null);
        final @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
                mResources, 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
        final @ColorInt int backgroundColor = ResourcesCompat.getColor(
                mResources, 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(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(
                mResources, R.color.color_state_list_emerald_translucent, null);
        onView(withId(viewId)).perform(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(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(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(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(setEnabled(false));
        verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_over",
                view, ColorUtils.compositeColors(emeraldDisabled, backgroundColor),
                allowedComponentVariance);
    }

    /**
     * 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.
     */
    @Test
    public void testBackgroundTintingViewCompatAcrossModeChange() {
        final @IdRes int viewId = R.id.view_untinted_background;
        final T view = mContainer.findViewById(viewId);

        final @ColorInt int emeraldDefault = ResourcesCompat.getColor(
                mResources, R.color.emerald_translucent_default, null);
        final @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
                mResources, 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
        final @ColorInt int backgroundColor = ResourcesCompat.getColor(
                mResources, 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(setBackgroundTintModeViewCompat(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(
                mResources, R.color.color_state_list_emerald_translucent, null);
        onView(withId(viewId)).perform(setBackgroundTintListViewCompat(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(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(setBackgroundTintModeViewCompat(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(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(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.
     */
    @Test
    public void testBackgroundOpaqueTintingAcrossBackgroundChange() {
        final @IdRes int viewId = R.id.view_tinted_no_background;
        final T view = mContainer.findViewById(viewId);

        final @ColorInt int lilacDefault = ResourcesCompat.getColor(
                mResources, R.color.lilac_default, null);
        final @ColorInt int lilacDisabled = ResourcesCompat.getColor(
                mResources, R.color.lilac_disabled, null);

        if (!hasBackgroundByDefault()) {
            assertNull("No background after XML loading", view.getBackground());
        }

        // Set background on our view
        onView(withId(viewId)).perform(setBackgroundResource(R.drawable.test_background_green));

        // 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(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(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(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(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.
     */
    @Test
    public void testBackgroundTranslucentTintingAcrossBackgroundChange() {
        final @IdRes int viewId = R.id.view_untinted_no_background;
        final T view = mContainer.findViewById(viewId);

        final @ColorInt int emeraldDefault = ResourcesCompat.getColor(
                mResources, R.color.emerald_translucent_default, null);
        final @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
                mResources, 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
        final @ColorInt int backgroundColorGreen = ResourcesCompat.getColor(
                mResources, R.color.test_green, null);
        final @ColorInt int backgroundColorRed = ResourcesCompat.getColor(
                mResources, R.color.test_red, null);

        if (!hasBackgroundByDefault()) {
            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(setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
        // Load and set a translucent color state list as the background tint list
        final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
                mResources, R.color.color_state_list_emerald_translucent, null);
        onView(withId(viewId)).perform(
                setBackgroundTintList(emeraldColor));

        // Set background on our view
        onView(withId(viewId)).perform(setBackgroundResource(R.drawable.test_background_green));

        // 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(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(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(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(setEnabled(true));
        verifyBackgroundIsColoredAs("Emerald tinting in re-enabled state on red background",
                view, ColorUtils.compositeColors(emeraldDefault, backgroundColorRed),
                allowedComponentVariance);
    }

    protected void testUntintedBackgroundTintingViewCompatAcrossStateChange(@IdRes int viewId) {
        final T view = mContainer.findViewById(viewId);

        final @ColorInt int oceanDefault = ResourcesCompat.getColor(
                mResources, R.color.ocean_default, null);
        final @ColorInt int oceanDisabled = ResourcesCompat.getColor(
                mResources, R.color.ocean_disabled, null);

        final ColorStateList oceanColor = ResourcesCompat.getColorStateList(
                mResources, R.color.color_state_list_ocean, null);
        onView(withId(viewId)).perform(setBackgroundTintListViewCompat(oceanColor));

        // 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(setEnabled(false))
                .check(matches(isBackground(oceanDisabled, true)));

        // 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(setEnabled(true))
                .check(matches(isBackground(oceanDefault, true)));
    }
}
