1/* 2 * Copyright (C) 2015 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 */ 16 17package android.support.v7.app; 18 19import org.junit.Test; 20 21import android.content.Context; 22import android.content.res.Resources; 23import android.graphics.Color; 24import android.os.Build; 25import android.support.v7.appcompat.test.R; 26import android.support.v7.widget.AppCompatAutoCompleteTextView; 27import android.support.v7.widget.AppCompatButton; 28import android.support.v7.widget.AppCompatCheckBox; 29import android.support.v7.widget.AppCompatEditText; 30import android.support.v7.widget.AppCompatMultiAutoCompleteTextView; 31import android.support.v7.widget.AppCompatRadioButton; 32import android.support.v7.widget.AppCompatRatingBar; 33import android.support.v7.widget.AppCompatSpinner; 34import android.test.suitebuilder.annotation.SmallTest; 35import android.util.TypedValue; 36import android.view.LayoutInflater; 37import android.view.View; 38import android.view.ViewGroup; 39 40import static org.junit.Assert.assertEquals; 41import static org.junit.Assert.assertSame; 42import static org.junit.Assert.assertTrue; 43 44public class LayoutInflaterFactoryTestCase 45 extends BaseInstrumentationTestCase<LayoutInflaterFactoryTestActivity> { 46 47 public LayoutInflaterFactoryTestCase() { 48 super(LayoutInflaterFactoryTestActivity.class); 49 } 50 51 @Test 52 @SmallTest 53 public void testAndroidThemeInflation() throws Throwable { 54 runTestOnUiThread(new Runnable() { 55 @Override 56 public void run() { 57 final LayoutInflater inflater = LayoutInflater.from(getActivity()); 58 assertThemedContext(inflater.inflate(R.layout.layout_android_theme, null)); 59 } 60 }); 61 } 62 63 @Test 64 @SmallTest 65 public void testAppThemeInflation() throws Throwable { 66 runTestOnUiThread(new Runnable() { 67 @Override 68 public void run() { 69 final LayoutInflater inflater = LayoutInflater.from(getActivity()); 70 assertThemedContext(inflater.inflate(R.layout.layout_app_theme, null)); 71 } 72 }); 73 } 74 75 @Test 76 @SmallTest 77 public void testAndroidThemeWithChildrenInflation() throws Throwable { 78 if (Build.VERSION.SDK_INT < 11) { 79 // Propagation of themed context to children only works on API 11+. Ignoring test. 80 return; 81 } 82 runTestOnUiThread(new Runnable() { 83 @Override 84 public void run() { 85 LayoutInflater inflater = LayoutInflater.from(getActivity()); 86 final ViewGroup root = (ViewGroup) inflater.inflate( 87 R.layout.layout_android_theme_children, null); 88 89 assertThemedContext(root); 90 91 for (int i = 0; i < root.getChildCount(); i++) { 92 final View child = root.getChildAt(i); 93 assertThemedContext(child); 94 } 95 } 96 }); 97 } 98 99 @Test 100 @SmallTest 101 public void testSpinnerInflation() throws Throwable { 102 testAppCompatWidgetInflation(R.layout.layout_spinner, AppCompatSpinner.class); 103 } 104 105 @Test 106 @SmallTest 107 public void testEditTextInflation() throws Throwable { 108 testAppCompatWidgetInflation(R.layout.layout_edittext, AppCompatEditText.class); 109 } 110 111 @Test 112 @SmallTest 113 public void testButtonInflation() throws Throwable { 114 testAppCompatWidgetInflation(R.layout.layout_button, AppCompatButton.class); 115 } 116 117 @Test 118 @SmallTest 119 public void testRadioButtonInflation() throws Throwable { 120 testAppCompatWidgetInflation(R.layout.layout_radiobutton, AppCompatRadioButton.class); 121 } 122 123 @Test 124 @SmallTest 125 public void testRadioButtonInflationWithVectorButton() throws Throwable { 126 testAppCompatWidgetInflation(R.layout.layout_radiobutton_vector, 127 AppCompatRadioButton.class); 128 } 129 130 @Test 131 @SmallTest 132 public void testCheckBoxInflation() throws Throwable { 133 testAppCompatWidgetInflation(R.layout.layout_checkbox, AppCompatCheckBox.class); 134 } 135 136 @Test 137 @SmallTest 138 public void testActvInflation() throws Throwable { 139 testAppCompatWidgetInflation(R.layout.layout_actv, AppCompatAutoCompleteTextView.class); 140 } 141 142 @Test 143 @SmallTest 144 public void testMactvInflation() throws Throwable { 145 testAppCompatWidgetInflation(R.layout.layout_mactv, 146 AppCompatMultiAutoCompleteTextView.class); 147 } 148 149 @Test 150 @SmallTest 151 public void testRatingBarInflation() throws Throwable { 152 testAppCompatWidgetInflation(R.layout.layout_ratingbar, AppCompatRatingBar.class); 153 } 154 155 @Test 156 @SmallTest 157 public void testDeclarativeOnClickWithContextWrapper() throws Throwable { 158 runTestOnUiThread(new Runnable() { 159 @Override 160 public void run() { 161 LayoutInflater inflater = LayoutInflater.from(getActivity()); 162 View view = inflater.inflate(R.layout.layout_button_themed_onclick, null); 163 164 assertTrue(view.performClick()); 165 assertTrue(getActivity().wasDeclarativeOnClickCalled()); 166 } 167 }); 168 } 169 170 private void testAppCompatWidgetInflation(final int layout, final Class<?> expectedClass) 171 throws Throwable { 172 runTestOnUiThread(new Runnable() { 173 @Override 174 public void run() { 175 LayoutInflater inflater = LayoutInflater.from(getActivity()); 176 View view = inflater.inflate(layout, null); 177 assertSame("View is " + expectedClass.getSimpleName(), expectedClass, 178 view.getClass()); 179 } 180 }); 181 } 182 183 private static void assertThemedContext(View view) { 184 final Context viewContext = view.getContext(); 185 186 final TypedValue colorAccentValue = getColorAccentValue(viewContext.getTheme()); 187 assertTrue(colorAccentValue.type >= TypedValue.TYPE_FIRST_COLOR_INT 188 && colorAccentValue.type <= TypedValue.TYPE_LAST_COLOR_INT); 189 assertEquals("View does not have ContextThemeWrapper context", 190 Color.MAGENTA, colorAccentValue.data); 191 } 192 193 private static TypedValue getColorAccentValue(final Resources.Theme theme) { 194 final TypedValue typedValue = new TypedValue(); 195 theme.resolveAttribute(R.attr.colorAccent, typedValue, true); 196 return typedValue; 197 } 198} 199