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 com.android.cts.stub.R; 20 21 22 import android.app.Activity; 23 import android.app.ActivityGroup; 24 import android.content.Intent; 25 import android.test.ActivityInstrumentationTestCase2; 26 import android.test.UiThreadTest; 27 import android.view.View; 28 import android.widget.ListView; 29 import android.widget.TabHost; 30 import android.widget.TextView; 31 import android.widget.TabHost.OnTabChangeListener; 32 import android.widget.TabHost.TabSpec; 33 34 /** 35 * Test {@link TabHost}. 36 */ 37 public class TabHostTest extends ActivityInstrumentationTestCase2<TabHostStubActivity> { 38 private static final String TAG_TAB1 = "tab 1"; 39 private static final String TAG_TAB2 = "tab 2"; 40 private static final int TAB_HOST_ID = android.R.id.tabhost; 41 42 private TabHostStubActivity mActivity; 43 44 public TabHostTest() { 45 super("com.android.cts.stub", TabHostStubActivity.class); 46 } 47 48 @Override 49 protected void setUp() throws Exception { 50 super.setUp(); 51 mActivity = getActivity(); 52 } 53 54 public void testConstructor() { 55 new TabHost(mActivity); 56 57 new TabHost(mActivity, null); 58 } 59 60 public void testNewTabSpec() { 61 TabHost tabHost = new TabHost(mActivity); 62 63 assertNotNull(tabHost.newTabSpec(TAG_TAB2)); 64 65 assertNotNull(tabHost.newTabSpec(null)); 66 } 67 68 /* 69 * Check points: 70 * 1. the tabWidget view and tabContent view associated with tabHost are created. 71 * 2. no exception occurs when doing normal operation after setup(). 72 */ 73 public void testSetup1() throws Throwable { 74 final Activity activity = launchActivity("com.android.cts.stub", StubActivity.class, null); 75 76 runTestOnUiThread(new Runnable() { 77 public void run() { 78 activity.setContentView(R.layout.tabhost_layout); 79 80 TabHost tabHost = (TabHost) activity.findViewById(TAB_HOST_ID); 81 assertNull(tabHost.getTabWidget()); 82 assertNull(tabHost.getTabContentView()); 83 tabHost.setup(); 84 assertNotNull(tabHost.getTabWidget()); 85 assertNotNull(tabHost.getTabContentView()); 86 87 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB1); 88 tabSpec.setIndicator(TAG_TAB1); 89 tabSpec.setContent(new MyTabContentFactoryList()); 90 tabHost.addTab(tabSpec); 91 tabHost.setCurrentTab(0); 92 } 93 }); 94 getInstrumentation().waitForIdleSync(); 95 96 activity.finish(); 97 } 98 99 /* 100 * Check points: 101 * 1. the tabWidget view and tabContent view associated with tabHost are created. 102 * 2. no exception occurs when uses TabSpec.setContent(android.content.Intent) after setup(). 103 */ 104 public void testSetup2() throws Throwable { 105 final ActivityGroup activity = launchActivity("com.android.cts.stub", 106 ActivityGroup.class, null); 107 108 109 runTestOnUiThread(new Runnable() { 110 public void run() { 111 activity.setContentView(R.layout.tabhost_layout); 112 113 TabHost tabHost = (TabHost) activity.findViewById(TAB_HOST_ID); 114 assertNull(tabHost.getTabWidget()); 115 assertNull(tabHost.getTabContentView()); 116 tabHost.setup(activity.getLocalActivityManager()); 117 assertNotNull(tabHost.getTabWidget()); 118 assertNotNull(tabHost.getTabContentView()); 119 120 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB1); 121 tabSpec.setIndicator(TAG_TAB1); 122 Intent intent = new Intent(Intent.ACTION_VIEW, null, 123 mActivity, StubActivity.class); 124 tabSpec.setContent(intent); 125 tabHost.addTab(tabSpec); 126 tabHost.setCurrentTab(0); 127 } 128 }); 129 getInstrumentation().waitForIdleSync(); 130 131 activity.finish(); 132 } 133 134 public void testOnTouchModeChanged() { 135 // implementation details 136 } 137 138 @UiThreadTest 139 public void testAddTab() { 140 TabHost tabHost = mActivity.getTabHost(); 141 // there is a initial tab 142 assertEquals(1, tabHost.getTabWidget().getChildCount()); 143 144 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 145 tabSpec.setIndicator(TAG_TAB2); 146 tabSpec.setContent(new MyTabContentFactoryList()); 147 tabHost.addTab(tabSpec); 148 assertEquals(2, tabHost.getTabWidget().getChildCount()); 149 tabHost.setCurrentTab(1); 150 assertTrue(tabHost.getCurrentView() instanceof ListView); 151 assertEquals(TAG_TAB2, tabHost.getCurrentTabTag()); 152 153 try { 154 tabHost.addTab(tabHost.newTabSpec("tab 3")); 155 fail("Should throw IllegalArgumentException"); 156 } catch (IllegalArgumentException e) { 157 } 158 159 try { 160 tabHost.addTab(tabHost.newTabSpec("tab 3").setIndicator("tab 3")); 161 fail("Should throw IllegalArgumentException"); 162 } catch (IllegalArgumentException e) { 163 } 164 165 try { 166 tabHost.addTab(null); 167 fail("Should throw NullPointerException"); 168 } catch (NullPointerException e) { 169 } 170 } 171 172 @UiThreadTest 173 public void testClearAllTabs() { 174 TabHost tabHost = mActivity.getTabHost(); 175 MyTabContentFactoryText tcf = new MyTabContentFactoryText(); 176 // add two additional tabs 177 tabHost.addTab(tabHost.newTabSpec(TAG_TAB1).setIndicator(TAG_TAB1).setContent(tcf)); 178 tabHost.addTab(tabHost.newTabSpec(TAG_TAB2).setIndicator(TAG_TAB2).setContent(tcf)); 179 assertEquals(3, tabHost.getTabWidget().getChildCount()); 180 assertEquals(3, tabHost.getTabContentView().getChildCount()); 181 assertEquals(0, tabHost.getCurrentTab()); 182 assertNotNull(tabHost.getCurrentView()); 183 184 /* 185 TODO: Uncomment after fixing clearAllTabs() issue. 186 The code below throws a NullPointerException in clearAllTabs(). The method throwing the 187 exception is TabWidget.onFocusChange(). 188 189 tabHost.clearAllTabs(); 190 191 assertEquals(0, tabHost.getTabWidget().getChildCount()); 192 assertEquals(0, tabHost.getTabContentView().getChildCount()); 193 assertEquals(-1, tabHost.getCurrentTab()); 194 assertNull(tabHost.getCurrentView()); 195 */ 196 } 197 198 public void testGetTabWidget() { 199 TabHost tabHost = mActivity.getTabHost(); 200 201 // The attributes defined in tabhost_layout.xml 202 assertEquals(android.R.id.tabs, tabHost.getTabWidget().getId()); 203 WidgetTestUtils.assertScaledPixels(1, tabHost.getTabWidget().getPaddingLeft(), 204 getActivity()); 205 WidgetTestUtils.assertScaledPixels(1, tabHost.getTabWidget().getPaddingRight(), 206 getActivity()); 207 WidgetTestUtils.assertScaledPixels(4, tabHost.getTabWidget().getPaddingTop(), 208 getActivity()); 209 } 210 211 @UiThreadTest 212 public void testAccessCurrentTab() { 213 TabHost tabHost = mActivity.getTabHost(); 214 assertEquals(0, tabHost.getCurrentTab()); 215 216 // normal value 217 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 218 tabSpec.setIndicator(TAG_TAB2); 219 tabSpec.setContent(new MyTabContentFactoryText()); 220 tabHost.addTab(tabSpec); 221 tabHost.setCurrentTab(1); 222 assertEquals(1, tabHost.getCurrentTab()); 223 tabHost.setCurrentTab(0); 224 assertEquals(0, tabHost.getCurrentTab()); 225 226 // exceptional value 227 tabHost.setCurrentTab(tabHost.getTabWidget().getChildCount() + 1); 228 assertEquals(0, tabHost.getCurrentTab()); 229 tabHost.setCurrentTab(-1); 230 assertEquals(0, tabHost.getCurrentTab()); 231 } 232 233 @UiThreadTest 234 public void testGetCurrentTabView() { 235 TabHost tabHost = mActivity.getTabHost(); 236 // current tab view is the first child of tabWidget. 237 assertSame(tabHost.getTabWidget().getChildAt(0), tabHost.getCurrentTabView()); 238 239 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 240 tabSpec.setIndicator(TAG_TAB2); 241 tabSpec.setContent(new MyTabContentFactoryText()); 242 tabHost.addTab(tabSpec); 243 tabHost.setCurrentTab(1); 244 // current tab view is the second child of tabWidget. 245 assertSame(tabHost.getTabWidget().getChildAt(1), tabHost.getCurrentTabView()); 246 } 247 248 @UiThreadTest 249 public void testGetCurrentView() { 250 TabHost tabHost = mActivity.getTabHost(); 251 TextView textView = (TextView) tabHost.getCurrentView(); 252 assertEquals(TabHostStubActivity.INITIAL_VIEW_TEXT, textView.getText().toString()); 253 254 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 255 tabSpec.setIndicator(TAG_TAB2); 256 tabSpec.setContent(new MyTabContentFactoryList()); 257 tabHost.addTab(tabSpec); 258 tabHost.setCurrentTab(1); 259 assertTrue(tabHost.getCurrentView() instanceof ListView); 260 } 261 262 @UiThreadTest 263 public void testSetCurrentTabByTag() { 264 TabHost tabHost = mActivity.getTabHost(); 265 266 // set CurrentTab 267 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 268 tabSpec.setIndicator(TAG_TAB2); 269 tabSpec.setContent(new MyTabContentFactoryText()); 270 tabHost.addTab(tabSpec); 271 272 tabHost.setCurrentTabByTag(TAG_TAB2); 273 assertEquals(1, tabHost.getCurrentTab()); 274 275 tabHost.setCurrentTabByTag(TabHostStubActivity.INITIAL_TAB_TAG); 276 assertEquals(0, tabHost.getCurrentTab()); 277 278 // exceptional value 279 tabHost.setCurrentTabByTag(null); 280 assertEquals(0, tabHost.getCurrentTab()); 281 282 tabHost.setCurrentTabByTag("unknown tag"); 283 assertEquals(0, tabHost.getCurrentTab()); 284 } 285 286 @UiThreadTest 287 public void testGetTabContentView() { 288 TabHost tabHost = mActivity.getTabHost(); 289 assertEquals(3, tabHost.getTabContentView().getChildCount()); 290 291 TextView child0 = (TextView) tabHost.getTabContentView().getChildAt(0); 292 assertEquals(mActivity.getResources().getString(R.string.hello_world), 293 child0.getText().toString()); 294 assertTrue(tabHost.getTabContentView().getChildAt(1) instanceof ListView); 295 TextView child2 = (TextView) tabHost.getTabContentView().getChildAt(2); 296 tabHost.setCurrentTab(0); 297 assertEquals(TabHostStubActivity.INITIAL_VIEW_TEXT, child2.getText().toString()); 298 299 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 300 tabSpec.setIndicator(TAG_TAB2); 301 tabSpec.setContent(new MyTabContentFactoryList()); 302 tabHost.addTab(tabSpec); 303 assertEquals(3, tabHost.getTabContentView().getChildCount()); 304 tabHost.setCurrentTab(1); 305 assertEquals(4, tabHost.getTabContentView().getChildCount()); 306 307 child0 = (TextView) tabHost.getTabContentView().getChildAt(0); 308 assertEquals(mActivity.getResources().getString(R.string.hello_world), 309 child0.getText().toString()); 310 assertTrue(tabHost.getTabContentView().getChildAt(1) instanceof ListView); 311 child2 = (TextView) tabHost.getTabContentView().getChildAt(2); 312 tabHost.setCurrentTab(0); 313 assertEquals(TabHostStubActivity.INITIAL_VIEW_TEXT, child2.getText().toString()); 314 } 315 316 @UiThreadTest 317 public void testDispatchKeyEvent() { 318 // Implementation details. 319 } 320 321 @UiThreadTest 322 public void testDispatchWindowFocusChanged() { 323 // Implementation details 324 } 325 326 /** 327 * Check points: 328 * 1. the specified callback should be invoked when the selected state of any of the items 329 * in this list changes 330 */ 331 @UiThreadTest 332 public void testSetOnTabChangedListener() { 333 TabHost tabHost = mActivity.getTabHost(); 334 335 // add a tab, and change current tab to the new tab 336 MockOnTabChangeListener listener = new MockOnTabChangeListener(); 337 tabHost.setOnTabChangedListener(listener); 338 339 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 340 tabSpec.setIndicator(TAG_TAB2); 341 tabSpec.setContent(new MyTabContentFactoryList()); 342 tabHost.addTab(tabSpec); 343 tabHost.setCurrentTab(1); 344 assertTrue(listener.hasCalledOnTabChanged()); 345 346 // change current tab to the first one 347 listener.reset(); 348 tabHost.setCurrentTab(0); 349 assertTrue(listener.hasCalledOnTabChanged()); 350 351 // set the same tab 352 listener.reset(); 353 tabHost.setCurrentTab(0); 354 assertFalse(listener.hasCalledOnTabChanged()); 355 } 356 357 @UiThreadTest 358 public void testGetCurrentTabTag() { 359 TabHost tabHost = mActivity.getTabHost(); 360 assertEquals(TabHostStubActivity.INITIAL_TAB_TAG, tabHost.getCurrentTabTag()); 361 362 TabSpec tabSpec = tabHost.newTabSpec(TAG_TAB2); 363 tabSpec.setIndicator(TAG_TAB2); 364 tabSpec.setContent(new MyTabContentFactoryList()); 365 tabHost.addTab(tabSpec); 366 tabHost.setCurrentTab(1); 367 assertEquals(TAG_TAB2, tabHost.getCurrentTabTag()); 368 } 369 370 @UiThreadTest 371 public void testOnAttachedToAndDetachedFromWindow() { 372 // implementation details 373 } 374 375 private class MyTabContentFactoryText implements TabHost.TabContentFactory { 376 public View createTabContent(String tag) { 377 final TextView tv = new TextView(mActivity); 378 tv.setText(tag); 379 return tv; 380 } 381 } 382 383 private class MyTabContentFactoryList implements TabHost.TabContentFactory { 384 public View createTabContent(String tag) { 385 final ListView lv = new ListView(mActivity); 386 return lv; 387 } 388 } 389 390 private class MockOnTabChangeListener implements OnTabChangeListener { 391 private boolean mCalledOnTabChanged = false; 392 393 boolean hasCalledOnTabChanged() { 394 return mCalledOnTabChanged; 395 } 396 397 void reset() { 398 mCalledOnTabChanged = false; 399 } 400 401 public void onTabChanged(String tabId) { 402 mCalledOnTabChanged = true; 403 } 404 } 405 406 } 407