1 package com.xtremelabs.robolectric.shadows; 2 3 import android.app.Application; 4 import android.view.View; 5 import android.view.ViewGroup; 6 import android.view.animation.Animation; 7 import android.view.animation.Animation.AnimationListener; 8 import android.widget.FrameLayout; 9 import android.widget.LinearLayout; 10 import com.xtremelabs.robolectric.R; 11 import com.xtremelabs.robolectric.Robolectric; 12 import com.xtremelabs.robolectric.WithTestDefaultsRunner; 13 import com.xtremelabs.robolectric.res.ResourceLoader; 14 import org.junit.After; 15 import org.junit.Before; 16 import org.junit.Test; 17 import org.junit.runner.RunWith; 18 19 import java.io.ByteArrayOutputStream; 20 import java.io.PrintStream; 21 22 import static com.xtremelabs.robolectric.Robolectric.shadowOf; 23 import static org.hamcrest.CoreMatchers.equalTo; 24 import static org.hamcrest.CoreMatchers.sameInstance; 25 import static org.hamcrest.MatcherAssert.assertThat; 26 import static org.hamcrest.core.IsNull.nullValue; 27 import static org.junit.Assert.*; 28 29 @RunWith(WithTestDefaultsRunner.class) 30 public class ViewGroupTest { 31 private String defaultLineSeparator; 32 private ViewGroup root; 33 private View child1; 34 private View child2; 35 private ViewGroup child3; 36 private View child3a; 37 private View child3b; 38 private Application context; 39 40 @Before setUp()41 public void setUp() throws Exception { 42 context = new Application(); 43 ShadowApplication.bind(context, new ResourceLoader(10, R.class, null, null)); 44 45 root = new FrameLayout(context); 46 47 child1 = new View(context); 48 child2 = new View(context); 49 child3 = new FrameLayout(context); 50 child3a = new View(context); 51 child3b = new View(context); 52 53 root.addView(child1); 54 root.addView(child2); 55 root.addView(child3); 56 57 child3.addView(child3a); 58 child3.addView(child3b); 59 60 defaultLineSeparator = System.getProperty("line.separator"); 61 System.setProperty("line.separator", "\n"); 62 } 63 64 @After tearDown()65 public void tearDown() throws Exception { 66 System.setProperty("line.separator", defaultLineSeparator); 67 } 68 69 @Test testLayoutAnimationListener()70 public void testLayoutAnimationListener() { 71 assertThat(root.getLayoutAnimationListener(), nullValue()); 72 73 AnimationListener animationListener = new AnimationListener() { 74 @Override 75 public void onAnimationEnd(Animation a) { } 76 77 @Override 78 public void onAnimationRepeat(Animation a) { } 79 80 @Override 81 public void onAnimationStart(Animation a) { } 82 }; 83 root.setLayoutAnimationListener(animationListener); 84 85 assertThat(root.getLayoutAnimationListener(), sameInstance(animationListener)); 86 } 87 88 @Test testRemoveChildAt()89 public void testRemoveChildAt() throws Exception { 90 root.removeViewAt(1); 91 92 assertThat(root.getChildCount(), equalTo(2)); 93 assertThat(root.getChildAt(0), sameInstance(child1)); 94 assertThat(root.getChildAt(1), sameInstance((View) child3)); 95 96 assertThat(child2.getParent(), nullValue()); 97 } 98 99 @Test testAddViewAt()100 public void testAddViewAt() throws Exception { 101 root.removeAllViews(); 102 root.addView(child1); 103 root.addView(child2); 104 root.addView(child3, 1); 105 assertThat(root.getChildAt(0), sameInstance(child1)); 106 assertThat(root.getChildAt(1), sameInstance((View) child3)); 107 assertThat(root.getChildAt(2), sameInstance(child2)); 108 } 109 110 @Test shouldfindViewWithTag()111 public void shouldfindViewWithTag() { 112 root.removeAllViews(); 113 child1.setTag("tag1"); 114 child2.setTag("tag2"); 115 child3.setTag("tag3"); 116 root.addView(child1); 117 root.addView(child2); 118 root.addView(child3, 1); 119 assertThat(root.findViewWithTag("tag1"), sameInstance(child1)); 120 assertThat(root.findViewWithTag("tag2"), sameInstance(child2)); 121 assertThat((ViewGroup) root.findViewWithTag("tag3"), sameInstance(child3)); 122 } 123 124 @Test shouldNotfindViewWithTagReturnNull()125 public void shouldNotfindViewWithTagReturnNull() { 126 root.removeAllViews(); 127 child1.setTag("tag1"); 128 child2.setTag("tag2"); 129 child3.setTag("tag3"); 130 root.addView(child1); 131 root.addView(child2); 132 root.addView(child3, 1); 133 assertThat(root.findViewWithTag("tag21"), equalTo(null)); 134 assertThat((ViewGroup) root.findViewWithTag("tag23"), equalTo(null)); 135 } 136 137 @Test shouldfindViewWithTagFromCorrectViewGroup()138 public void shouldfindViewWithTagFromCorrectViewGroup() { 139 root.removeAllViews(); 140 child1.setTag("tag1"); 141 child2.setTag("tag2"); 142 child3.setTag("tag3"); 143 root.addView(child1); 144 root.addView(child2); 145 root.addView(child3); 146 147 child3a.setTag("tag1"); 148 child3b.setTag("tag2"); 149 150 //can find views by tag from root 151 assertThat(root.findViewWithTag("tag1"), sameInstance(child1)); 152 assertThat(root.findViewWithTag("tag2"), sameInstance(child2)); 153 assertThat((ViewGroup) root.findViewWithTag("tag3"), sameInstance(child3)); 154 155 //can find views by tag from child3 156 assertThat(child3.findViewWithTag("tag1"), sameInstance(child3a)); 157 assertThat(child3.findViewWithTag("tag2"), sameInstance(child3b)); 158 } 159 160 @Test shouldFindViewWithTag_whenViewGroupOverridesGetTag()161 public void shouldFindViewWithTag_whenViewGroupOverridesGetTag() throws Exception { 162 ViewGroup viewGroup = new LinearLayout(Robolectric.application) { 163 @Override 164 public Object getTag() { 165 return "blarg"; 166 } 167 }; 168 assertThat((ViewGroup) viewGroup.findViewWithTag("blarg"), sameInstance(viewGroup)); 169 } 170 171 @Test hasFocus_shouldReturnTrueIfAnyChildHasFocus()172 public void hasFocus_shouldReturnTrueIfAnyChildHasFocus() throws Exception { 173 assertFalse(root.hasFocus()); 174 175 child1.requestFocus(); 176 assertTrue(root.hasFocus()); 177 178 child1.clearFocus(); 179 assertFalse(root.hasFocus()); 180 181 child3b.requestFocus(); 182 assertTrue(root.hasFocus()); 183 184 child3b.clearFocus(); 185 assertFalse(root.hasFocus()); 186 187 root.requestFocus(); 188 assertTrue(root.hasFocus()); 189 } 190 191 @Test clearFocus_shouldRecursivelyClearTheFocusOfAllChildren()192 public void clearFocus_shouldRecursivelyClearTheFocusOfAllChildren() throws Exception { 193 child3a.requestFocus(); 194 195 root.clearFocus(); 196 197 assertFalse(child3a.hasFocus()); 198 assertFalse(child3.hasFocus()); 199 assertFalse(root.hasFocus()); 200 201 root.requestFocus(); 202 root.clearFocus(); 203 assertFalse(root.hasFocus()); 204 } 205 206 @Test findFocus_shouldRecursivelyFindTheViewWithFocus()207 public void findFocus_shouldRecursivelyFindTheViewWithFocus() { 208 child3a.requestFocus(); 209 210 assertSame(child3a, root.findFocus()); 211 } 212 213 @Test findFocus_shouldReturnThisBeforeChildrenWithFocus()214 public void findFocus_shouldReturnThisBeforeChildrenWithFocus() { 215 child3a.requestFocus(); 216 child3.requestFocus(); 217 218 assertSame(child3, root.findFocus()); 219 } 220 221 @Test dump_shouldDumpStructure()222 public void dump_shouldDumpStructure() throws Exception { 223 child3.setId(R.id.snippet_text); 224 225 ByteArrayOutputStream out = new ByteArrayOutputStream(); 226 shadowOf(root).dump(new PrintStream(out), 0); 227 assertEquals("<FrameLayout>\n" + 228 " <View/>\n" + 229 " <View/>\n" + 230 " <FrameLayout id=\"id/snippet_text\">\n" + 231 " <View/>\n" + 232 " <View/>\n" + 233 " </FrameLayout>\n" + 234 "</FrameLayout>\n", out.toString()); 235 } 236 237 @Test testRemoveView()238 public void testRemoveView() { 239 root.removeView(new View(context)); 240 assertThat(root.getChildCount(), equalTo(3)); 241 242 root.removeView(child2); 243 assertThat(root.getChildCount(), equalTo(2)); 244 assertThat(root.getChildAt(0), sameInstance(child1)); 245 assertThat(root.getChildAt(1), sameInstance((View) child3)); 246 247 root.removeView(child2); 248 assertThat(root.getChildCount(), equalTo(2)); 249 assertThat(root.getChildAt(0), sameInstance(child1)); 250 assertThat(root.getChildAt(1), sameInstance((View) child3)); 251 252 root.removeView(child1); 253 root.removeView(child3); 254 assertThat(root.getChildCount(), equalTo(0)); 255 } 256 257 @Test testRemoveViewInLayout()258 public void testRemoveViewInLayout() { 259 root.removeViewInLayout(new View(context)); 260 assertThat(root.getChildCount(), equalTo(3)); 261 262 root.removeViewInLayout(child2); 263 assertThat(root.getChildCount(), equalTo(2)); 264 assertThat(root.getChildAt(0), sameInstance(child1)); 265 assertThat(root.getChildAt(1), sameInstance((View) child3)); 266 267 root.removeViewInLayout(child2); 268 assertThat(root.getChildCount(), equalTo(2)); 269 assertThat(root.getChildAt(0), sameInstance(child1)); 270 assertThat(root.getChildAt(1), sameInstance((View) child3)); 271 272 root.removeViewInLayout(child1); 273 root.removeViewInLayout(child3); 274 assertThat(root.getChildCount(), equalTo(0)); 275 } 276 277 @Test testRemoveViews()278 public void testRemoveViews() { 279 root.removeViews(0, 0); 280 assertThat(root.getChildCount(), equalTo(3)); 281 282 root.removeViews(2, 1); 283 assertThat(root.getChildCount(), equalTo(2)); 284 assertThat(root.getChildAt(0), sameInstance(child1)); 285 assertThat(root.getChildAt(1), sameInstance(child2)); 286 287 root.removeViews(0, 1); 288 assertThat(root.getChildCount(), equalTo(1)); 289 assertThat(root.getChildAt(0), sameInstance(child2)); 290 291 root.removeViews(0, 1); 292 assertThat(root.getChildCount(), equalTo(0)); 293 294 root.addView(child1); 295 root.addView(child2); 296 root.addView(child3); 297 298 root.removeViews(1, 1); 299 assertThat(root.getChildCount(), equalTo(2)); 300 assertThat(root.getChildAt(0), sameInstance(child1)); 301 assertThat(root.getChildAt(1), sameInstance((View) child3)); 302 303 root.removeViews(0, 2); 304 assertThat(root.getChildCount(), equalTo(0)); 305 } 306 307 @Test testRemoveViewsInLayout()308 public void testRemoveViewsInLayout() { 309 root.removeViewsInLayout(0, 0); 310 assertThat(root.getChildCount(), equalTo(3)); 311 312 root.removeViewsInLayout(2, 1); 313 assertThat(root.getChildCount(), equalTo(2)); 314 assertThat(root.getChildAt(0), sameInstance(child1)); 315 assertThat(root.getChildAt(1), sameInstance(child2)); 316 317 root.removeViewsInLayout(0, 1); 318 assertThat(root.getChildCount(), equalTo(1)); 319 assertThat(root.getChildAt(0), sameInstance(child2)); 320 321 root.removeViewsInLayout(0, 1); 322 assertThat(root.getChildCount(), equalTo(0)); 323 324 root.addView(child1); 325 root.addView(child2); 326 root.addView(child3); 327 328 root.removeViewsInLayout(1, 1); 329 assertThat(root.getChildCount(), equalTo(2)); 330 assertThat(root.getChildAt(0), sameInstance(child1)); 331 assertThat(root.getChildAt(1), sameInstance((View) child3)); 332 333 root.removeViewsInLayout(0, 2); 334 assertThat(root.getChildCount(), equalTo(0)); 335 } 336 } 337