Home | History | Annotate | Download | only in shadows
      1 package com.xtremelabs.robolectric.shadows;
      2 
      3 import android.os.Looper;
      4 import android.view.View;
      5 import android.view.ViewGroup;
      6 import android.widget.AdapterView;
      7 import android.widget.TextView;
      8 import com.xtremelabs.robolectric.Robolectric;
      9 import com.xtremelabs.robolectric.util.Transcript;
     10 
     11 import static com.xtremelabs.robolectric.Robolectric.*;
     12 import static com.xtremelabs.robolectric.matchers.TextViewHasTextMatcher.hasText;
     13 import static org.hamcrest.CoreMatchers.equalTo;
     14 import static org.hamcrest.CoreMatchers.is;
     15 import static org.hamcrest.CoreMatchers.not;
     16 import static org.hamcrest.CoreMatchers.nullValue;
     17 import static org.hamcrest.CoreMatchers.sameInstance;
     18 import static org.hamcrest.core.CombinableMatcher.both;
     19 import static org.junit.Assert.assertThat;
     20 
     21 public class AdapterViewBehavior {
     22     public static void shouldActAsAdapterView(AdapterView adapterView) throws Exception {
     23         Robolectric.shadowOf(Looper.getMainLooper()).pause();
     24 
     25         testSetAdapter_ShouldCauseViewsToBeRenderedAsynchronously(adapterView);
     26         testSetAdapter_ShouldSelectFirstItemAsynchronously(adapterView);
     27         testSetAdapter_ShouldFireOnNothingSelectedWhenAdapterCountIsReducedToZero(adapterView);
     28 
     29         shouldIgnoreSetSelectionCallsWithInvalidPosition(adapterView);
     30         shouldOnlyUpdateOnceIfInvalidatedMultipleTimes(adapterView);
     31 
     32         testSetEmptyView_ShouldHideAdapterViewIfAdapterIsNull(adapterView);
     33         testSetEmptyView_ShouldHideAdapterViewIfAdapterViewIsEmpty(adapterView);
     34         testSetEmptyView_ShouldHideEmptyViewIfAdapterViewIsNotEmpty(adapterView);
     35         testSetEmptyView_ShouldHideEmptyViewWhenAdapterGetsNewItem(adapterView);
     36     }
     37 
     38     private static void shouldIgnoreSetSelectionCallsWithInvalidPosition(AdapterView adapterView) {
     39         final Transcript transcript = new Transcript();
     40 
     41         adapterView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
     42             @Override
     43             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
     44                 transcript.add("onItemSelected fired");
     45             }
     46 
     47             @Override
     48             public void onNothingSelected(AdapterView<?> parent) {
     49             }
     50         });
     51 
     52         ShadowHandler.idleMainLooper();
     53         transcript.assertNoEventsSoFar();
     54         adapterView.setSelection(AdapterView.INVALID_POSITION);
     55         ShadowHandler.idleMainLooper();
     56         transcript.assertNoEventsSoFar();
     57     }
     58 
     59     private static void testSetAdapter_ShouldCauseViewsToBeRenderedAsynchronously(AdapterView adapterView) throws Exception {
     60         adapterView.setAdapter(new CountingAdapter(2));
     61 
     62         assertThat(adapterView.getCount(), equalTo(2));
     63         assertThat(adapterView.getChildCount(), equalTo(0));
     64 
     65         ShadowHandler.idleMainLooper();
     66         assertThat(adapterView.getChildCount(), equalTo(2));
     67         assertThat((TextView) adapterView.getChildAt(0), hasText("Item 0"));
     68         assertThat((TextView) adapterView.getChildAt(1), hasText("Item 1"));
     69     }
     70 
     71     private static void testSetAdapter_ShouldSelectFirstItemAsynchronously(final AdapterView adapterView) throws Exception {
     72         final Transcript transcript = new Transcript();
     73 
     74         adapterView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
     75             @Override
     76             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
     77                 assertThat(parent, sameInstance(adapterView));
     78                 assertThat(view, both(sameInstance(adapterView.getChildAt(position))).and(not(nullValue())));
     79                 assertThat(id, equalTo(adapterView.getAdapter().getItemId(position)));
     80                 transcript.add("selected item " + position);
     81             }
     82 
     83             @Override
     84             public void onNothingSelected(AdapterView<?> parent) {
     85             }
     86         });
     87         adapterView.setAdapter(new CountingAdapter(2));
     88         transcript.assertNoEventsSoFar();
     89         ShadowHandler.idleMainLooper();
     90         transcript.assertEventsSoFar("selected item 0");
     91     }
     92 
     93     private static void testSetAdapter_ShouldFireOnNothingSelectedWhenAdapterCountIsReducedToZero(final AdapterView adapterView) throws Exception {
     94         final Transcript transcript = new Transcript();
     95 
     96         adapterView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
     97             @Override
     98             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
     99             }
    100 
    101             @Override
    102             public void onNothingSelected(AdapterView<?> parent) {
    103                 transcript.add("onNothingSelected fired");
    104             }
    105         });
    106         CountingAdapter adapter = new CountingAdapter(2);
    107         adapterView.setAdapter(adapter);
    108         ShadowHandler.idleMainLooper();
    109         transcript.assertNoEventsSoFar();
    110         adapter.setCount(0);
    111         ShadowHandler.idleMainLooper();
    112         transcript.assertEventsSoFar("onNothingSelected fired");
    113     }
    114 
    115     private static void testSetEmptyView_ShouldHideAdapterViewIfAdapterIsNull(final AdapterView adapterView) throws Exception {
    116     	adapterView.setAdapter(null);
    117 
    118     	View emptyView = new View(adapterView.getContext());
    119 		adapterView.setEmptyView(emptyView);
    120 
    121 		assertThat(adapterView.getVisibility(), is(View.GONE));
    122 		assertThat(emptyView.getVisibility(), is(View.VISIBLE));
    123     }
    124 
    125     private static void testSetEmptyView_ShouldHideAdapterViewIfAdapterViewIsEmpty(final AdapterView adapterView) throws Exception {
    126     	adapterView.setAdapter(new CountingAdapter(0));
    127 
    128     	View emptyView = new View(adapterView.getContext());
    129 		adapterView.setEmptyView(emptyView);
    130 
    131 		assertThat(adapterView.getVisibility(), is(View.GONE));
    132 		assertThat(emptyView.getVisibility(), is(View.VISIBLE));
    133     }
    134 
    135     private static void testSetEmptyView_ShouldHideEmptyViewIfAdapterViewIsNotEmpty(final AdapterView adapterView) throws Exception {
    136     	adapterView.setAdapter(new CountingAdapter(1));
    137 
    138     	View emptyView = new View(adapterView.getContext());
    139 		adapterView.setEmptyView(emptyView);
    140 
    141 		assertThat(adapterView.getVisibility(), is(View.VISIBLE));
    142 		assertThat(emptyView.getVisibility(), is(View.GONE));
    143     }
    144 
    145     private static void testSetEmptyView_ShouldHideEmptyViewWhenAdapterGetsNewItem(final AdapterView adapterView) throws Exception {
    146     	CountingAdapter adapter = new CountingAdapter(0);
    147 		adapterView.setAdapter(adapter);
    148 
    149     	View emptyView = new View(adapterView.getContext());
    150 		adapterView.setEmptyView(emptyView);
    151 
    152 		assertThat(adapterView.getVisibility(), is(View.GONE));
    153 		assertThat(emptyView.getVisibility(), is(View.VISIBLE));
    154 
    155 		adapter.setCount(1);
    156 
    157 		ShadowHandler.idleMainLooper();
    158 
    159 		assertThat(adapterView.getVisibility(), is(View.VISIBLE));
    160 		assertThat(emptyView.getVisibility(), is(View.GONE));
    161     }
    162 
    163     private static void testSetEmptyView_ShouldHideAdapterViewWhenAdapterBecomesEmpty(final AdapterView adapterView) throws Exception {
    164     	CountingAdapter adapter = new CountingAdapter(1);
    165 		adapterView.setAdapter(adapter);
    166 
    167     	View emptyView = new View(adapterView.getContext());
    168 		adapterView.setEmptyView(emptyView);
    169 
    170 		assertThat(adapterView.getVisibility(), is(View.GONE));
    171 		assertThat(emptyView.getVisibility(), is(View.VISIBLE));
    172 
    173 		adapter.setCount(0);
    174 
    175 		ShadowHandler.idleMainLooper();
    176 
    177 		assertThat(adapterView.getVisibility(), is(View.VISIBLE));
    178 		assertThat(emptyView.getVisibility(), is(View.GONE));
    179     }
    180 
    181     private static void shouldOnlyUpdateOnceIfInvalidatedMultipleTimes(final AdapterView adapterView) {
    182         final Transcript transcript = new Transcript();
    183         CountingAdapter adapter = new CountingAdapter(2) {
    184             @Override
    185             public View getView(int position, View convertView, ViewGroup parent) {
    186                 transcript.add("getView for " + position);
    187                 return super.getView(position, convertView, parent);
    188             }
    189         };
    190         adapterView.setAdapter(adapter);
    191 
    192         transcript.assertNoEventsSoFar();
    193 
    194         adapter.notifyDataSetChanged();
    195         adapter.notifyDataSetChanged();
    196 
    197         ShadowHandler.idleMainLooper();
    198 
    199         transcript.assertEventsSoFar("getView for 0", "getView for 1");
    200     }
    201 }
    202