1 /* 2 * Copyright (C) 2017 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 17 package androidx.leanback.widget; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertTrue; 22 23 import android.content.Context; 24 import android.support.test.InstrumentationRegistry; 25 import android.support.test.filters.SmallTest; 26 import android.support.test.runner.AndroidJUnit4; 27 import android.text.InputType; 28 import android.view.ContextThemeWrapper; 29 import android.widget.FrameLayout; 30 31 import androidx.core.os.BuildCompat; 32 import androidx.leanback.test.R; 33 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 import java.util.Arrays; 39 40 @SmallTest 41 @RunWith(AndroidJUnit4.class) 42 public class GuidedActionStylistTest { 43 private static final int DEFAULT_MAX_LINES = 0; 44 45 // Simulate Android Context 46 private Context mContext; 47 48 // The GuidedActionStylist for testing purpose 49 private GuidedActionsStylist mGuidedActionsStylist; 50 51 // Mocked view holder, required by the parameter of onBindViewHolder method 52 private GuidedActionsStylist.ViewHolder mViewHolder; 53 54 // Mocked action object, required by the parameter of onBindViewHolder method 55 private GuidedAction mGuidedAction; 56 57 @Before 58 public void setUp() throws Exception { 59 60 // Get context from instrumentation registry firstly 61 mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 62 63 // Then apply the theme on the context 64 mContext = new ContextThemeWrapper(mContext, 65 R.style.Widget_Leanback_GuidedSubActionsListStyle); 66 67 // Prepare GuidedActionStylist object 68 mGuidedActionsStylist = new GuidedActionsStylist(); 69 70 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 71 @Override 72 public void run() { 73 // Create view holder object programmatically 74 mViewHolder = mGuidedActionsStylist.onCreateViewHolder(new FrameLayout(mContext)); 75 } 76 }); 77 } 78 79 /** 80 * Test cases when multilineDescription is set to true 81 */ 82 @Test 83 public void testWhenMultiLineDescriptionSetToTrue() { 84 85 // Create a action and set multilineDescription to true 86 mGuidedAction = new GuidedAction.Builder(mContext).multilineDescription(true).build(); 87 88 // Execute onBindViewHolder method so we can monitor the internal state 89 mGuidedActionsStylist.onBindViewHolder(mViewHolder, mGuidedAction); 90 91 // double check if multilineDescription option has been enabled 92 assertTrue(mGuidedAction.hasMultilineDescription()); 93 94 // currently the title view and description view using the same flag. So when we execute 95 // multilineDescription(true) method, the multi line mode should be enabled both for title 96 // view and description view. 97 // Test cases should be updated when we change this behavior 98 assertTrue((mViewHolder.mTitleView.getInputType() & InputType.TYPE_TEXT_FLAG_MULTI_LINE) 99 == InputType.TYPE_TEXT_FLAG_MULTI_LINE); 100 assertTrue((mViewHolder.mDescriptionView.getInputType() 101 & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == InputType.TYPE_TEXT_FLAG_MULTI_LINE); 102 } 103 104 /** 105 * Test cases when multilineDescription is set to false 106 */ 107 @Test 108 public void testWhenMultiLineDescriptionSetToFalse() { 109 110 // Create a action and set multilineDescription to false 111 mGuidedAction = new GuidedAction.Builder(mContext).multilineDescription(false).build(); 112 113 // Execute onBindViewHolder method so we can monitor the internal state 114 mGuidedActionsStylist.onBindViewHolder(mViewHolder, mGuidedAction); 115 116 // double check if multilineDescription option has been disabled 117 assertFalse(mGuidedAction.hasMultilineDescription()); 118 119 // currently the title view and description view using the same flag. So when we execute 120 // multilineDescription(true) method, the multi line mode should be disabled both for title 121 // view and description view. 122 // Test cases should be updated when we change this behavior 123 assertEquals(mViewHolder.mTitleView.getMaxLines(), DEFAULT_MAX_LINES); 124 assertEquals(mViewHolder.mDescriptionView.getMaxLines(), DEFAULT_MAX_LINES); 125 } 126 127 @Test 128 public void testAutofillHintsOnTitle() { 129 if (!BuildCompat.isAtLeastP()) { 130 return; 131 } 132 String[] hints = new String[]{"hint1", "hint2"}; 133 mGuidedAction = new GuidedAction.Builder(mContext) 134 .editable(true) 135 .autofillHints(hints) 136 .build(); 137 138 assertTrue(BuildCompat.isAtLeastP()); 139 // Execute onBindViewHolder method so we can monitor the internal state 140 mGuidedActionsStylist.onBindViewHolder(mViewHolder, mGuidedAction); 141 142 assertTrue(Arrays.equals(mViewHolder.mTitleView.getAutofillHints(), hints)); 143 144 } 145 146 @Test 147 public void testAutofillHintsOnNonEditableViews() { 148 if (!BuildCompat.isAtLeastP()) { 149 return; 150 } 151 String[] hints = new String[]{"hint1", "hint2"}; 152 mGuidedAction = new GuidedAction.Builder(mContext) 153 .editable(false) 154 .autofillHints(hints) 155 .build(); 156 157 // Execute onBindViewHolder method so we can monitor the internal state 158 mGuidedActionsStylist.onBindViewHolder(mViewHolder, mGuidedAction); 159 160 String[] viewHints = mViewHolder.mTitleView.getAutofillHints(); 161 assertTrue(viewHints == null || viewHints.length == 0); 162 163 viewHints = mViewHolder.mDescriptionView.getAutofillHints(); 164 assertTrue(viewHints == null || viewHints.length == 0); 165 } 166 167 @Test 168 public void testAutofillHintsOnDescription() { 169 if (!BuildCompat.isAtLeastP()) { 170 return; 171 } 172 String[] hints = new String[]{"hint1", "hint2"}; 173 mGuidedAction = new GuidedAction.Builder(mContext) 174 .editable(false) 175 .descriptionEditable(true) 176 .autofillHints(hints) 177 .build(); 178 179 // Execute onBindViewHolder method so we can monitor the internal state 180 mGuidedActionsStylist.onBindViewHolder(mViewHolder, mGuidedAction); 181 182 assertTrue(Arrays.equals(mViewHolder.mDescriptionView.getAutofillHints(), hints)); 183 184 } 185 186 } 187