ViewTest.java revision 7cd4fd403867d4e7e6ee944a07ad6fb6c537f3ec
1package com.xtremelabs.robolectric.shadows; 2 3import android.app.Activity; 4import android.content.Context; 5import android.graphics.Point; 6import android.graphics.drawable.ColorDrawable; 7import android.view.MotionEvent; 8import android.view.View; 9import android.view.ViewGroup; 10import android.view.ViewTreeObserver; 11import android.view.animation.Animation; 12import android.widget.LinearLayout; 13import com.xtremelabs.robolectric.R; 14import com.xtremelabs.robolectric.Robolectric; 15import com.xtremelabs.robolectric.WithTestDefaultsRunner; 16import com.xtremelabs.robolectric.util.TestAnimationListener; 17import com.xtremelabs.robolectric.util.TestOnClickListener; 18import com.xtremelabs.robolectric.util.TestOnLongClickListener; 19import com.xtremelabs.robolectric.util.TestRunnable; 20import com.xtremelabs.robolectric.util.Transcript; 21import org.junit.Before; 22import org.junit.Test; 23import org.junit.runner.RunWith; 24 25import static com.xtremelabs.robolectric.Robolectric.shadowOf; 26import static junit.framework.Assert.assertEquals; 27import static org.hamcrest.CoreMatchers.*; 28import static org.junit.Assert.assertFalse; 29import static org.junit.Assert.assertNotSame; 30import static org.junit.Assert.assertThat; 31import static org.junit.Assert.assertTrue; 32 33@RunWith(WithTestDefaultsRunner.class) 34public class ViewTest { 35 private View view; 36 37 @Before 38 public void setUp() throws Exception { 39 view = new View(new Activity()); 40 } 41 42 @Test 43 public void testHasEmptyLayoutParams() throws Exception { 44 ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); 45 assertThat(layoutParams, notNullValue()); 46 } 47 48 @Test 49 public void layout_shouldAffectWidthAndHeight() throws Exception { 50 assertThat(view.getWidth(), equalTo(0)); 51 assertThat(view.getHeight(), equalTo(0)); 52 53 view.layout(100, 200, 303, 404); 54 assertThat(view.getWidth(), equalTo(303 - 100)); 55 assertThat(view.getHeight(), equalTo(404 - 200)); 56 } 57 58 @Test 59 public void shouldFocus() throws Exception { 60 final Transcript transcript = new Transcript(); 61 62 view.setOnFocusChangeListener(new View.OnFocusChangeListener() { 63 @Override 64 public void onFocusChange(View v, boolean hasFocus) { 65 transcript.add(hasFocus ? "Gained focus" : "Lost focus"); 66 } 67 }); 68 69 assertFalse(view.isFocused()); 70 assertFalse(view.hasFocus()); 71 transcript.assertNoEventsSoFar(); 72 73 view.requestFocus(); 74 assertTrue(view.isFocused()); 75 assertTrue(view.hasFocus()); 76 transcript.assertEventsSoFar("Gained focus"); 77 78 view.clearFocus(); 79 assertFalse(view.isFocused()); 80 assertFalse(view.hasFocus()); 81 transcript.assertEventsSoFar("Lost focus"); 82 } 83 84 @Test 85 public void shouldNotBeFocusableByDefault() throws Exception { 86 assertFalse(view.isFocusable()); 87 88 view.setFocusable(true); 89 assertTrue(view.isFocusable()); 90 } 91 92 @Test 93 public void shouldKnowIfThisOrAncestorsAreVisible() throws Exception { 94 assertTrue(shadowOf(view).derivedIsVisible()); 95 96 ViewGroup grandParent = new LinearLayout(null); 97 ViewGroup parent = new LinearLayout(null); 98 grandParent.addView(parent); 99 parent.addView(view); 100 101 grandParent.setVisibility(View.GONE); 102 103 assertFalse(shadowOf(view).derivedIsVisible()); 104 } 105 106 @Test 107 public void shouldInflateMergeRootedLayoutAndNotCreateReferentialLoops() throws Exception { 108 LinearLayout root = new LinearLayout(null); 109 root.inflate(new Activity(), R.layout.inner_merge, root); 110 for (int i = 0; i < root.getChildCount(); i++) { 111 View child = root.getChildAt(i); 112 assertNotSame(root, child); 113 } 114 } 115 116 @Test 117 public void performLongClick_shouldClickOnView() throws Exception { 118 TestOnLongClickListener clickListener = new TestOnLongClickListener(); 119 view.setOnLongClickListener(clickListener); 120 shadowOf(view).performLongClick(); 121 122 assertTrue(clickListener.clicked); 123 } 124 125 126 @Test 127 public void checkedClick_shouldClickOnView() throws Exception { 128 TestOnClickListener clickListener = new TestOnClickListener(); 129 view.setOnClickListener(clickListener); 130 shadowOf(view).checkedPerformClick(); 131 132 assertTrue(clickListener.clicked); 133 } 134 135 @Test(expected = RuntimeException.class) 136 public void checkedClick_shouldThrowIfViewIsNotVisible() throws Exception { 137 ViewGroup grandParent = new LinearLayout(null); 138 ViewGroup parent = new LinearLayout(null); 139 grandParent.addView(parent); 140 parent.addView(view); 141 grandParent.setVisibility(View.GONE); 142 143 shadowOf(view).checkedPerformClick(); 144 } 145 146 @Test(expected = RuntimeException.class) 147 public void checkedClick_shouldThrowIfViewIsDisabled() throws Exception { 148 view.setEnabled(false); 149 shadowOf(view).checkedPerformClick(); 150 } 151 152 @Test 153 public void getBackground_shouldReturnNullIfNoBackgroundHasBeenSet() throws Exception { 154 assertThat(view.getBackground(), nullValue()); 155 } 156 157 @Test 158 public void shouldSetBackgroundColor() { 159 view.setBackgroundColor(R.color.android_red); 160 int intColor = view.getResources().getColor(R.color.android_red); 161 162 assertThat((ColorDrawable) view.getBackground(), equalTo(new ColorDrawable(intColor))); 163 } 164 165 @Test 166 public void shouldSetBackgroundResource() throws Exception { 167 view.setBackgroundResource(R.drawable.an_image); 168 assertThat(view.getBackground(), equalTo(view.getResources().getDrawable(R.drawable.an_image))); 169 } 170 171 @Test 172 public void shouldRecordBackgroundColor() { 173 int[] colors = {0, 1, 727}; 174 175 for (int color : colors) { 176 view.setBackgroundColor(color); 177 assertThat(shadowOf(view).getBackgroundColor(), equalTo(color)); 178 } 179 } 180 181 @Test 182 public void shouldPostActionsToTheMessageQueue() throws Exception { 183 Robolectric.pauseMainLooper(); 184 185 TestRunnable runnable = new TestRunnable(); 186 view.post(runnable); 187 assertFalse(runnable.wasRun); 188 189 Robolectric.unPauseMainLooper(); 190 assertTrue(runnable.wasRun); 191 } 192 193 @Test 194 public void shouldPostInvalidateDelayed() throws Exception { 195 Robolectric.pauseMainLooper(); 196 197 view.postInvalidateDelayed(100); 198 ShadowView shadowView = shadowOf(view); 199 assertFalse(shadowView.wasInvalidated()); 200 201 Robolectric.unPauseMainLooper(); 202 assertTrue(shadowView.wasInvalidated()); 203 } 204 205 @Test 206 public void shouldPostActionsToTheMessageQueueWithDelay() throws Exception { 207 Robolectric.pauseMainLooper(); 208 209 TestRunnable runnable = new TestRunnable(); 210 view.postDelayed(runnable, 1); 211 assertFalse(runnable.wasRun); 212 213 Robolectric.getUiThreadScheduler().advanceBy(1); 214 assertTrue(runnable.wasRun); 215 } 216 217 @Test 218 public void shouldSupportAllConstructors() throws Exception { 219 new View(null); 220 new View(null, null); 221 new View(null, null, 0); 222 } 223 224 @Test 225 public void shouldSetAnimation() throws Exception { 226 Animation anim = new TestAnimation(); 227 view.setAnimation(anim); 228 assertThat(view.getAnimation(), sameInstance(anim)); 229 } 230 231 @Test 232 public void shouldStartAndClearAnimation() throws Exception { 233 Animation anim = new TestAnimation(); 234 TestAnimationListener listener = new TestAnimationListener(); 235 anim.setAnimationListener(listener); 236 assertThat(listener.wasStartCalled, equalTo(false)); 237 assertThat(listener.wasRepeatCalled, equalTo(false)); 238 assertThat(listener.wasEndCalled, equalTo(false)); 239 view.startAnimation(anim); 240 assertThat(listener.wasStartCalled, equalTo(true)); 241 assertThat(listener.wasRepeatCalled, equalTo(false)); 242 assertThat(listener.wasEndCalled, equalTo(false)); 243 view.clearAnimation(); 244 assertThat(listener.wasStartCalled, equalTo(true)); 245 assertThat(listener.wasRepeatCalled, equalTo(false)); 246 assertThat(listener.wasEndCalled, equalTo(true)); 247 } 248 249 @Test 250 public void shouldfindViewWithTag() { 251 String tagged = "tagged"; 252 String tagged2 = "tagged"; 253 view.setTag(tagged); 254 assertThat(view.findViewWithTag(tagged2),sameInstance(view)); 255 } 256 257 @Test 258 public void scrollTo_shouldStoreTheScrolledCoordinates() throws Exception { 259 view.scrollTo(1, 2); 260 assertThat(shadowOf(view).scrollToCoordinates, equalTo(new Point(1, 2))); 261 } 262 263 @Test 264 public void shouldScrollTo() throws Exception { 265 view.scrollTo(7, 6); 266 267 assertEquals(7, view.getScrollX()); 268 assertEquals(6, view.getScrollY()); 269 } 270 271 @Test 272 public void shouldGetScrollXAndY() { 273 assertEquals(0, view.getScrollX()); 274 assertEquals(0, view.getScrollY()); 275 } 276 277 @Test 278 public void getViewTreeObserver_shouldReturnTheSameObserverFromMultipleCalls() throws Exception { 279 ViewTreeObserver observer = view.getViewTreeObserver(); 280 assertThat(observer, instanceOf(ViewTreeObserver.class)); 281 assertThat(view.getViewTreeObserver(), sameInstance(observer)); 282 } 283 284 @Test 285 public void dispatchTouchEvent_sendsMotionEventToOnTouchEvent() throws Exception { 286 TouchableView touchableView = new TouchableView(null); 287 MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 12f, 34f, 0); 288 touchableView.dispatchTouchEvent(event); 289 assertThat(touchableView.event, sameInstance(event)); 290 view.dispatchTouchEvent(event); 291 assertThat(shadowOf(view).getLastTouchEvent(), sameInstance(event)); 292 } 293 294 @Test 295 public void dispatchTouchEvent_listensToTrueFromListener() throws Exception { 296 view.setOnTouchListener(new View.OnTouchListener() { 297 @Override 298 public boolean onTouch(View view, MotionEvent motionEvent) { 299 return true; 300 } 301 }); 302 MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 12f, 34f, 0); 303 view.dispatchTouchEvent(event); 304 assertThat(shadowOf(view).getLastTouchEvent(), nullValue()); 305 } 306 307 @Test 308 public void dispatchTouchEvent_listensToFalseFromListener() throws Exception { 309 view.setOnTouchListener(new View.OnTouchListener() { 310 @Override 311 public boolean onTouch(View view, MotionEvent motionEvent) { 312 return false; 313 } 314 }); 315 MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 12f, 34f, 0); 316 view.dispatchTouchEvent(event); 317 assertThat(shadowOf(view).getLastTouchEvent(), sameInstance(event)); 318 } 319 320 @Test 321 public void test_nextFocusDownId() throws Exception { 322 assertEquals(View.NO_ID, view.getNextFocusDownId()); 323 324 view.setNextFocusDownId(R.id.icon); 325 assertEquals(R.id.icon, view.getNextFocusDownId()); 326 } 327 328 private static class TestAnimation extends Animation { 329 } 330 331 private static class TouchableView extends View { 332 MotionEvent event; 333 334 public TouchableView(Context context) { 335 super(context); 336 } 337 338 @Override 339 public boolean onTouchEvent(MotionEvent event) { 340 this.event = event; 341 return false; 342 } 343 } 344} 345