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 org.xmlpull.v1.XmlPullParser; 23 24 import android.content.Context; 25 import android.content.res.Resources; 26 import android.graphics.Canvas; 27 import android.graphics.Rect; 28 import android.graphics.drawable.Drawable; 29 import android.os.Parcelable; 30 import android.test.AndroidTestCase; 31 import android.util.AttributeSet; 32 import android.util.StateSet; 33 import android.util.Xml; 34 import android.view.Gravity; 35 import android.view.View; 36 import android.view.View.OnClickListener; 37 import android.widget.CompoundButton; 38 import android.widget.CompoundButton.OnCheckedChangeListener; 39 40 /** 41 * Test {@link CompoundButton}. 42 */ 43 public class CompoundButtonTest extends AndroidTestCase { 44 private Resources mResources; 45 46 @Override 47 protected void setUp() throws Exception { 48 super.setUp(); 49 mResources = mContext.getResources(); 50 } 51 52 public void testConstructor() { 53 XmlPullParser parser = mContext.getResources().getXml(R.layout.togglebutton_layout); 54 AttributeSet mAttrSet = Xml.asAttributeSet(parser); 55 56 new MockCompoundButton(mContext, mAttrSet, 0); 57 new MockCompoundButton(mContext, mAttrSet); 58 new MockCompoundButton(mContext); 59 60 try { 61 new MockCompoundButton(null, null, -1); 62 fail("Should throw NullPointerException."); 63 } catch (NullPointerException e) { 64 // expected, test success. 65 } 66 67 try { 68 new MockCompoundButton(null, null); 69 fail("Should throw NullPointerException."); 70 } catch (NullPointerException e) { 71 // expected, test success. 72 } 73 74 try { 75 new MockCompoundButton(null); 76 fail("Should throw NullPointerException."); 77 } catch (NullPointerException e) { 78 // expected, test success. 79 } 80 } 81 82 public void testAccessChecked() { 83 CompoundButton compoundButton = new MockCompoundButton(mContext); 84 MockOnCheckedChangeListener listener = new MockOnCheckedChangeListener(); 85 compoundButton.setOnCheckedChangeListener(listener); 86 assertFalse(compoundButton.isChecked()); 87 assertFalse(listener.hasCalledCheckedChange()); 88 89 compoundButton.setChecked(true); 90 assertTrue(compoundButton.isChecked()); 91 assertTrue(listener.hasCalledCheckedChange()); 92 assertSame(compoundButton, listener.getInputCompoundButton()); 93 assertTrue(listener.getInputChecked()); 94 95 listener.reset(); 96 compoundButton.setChecked(true); 97 assertTrue(compoundButton.isChecked()); 98 assertFalse(listener.hasCalledCheckedChange()); 99 100 compoundButton.setChecked(false); 101 assertFalse(compoundButton.isChecked()); 102 assertTrue(listener.hasCalledCheckedChange()); 103 assertSame(compoundButton, listener.getInputCompoundButton()); 104 assertFalse(listener.getInputChecked()); 105 } 106 107 public void testSetOnCheckedChangeListener() { 108 CompoundButton compoundButton = new MockCompoundButton(mContext); 109 MockOnCheckedChangeListener listener = new MockOnCheckedChangeListener(); 110 compoundButton.setOnCheckedChangeListener(listener); 111 assertFalse(compoundButton.isChecked()); 112 assertFalse(listener.hasCalledCheckedChange()); 113 114 compoundButton.setChecked(true); 115 assertTrue(listener.hasCalledCheckedChange()); 116 117 // set null 118 compoundButton.setOnCheckedChangeListener(null); 119 listener.reset(); 120 compoundButton.setChecked(false); 121 assertFalse(listener.hasCalledCheckedChange()); 122 } 123 124 public void testToggle() { 125 CompoundButton compoundButton = new MockCompoundButton(mContext); 126 assertFalse(compoundButton.isChecked()); 127 128 compoundButton.toggle(); 129 assertTrue(compoundButton.isChecked()); 130 131 compoundButton.toggle(); 132 assertFalse(compoundButton.isChecked()); 133 134 compoundButton.setChecked(true); 135 compoundButton.toggle(); 136 assertFalse(compoundButton.isChecked()); 137 } 138 139 public void testPerformClick() { 140 CompoundButton compoundButton = new MockCompoundButton(mContext); 141 assertFalse(compoundButton.isChecked()); 142 143 // performClick without OnClickListener will return false. 144 assertFalse(compoundButton.performClick()); 145 assertTrue(compoundButton.isChecked()); 146 147 assertFalse(compoundButton.performClick()); 148 assertFalse(compoundButton.isChecked()); 149 150 // performClick with OnClickListener will return true. 151 compoundButton.setOnClickListener(new OnClickListener() { 152 public void onClick(View v) { 153 } 154 }); 155 assertTrue(compoundButton.performClick()); 156 assertTrue(compoundButton.isChecked()); 157 158 assertTrue(compoundButton.performClick()); 159 assertFalse(compoundButton.isChecked()); 160 } 161 162 public void testDrawableStateChanged() { 163 MockCompoundButton compoundButton = new MockCompoundButton(mContext); 164 assertFalse(compoundButton.isChecked()); 165 // drawableStateChanged without any drawables. 166 compoundButton.drawableStateChanged(); 167 168 // drawableStateChanged when CheckMarkDrawable is not null. 169 Drawable drawable = mResources.getDrawable(R.drawable.scenery); 170 compoundButton.setButtonDrawable(drawable); 171 drawable.setState(null); 172 assertNull(drawable.getState()); 173 174 compoundButton.drawableStateChanged(); 175 assertNotNull(drawable.getState()); 176 assertSame(compoundButton.getDrawableState(), drawable.getState()); 177 } 178 179 public void testSetButtonDrawableByDrawable() { 180 CompoundButton compoundButton; 181 182 // set null drawable 183 compoundButton = new MockCompoundButton(mContext); 184 compoundButton.setButtonDrawable(null); 185 186 // set drawable when checkedTextView is GONE 187 compoundButton = new MockCompoundButton(mContext); 188 compoundButton.setVisibility(View.GONE); 189 Drawable firstDrawable = mResources.getDrawable(R.drawable.scenery); 190 firstDrawable.setVisible(true, false); 191 assertEquals(StateSet.WILD_CARD, firstDrawable.getState()); 192 193 compoundButton.setButtonDrawable(firstDrawable); 194 assertFalse(firstDrawable.isVisible()); 195 196 // update drawable when checkedTextView is VISIBLE 197 compoundButton.setVisibility(View.VISIBLE); 198 Drawable secondDrawable = mResources.getDrawable(R.drawable.pass); 199 secondDrawable.setVisible(true, false); 200 assertEquals(StateSet.WILD_CARD, secondDrawable.getState()); 201 202 compoundButton.setButtonDrawable(secondDrawable); 203 assertTrue(secondDrawable.isVisible()); 204 // the firstDrawable is not active. 205 assertFalse(firstDrawable.isVisible()); 206 } 207 208 public void testSetButtonDrawableById() { 209 CompoundButton compoundButton; 210 // resId is 0 211 compoundButton = new MockCompoundButton(mContext); 212 compoundButton.setButtonDrawable(0); 213 214 // set drawable 215 compoundButton = new MockCompoundButton(mContext); 216 compoundButton.setButtonDrawable(R.drawable.scenery); 217 218 // set the same drawable again 219 compoundButton.setButtonDrawable(R.drawable.scenery); 220 221 // update drawable 222 compoundButton.setButtonDrawable(R.drawable.pass); 223 } 224 225 public void testOnCreateDrawableState() { 226 MockCompoundButton compoundButton; 227 228 // compoundButton is not checked, append 0 to state array. 229 compoundButton = new MockCompoundButton(mContext); 230 int[] state = compoundButton.onCreateDrawableState(0); 231 assertEquals(0, state[state.length - 1]); 232 233 // compoundButton is checked, append R.attr.state_checked to state array. 234 compoundButton.setChecked(true); 235 int[] checkedState = compoundButton.onCreateDrawableState(0); 236 assertEquals(state[0], checkedState[0]); 237 assertEquals(com.android.internal.R.attr.state_checked, 238 checkedState[checkedState.length - 1]); 239 240 // compoundButton is not checked again. 241 compoundButton.setChecked(false); 242 state = compoundButton.onCreateDrawableState(0); 243 assertEquals(0, state[state.length - 1]); 244 } 245 246 public void testOnDraw() { 247 int viewHeight; 248 int drawableWidth; 249 int drawableHeight; 250 Rect bounds; 251 Drawable drawable; 252 Canvas canvas = new Canvas(android.graphics.Bitmap.createBitmap(100, 100, 253 android.graphics.Bitmap.Config.ARGB_8888)); 254 MockCompoundButton compoundButton; 255 256 // onDraw when there is no drawable 257 compoundButton = new MockCompoundButton(mContext); 258 compoundButton.onDraw(canvas); 259 260 // onDraw when Gravity.TOP, it's default. 261 compoundButton = new MockCompoundButton(mContext); 262 drawable = mResources.getDrawable(R.drawable.scenery); 263 compoundButton.setButtonDrawable(drawable); 264 viewHeight = compoundButton.getHeight(); 265 drawableWidth = drawable.getIntrinsicWidth(); 266 drawableHeight = drawable.getIntrinsicHeight(); 267 268 compoundButton.onDraw(canvas); 269 bounds = drawable.copyBounds(); 270 assertEquals(0, bounds.left); 271 assertEquals(drawableWidth, bounds.right); 272 assertEquals(0, bounds.top); 273 assertEquals(drawableHeight, bounds.bottom); 274 275 // onDraw when Gravity.BOTTOM 276 compoundButton.setGravity(Gravity.BOTTOM); 277 compoundButton.onDraw(canvas); 278 bounds = drawable.copyBounds(); 279 assertEquals(0, bounds.left); 280 assertEquals(drawableWidth, bounds.right); 281 assertEquals(viewHeight - drawableHeight, bounds.top); 282 assertEquals(viewHeight, bounds.bottom); 283 284 // onDraw when Gravity.CENTER_VERTICAL 285 compoundButton.setGravity(Gravity.CENTER_VERTICAL); 286 compoundButton.onDraw(canvas); 287 bounds = drawable.copyBounds(); 288 assertEquals(0, bounds.left); 289 assertEquals(drawableWidth, bounds.right); 290 assertEquals( (viewHeight - drawableHeight) / 2, bounds.top); 291 assertEquals( (viewHeight - drawableHeight) / 2 + drawableHeight, bounds.bottom); 292 } 293 294 public void testAccessInstanceState() { 295 CompoundButton compoundButton = new MockCompoundButton(mContext); 296 Parcelable state; 297 298 assertFalse(compoundButton.isChecked()); 299 assertFalse(compoundButton.getFreezesText()); 300 301 state = compoundButton.onSaveInstanceState(); 302 assertNotNull(state); 303 assertTrue(compoundButton.getFreezesText()); 304 305 compoundButton.setChecked(true); 306 307 compoundButton.onRestoreInstanceState(state); 308 assertFalse(compoundButton.isChecked()); 309 assertTrue(compoundButton.isLayoutRequested()); 310 } 311 312 public void testVerifyDrawable() { 313 MockCompoundButton compoundButton = new MockCompoundButton(mContext); 314 Drawable drawable = mContext.getResources().getDrawable(R.drawable.scenery); 315 316 assertTrue(compoundButton.verifyDrawable(null)); 317 assertFalse(compoundButton.verifyDrawable(drawable)); 318 319 compoundButton.setButtonDrawable(drawable); 320 assertTrue(compoundButton.verifyDrawable(null)); 321 assertTrue(compoundButton.verifyDrawable(drawable)); 322 } 323 324 private final class MockCompoundButton extends CompoundButton { 325 public MockCompoundButton(Context context) { 326 super(context); 327 } 328 329 public MockCompoundButton(Context context, AttributeSet attrs) { 330 super(context, attrs, 0); 331 } 332 333 public MockCompoundButton(Context context, AttributeSet attrs, int defStyle) { 334 super(context, attrs, defStyle); 335 } 336 337 @Override 338 protected void drawableStateChanged() { 339 super.drawableStateChanged(); 340 } 341 342 @Override 343 protected void onDraw(Canvas canvas) { 344 super.onDraw(canvas); 345 } 346 347 @Override 348 protected int[] onCreateDrawableState(int extraSpace) { 349 return super.onCreateDrawableState(extraSpace); 350 } 351 352 @Override 353 protected boolean verifyDrawable(Drawable who) { 354 return super.verifyDrawable(who); 355 } 356 } 357 358 private final class MockOnCheckedChangeListener implements OnCheckedChangeListener { 359 private boolean mHasCalledChecked; 360 private CompoundButton mCompoundButton; 361 private boolean mIsChecked; 362 363 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 364 mHasCalledChecked = true; 365 mCompoundButton = buttonView; 366 mIsChecked = isChecked; 367 } 368 369 public boolean getInputChecked() { 370 return mIsChecked; 371 } 372 373 public CompoundButton getInputCompoundButton() { 374 return mCompoundButton; 375 } 376 377 public boolean hasCalledCheckedChange() { 378 return mHasCalledChecked; 379 } 380 381 public void reset() { 382 mHasCalledChecked = false; 383 mCompoundButton = null; 384 mIsChecked = false; 385 } 386 } 387 } 388