AppCompatSpinnerTest.java revision 1d6e3840486930e276d142861afb6c7e72d5ce72
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.v7.widget; 17 18import android.content.res.Resources; 19import android.support.annotation.ColorInt; 20import android.support.annotation.ColorRes; 21import android.support.annotation.IdRes; 22import android.support.v4.content.ContextCompat; 23import android.support.v4.content.res.ResourcesCompat; 24import android.support.v7.appcompat.test.R; 25import android.test.suitebuilder.annotation.SmallTest; 26import org.hamcrest.Matcher; 27import org.junit.Test; 28 29import static android.support.test.espresso.Espresso.onView; 30import static android.support.test.espresso.action.ViewActions.click; 31import static android.support.test.espresso.assertion.ViewAssertions.matches; 32import static android.support.test.espresso.matcher.RootMatchers.isPlatformPopup; 33import static android.support.test.espresso.matcher.ViewMatchers.withId; 34import static android.support.test.espresso.matcher.ViewMatchers.withText; 35import static android.support.v7.testutils.TestUtilsMatchers.hasChild; 36import static android.support.v7.testutils.TestUtilsMatchers.isCombinedBackground; 37 38/** 39 * In addition to all tinting-related tests done by the base class, this class provides 40 * tests specific to {@link AppCompatSpinner} class. 41 */ 42@SmallTest 43public class AppCompatSpinnerTest 44 extends AppCompatBaseViewTest<AppCompatSpinnerActivity, AppCompatSpinner> { 45 public AppCompatSpinnerTest() { 46 super(AppCompatSpinnerActivity.class); 47 } 48 49 @Override 50 protected boolean hasBackgroundByDefault() { 51 // Spinner has default background set on it 52 return true; 53 } 54 55 /** 56 * Helper method that verifies that the popup for the specified {@link AppCompatSpinner} 57 * is themed with the specified color. 58 */ 59 private void verifySpinnerPopupTheming(@IdRes int spinnerId, 60 @ColorRes int expectedPopupColorResId, boolean matchDropDownListView) { 61 final Resources res = mActivityTestRule.getActivity().getResources(); 62 final @ColorInt int expectedPopupColor = 63 ResourcesCompat.getColor(res, expectedPopupColorResId, null); 64 final AppCompatSpinner spinner = (AppCompatSpinner) mContainer.findViewById(spinnerId); 65 66 // Click the spinner to show its popup content 67 onView(withId(spinnerId)).perform(click()); 68 69 // The internal implementation details of the AppCompatSpinner's popup content depends 70 // on the platform version itself (in android.widget.PopupWindow) as well as on when the 71 // popup theme is being applied first (in XML or at runtime). Instead of trying to catch 72 // all possible variations of how the popup content is wrapped, we use a view matcher that 73 // creates a single bitmap that combines backgrounds starting from the parent of the 74 // popup content items upwards (drawing them in reverse order), and then tests that the 75 // combined bitmap matches the expected color fill. This should remove dependency on the 76 // internal implementation details on which exact "chrome" part of the popup has the 77 // matching background. 78 String itemText = (String) spinner.getAdapter().getItem(2); 79 Matcher popupContentMatcher = hasChild(withText(itemText)); 80 onView(popupContentMatcher).inRoot(isPlatformPopup()).check( 81 matches(isCombinedBackground(expectedPopupColor))); 82 83 // Click an entry in the popup to dismiss it 84 onView(withText(itemText)).perform(click()); 85 } 86 87 @Test 88 public void testPopupThemingFromXmlAttribute() { 89 verifySpinnerPopupTheming(R.id.view_magenta_themed_popup, R.color.test_magenta, true); 90 } 91 92 @Test 93 public void testUnthemedPopupRuntimeTheming() { 94 final AppCompatSpinner spinner = 95 (AppCompatSpinner) mContainer.findViewById(R.id.view_unthemed_popup); 96 spinner.setPopupBackgroundResource(R.drawable.test_background_blue); 97 verifySpinnerPopupTheming(R.id.view_unthemed_popup, R.color.test_blue, false); 98 99 // Set a different popup background 100 spinner.setPopupBackgroundDrawable(ContextCompat.getDrawable( 101 mActivityTestRule.getActivity(), R.drawable.test_background_green)); 102 verifySpinnerPopupTheming(R.id.view_unthemed_popup, R.color.test_green, false); 103 } 104 105 @Test 106 public void testThemedPopupRuntimeTheming() { 107 final AppCompatSpinner spinner = 108 (AppCompatSpinner) mContainer.findViewById(R.id.view_ocean_themed_popup); 109 verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.ocean_default, true); 110 111 // Now set a different popup background 112 spinner.setPopupBackgroundResource(R.drawable.test_background_red); 113 verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.test_red, false); 114 115 // Set a different popup background 116 spinner.setPopupBackgroundDrawable(ContextCompat.getDrawable( 117 mActivityTestRule.getActivity(), R.drawable.test_background_blue)); 118 verifySpinnerPopupTheming(R.id.view_ocean_themed_popup, R.color.test_blue, false); 119 } 120} 121