1 /* 2 * Copyright (C) 2008 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 android.widget.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNotNull; 21 import static org.junit.Assert.assertSame; 22 import static org.junit.Assert.assertTrue; 23 24 import android.content.Context; 25 import android.view.LayoutInflater; 26 import android.view.View; 27 import android.widget.LinearLayout; 28 import android.widget.SimpleExpandableListAdapter; 29 import android.widget.TextView; 30 import android.widget.TwoLineListItem; 31 32 import androidx.test.InstrumentationRegistry; 33 import androidx.test.annotation.UiThreadTest; 34 import androidx.test.filters.SmallTest; 35 import androidx.test.runner.AndroidJUnit4; 36 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 41 import java.util.ArrayList; 42 import java.util.HashMap; 43 44 /** 45 * Test {@link SimpleExpandableListAdapter}. 46 */ 47 @SmallTest 48 @RunWith(AndroidJUnit4.class) 49 public class SimpleExpandableListAdapterTest { 50 private static final int EXPANDED_GROUP_LAYOUT = android.R.layout.simple_expandable_list_item_2; 51 52 private static final int LAST_CHILD_LAYOUT = android.R.layout.simple_list_item_2; 53 54 private static final int CHILD_LAYOUT = android.R.layout.simple_list_item_1; 55 56 private static final int GROUP_LAYOUT = android.R.layout.simple_expandable_list_item_1; 57 58 private static final int[] VIEWS_GROUP_TO = new int[] { 59 android.R.id.text1 60 }; 61 62 private static final int[] VIEWS_CHILD_TO = new int[] { 63 android.R.id.text1 64 }; 65 66 private static final String[] COLUMNS_GROUP_FROM = new String[] { 67 "column0" 68 }; 69 70 private static final String[] COLUMNS_CHILD_FROM = new String[] { 71 "column0" 72 }; 73 74 private SimpleExpandableListAdapter mSimpleExpandableListAdapter; 75 76 private Context mContext; 77 78 /** 79 * The child list.Each data are prefixed with "child". The content will be 80 * set to 4 sub lists. Each sub list has 1 column. The first sub list has 1 81 * row, the second has 2 rows, the third has 3 rows and the last has 4 rows 82 */ 83 private ArrayList<ArrayList<HashMap<String, String>>> mChildList; 84 85 /** 86 * The group list. Each data are prefixed with "group". The content will be 87 * set to 1 column and 4 rows 88 */ 89 private ArrayList<HashMap<String, String>> mGroupList; 90 91 private LinearLayout mAdapterHost; 92 93 @Before 94 public void setup() { 95 mContext = InstrumentationRegistry.getTargetContext(); 96 mSimpleExpandableListAdapter = null; 97 mGroupList = createTestList(1, 4, "group"); 98 mChildList = new ArrayList<>(); 99 for (int i = 0; i < 4; i++) { 100 ArrayList<HashMap<String, String>> l = createTestList(1, i + 1, "child"); 101 mChildList.add(l); 102 } 103 104 mSimpleExpandableListAdapter = new SimpleExpandableListAdapter(mContext, 105 mGroupList, GROUP_LAYOUT, COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 106 mChildList, CHILD_LAYOUT, COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 107 108 mAdapterHost = (LinearLayout) ((LayoutInflater) mContext 109 .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate( 110 R.layout.cursoradapter_host, null); 111 } 112 113 @Test 114 public void testConstructor() { 115 new SimpleExpandableListAdapter(mContext, 116 mGroupList, GROUP_LAYOUT, COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 117 mChildList, CHILD_LAYOUT, COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 118 119 new SimpleExpandableListAdapter(mContext, 120 mGroupList, GROUP_LAYOUT, EXPANDED_GROUP_LAYOUT, 121 COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 122 mChildList, CHILD_LAYOUT, COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 123 124 new SimpleExpandableListAdapter(mContext, 125 mGroupList, GROUP_LAYOUT, EXPANDED_GROUP_LAYOUT, 126 COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 127 mChildList, CHILD_LAYOUT, LAST_CHILD_LAYOUT, 128 COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 129 } 130 131 @Test 132 public void testGetChild() { 133 HashMap<String, String> expected = new HashMap<>(); 134 expected.put("column0", "child00"); 135 assertEquals(expected, mSimpleExpandableListAdapter.getChild(0, 0)); 136 137 expected = new HashMap<String, String>(); 138 expected.put("column0", "child30"); 139 assertEquals(expected, mSimpleExpandableListAdapter.getChild(3, 3)); 140 } 141 142 @UiThreadTest 143 @Test(expected=IndexOutOfBoundsException.class) 144 public void testGetChildGroupPositionTooLow() { 145 mSimpleExpandableListAdapter.getChild(-1, 0); 146 } 147 148 @UiThreadTest 149 @Test(expected=IndexOutOfBoundsException.class) 150 public void testGetChildGroupPositionTooHigh() { 151 mSimpleExpandableListAdapter.getChild(4, 0); 152 } 153 154 @UiThreadTest 155 @Test(expected=IndexOutOfBoundsException.class) 156 public void testGetChildChildPositionTooLow() { 157 mSimpleExpandableListAdapter.getChild(0, -1); 158 } 159 160 @UiThreadTest 161 @Test(expected=IndexOutOfBoundsException.class) 162 public void testGetChildChildPositionTooHigh() { 163 mSimpleExpandableListAdapter.getChild(0, 1); 164 } 165 166 @Test 167 public void testGetChildId() { 168 assertEquals(0, mSimpleExpandableListAdapter.getChildId(0, 0)); 169 assertEquals(3, mSimpleExpandableListAdapter.getChildId(3, 3)); 170 171 // the following indexes are out of bounds 172 assertEquals(0, mSimpleExpandableListAdapter.getChildId(-1, 0)); 173 assertEquals(-1, mSimpleExpandableListAdapter.getChildId(0, -1)); 174 assertEquals(0, mSimpleExpandableListAdapter.getChildId(4, 0)); 175 assertEquals(4, mSimpleExpandableListAdapter.getChildId(0, 4)); 176 } 177 178 @UiThreadTest 179 @Test 180 public void testGetChildView() { 181 // the normal and last use same layout 182 View result = mSimpleExpandableListAdapter.getChildView(0, 0, false, null, mAdapterHost); 183 assertTrue(result instanceof TextView); 184 assertEquals("child00", ((TextView) result).getText().toString()); 185 186 result = mSimpleExpandableListAdapter.getChildView(3, 3, true, null, mAdapterHost); 187 assertTrue(result instanceof TextView); 188 assertEquals("child30", ((TextView) result).getText().toString()); 189 190 // the normal and last use different layouts 191 mSimpleExpandableListAdapter = new SimpleExpandableListAdapter(mContext, 192 mGroupList, GROUP_LAYOUT, EXPANDED_GROUP_LAYOUT, 193 COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 194 mChildList, CHILD_LAYOUT, LAST_CHILD_LAYOUT, 195 COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 196 197 result = mSimpleExpandableListAdapter.getChildView(0, 0, false, null, mAdapterHost); 198 assertTrue(result instanceof TextView); 199 assertEquals("child00", ((TextView) result).getText().toString()); 200 201 result = mSimpleExpandableListAdapter.getChildView(3, 3, true, null, mAdapterHost); 202 assertTrue(result instanceof TwoLineListItem); 203 assertEquals("child30", 204 ((TextView) result.findViewById(android.R.id.text1)).getText().toString()); 205 206 // use convert view 207 View convertView = new TextView(mContext); 208 convertView.setId(android.R.id.text1); 209 result = mSimpleExpandableListAdapter.getChildView(2, 2, false, convertView, mAdapterHost); 210 assertSame(convertView, result); 211 assertEquals("child20", ((TextView) result).getText().toString()); 212 213 // the parent can be null 214 convertView = new TextView(mContext); 215 convertView.setId(android.R.id.text1); 216 result = mSimpleExpandableListAdapter.getChildView(1, 1, false, convertView, null); 217 assertSame(convertView, result); 218 assertEquals("child10", ((TextView) result).getText().toString()); 219 } 220 221 @UiThreadTest 222 @Test(expected=IndexOutOfBoundsException.class) 223 public void testGetChildViewGroupPositionTooLow() { 224 mSimpleExpandableListAdapter.getChildView(-1, 0, false, null, mAdapterHost); 225 } 226 227 @UiThreadTest 228 @Test(expected=IndexOutOfBoundsException.class) 229 public void testGetChildViewGroupPositionTooHigh() { 230 mSimpleExpandableListAdapter.getChildView(4, 0, false, null, mAdapterHost); 231 } 232 233 @UiThreadTest 234 @Test(expected=IndexOutOfBoundsException.class) 235 public void testGetChildViewChildPositionTooLow() { 236 mSimpleExpandableListAdapter.getChildView(0, -1, false, null, mAdapterHost); 237 } 238 239 @UiThreadTest 240 @Test(expected=IndexOutOfBoundsException.class) 241 public void testGetChildViewChildPositionTooHigh() { 242 mSimpleExpandableListAdapter.getChildView(0, 1, false, null, mAdapterHost); 243 } 244 245 @UiThreadTest 246 @Test 247 public void testNewChildView() { 248 // the normal and last use same layout 249 View result = mSimpleExpandableListAdapter.newChildView(false, mAdapterHost); 250 assertTrue(result instanceof TextView); 251 assertNotNull(result.findViewById(android.R.id.text1)); 252 253 result = mSimpleExpandableListAdapter.newChildView(true, mAdapterHost); 254 assertTrue(result instanceof TextView); 255 assertNotNull(result.findViewById(android.R.id.text1)); 256 257 // the normal and last use different layouts 258 mSimpleExpandableListAdapter = new SimpleExpandableListAdapter(mContext, 259 mGroupList, GROUP_LAYOUT, EXPANDED_GROUP_LAYOUT, 260 COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 261 mChildList, CHILD_LAYOUT, LAST_CHILD_LAYOUT, 262 COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 263 264 result = mSimpleExpandableListAdapter.newChildView(false, mAdapterHost); 265 assertTrue(result instanceof TextView); 266 assertNotNull(result.findViewById(android.R.id.text1)); 267 268 result = mSimpleExpandableListAdapter.newChildView(true, mAdapterHost); 269 assertTrue(result instanceof TwoLineListItem); 270 assertNotNull(result.findViewById(android.R.id.text1)); 271 } 272 273 @Test 274 public void testGetChildrenCount() { 275 assertEquals(1, mSimpleExpandableListAdapter.getChildrenCount(0)); 276 assertEquals(2, mSimpleExpandableListAdapter.getChildrenCount(1)); 277 assertEquals(3, mSimpleExpandableListAdapter.getChildrenCount(2)); 278 assertEquals(4, mSimpleExpandableListAdapter.getChildrenCount(3)); 279 } 280 281 @Test(expected=IndexOutOfBoundsException.class) 282 public void testGetChildrenCountGroupPositionTooLow() { 283 mSimpleExpandableListAdapter.getChildrenCount(-1); 284 } 285 286 @Test(expected=IndexOutOfBoundsException.class) 287 public void testGetChildrenCountGroupPositionTooHigh() { 288 mSimpleExpandableListAdapter.getChildrenCount(4); 289 } 290 291 @Test 292 public void testGetGroup() { 293 HashMap<String, String> expected = new HashMap<>(); 294 expected.put("column0", "group00"); 295 assertEquals(expected, mSimpleExpandableListAdapter.getGroup(0)); 296 297 expected = new HashMap<>(); 298 expected.put("column0", "group30"); 299 assertEquals(expected, mSimpleExpandableListAdapter.getGroup(3)); 300 } 301 302 @Test(expected=IndexOutOfBoundsException.class) 303 public void testGetGroupGroupPositionTooLow() { 304 mSimpleExpandableListAdapter.getGroup(-1); 305 } 306 307 @Test(expected=IndexOutOfBoundsException.class) 308 public void testGetGroupGroupPositionTooHigh() { 309 mSimpleExpandableListAdapter.getGroup(4); 310 } 311 312 @Test 313 public void testGetGroupCount() { 314 assertEquals(4, mSimpleExpandableListAdapter.getGroupCount()); 315 316 mSimpleExpandableListAdapter = new SimpleExpandableListAdapter(mContext, 317 createTestList(1, 9, ""), GROUP_LAYOUT, COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 318 mChildList, CHILD_LAYOUT, COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 319 assertEquals(9, mSimpleExpandableListAdapter.getGroupCount()); 320 } 321 322 @Test 323 public void testGetGroupId() { 324 assertEquals(0, mSimpleExpandableListAdapter.getGroupId(0)); 325 assertEquals(3, mSimpleExpandableListAdapter.getGroupId(3)); 326 327 // following indexes are out of bounds 328 assertEquals(-1, mSimpleExpandableListAdapter.getGroupId(-1)); 329 assertEquals(4, mSimpleExpandableListAdapter.getGroupId(4)); 330 } 331 332 @UiThreadTest 333 @Test 334 public void testGetGroupView() { 335 // the collapsed and expanded use same layout 336 View result = mSimpleExpandableListAdapter.getGroupView(0, false, null, mAdapterHost); 337 assertTrue(result instanceof TextView); 338 assertEquals("group00", ((TextView) result).getText().toString()); 339 340 result = mSimpleExpandableListAdapter.getGroupView(3, true, null, mAdapterHost); 341 assertTrue(result instanceof TextView); 342 assertEquals("group30", ((TextView) result).getText().toString()); 343 344 // the collapsed and expanded use different layouts 345 mSimpleExpandableListAdapter = new SimpleExpandableListAdapter(mContext, 346 mGroupList, GROUP_LAYOUT, EXPANDED_GROUP_LAYOUT, 347 COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 348 mChildList, CHILD_LAYOUT, LAST_CHILD_LAYOUT, 349 COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 350 351 result = mSimpleExpandableListAdapter.getGroupView(0, true, null, mAdapterHost); 352 assertTrue(result instanceof TextView); 353 assertEquals("group00", ((TextView) result).getText().toString()); 354 355 result = mSimpleExpandableListAdapter.getGroupView(3, false, null, mAdapterHost); 356 assertTrue(result instanceof TwoLineListItem); 357 assertEquals("group30", 358 ((TextView) result.findViewById(android.R.id.text1)).getText().toString()); 359 360 // use convert view 361 View convertView = new TextView(mContext); 362 convertView.setId(android.R.id.text1); 363 result = mSimpleExpandableListAdapter.getGroupView(2, false, convertView, mAdapterHost); 364 assertSame(convertView, result); 365 assertEquals("group20", ((TextView) result).getText().toString()); 366 367 // the parent can be null 368 convertView = new TextView(mContext); 369 convertView.setId(android.R.id.text1); 370 result = mSimpleExpandableListAdapter.getGroupView(1, false, convertView, null); 371 assertSame(convertView, result); 372 assertEquals("group10", ((TextView) result).getText().toString()); 373 } 374 375 @UiThreadTest 376 @Test(expected=IndexOutOfBoundsException.class) 377 public void testGetGroupViewGroupPositionTooLow() { 378 mSimpleExpandableListAdapter.getGroupView(-1, false, null, mAdapterHost); 379 } 380 381 @UiThreadTest 382 @Test(expected=IndexOutOfBoundsException.class) 383 public void testGetGroupViewGroupPositionTooHigh() { 384 mSimpleExpandableListAdapter.getGroupView(4, false, null, mAdapterHost); 385 } 386 387 @UiThreadTest 388 @Test 389 public void testNewGroupView() { 390 // the collapsed and expanded use same layout 391 View result = mSimpleExpandableListAdapter.newGroupView(false, mAdapterHost); 392 assertTrue(result instanceof TextView); 393 assertNotNull(result.findViewById(android.R.id.text1)); 394 395 result = mSimpleExpandableListAdapter.newGroupView(true, mAdapterHost); 396 assertTrue(result instanceof TextView); 397 assertNotNull(result.findViewById(android.R.id.text1)); 398 399 // the collapsed and expanded use different layouts 400 mSimpleExpandableListAdapter = new SimpleExpandableListAdapter(mContext, 401 mGroupList, GROUP_LAYOUT, EXPANDED_GROUP_LAYOUT, 402 COLUMNS_GROUP_FROM, VIEWS_GROUP_TO, 403 mChildList, CHILD_LAYOUT, LAST_CHILD_LAYOUT, 404 COLUMNS_CHILD_FROM, VIEWS_CHILD_TO); 405 406 result = mSimpleExpandableListAdapter.newGroupView(true, mAdapterHost); 407 assertTrue(result instanceof TextView); 408 assertNotNull(result.findViewById(android.R.id.text1)); 409 410 result = mSimpleExpandableListAdapter.newGroupView(false, mAdapterHost); 411 assertTrue(result instanceof TwoLineListItem); 412 assertNotNull(result.findViewById(android.R.id.text1)); 413 } 414 415 @Test 416 public void testIsChildSelectable() { 417 assertTrue(mSimpleExpandableListAdapter.isChildSelectable(0, 0)); 418 assertTrue(mSimpleExpandableListAdapter.isChildSelectable(3, 3)); 419 420 // following indexes are out of bounds 421 assertTrue(mSimpleExpandableListAdapter.isChildSelectable(-1, 0)); 422 assertTrue(mSimpleExpandableListAdapter.isChildSelectable(0, -1)); 423 assertTrue(mSimpleExpandableListAdapter.isChildSelectable(4, 0)); 424 assertTrue(mSimpleExpandableListAdapter.isChildSelectable(0, 1)); 425 } 426 427 @Test 428 public void testHasStableIds() { 429 assertTrue(mSimpleExpandableListAdapter.hasStableIds()); 430 } 431 432 /** 433 * Creates the test list. 434 * 435 * @param colCount the column count 436 * @param rowCount the row count 437 * @param prefix the prefix 438 * @return the array list< hash map< string, string>> 439 */ 440 private ArrayList<HashMap<String, String>> createTestList(int colCount, int rowCount, 441 String prefix) { 442 ArrayList<HashMap<String, String>> list = new ArrayList<>(); 443 String[] columns = new String[colCount]; 444 for (int i = 0; i < colCount; i++) { 445 columns[i] = "column" + i; 446 } 447 448 for (int i = 0; i < rowCount; i++) { 449 HashMap<String, String> row = new HashMap<>(); 450 for (int j = 0; j < colCount; j++) { 451 row.put(columns[j], prefix + i + "" + j); 452 } 453 list.add(row); 454 } 455 456 return list; 457 } 458 } 459