Home | History | Annotate | Download | only in shadows
      1 package com.xtremelabs.robolectric.shadows;
      2 
      3 import android.os.Bundle;
      4 import android.os.Handler;
      5 import android.os.Looper;
      6 import android.support.v4.app.Fragment;
      7 import android.support.v4.app.FragmentActivity;
      8 import android.support.v4.app.FragmentTransaction;
      9 import android.view.LayoutInflater;
     10 import android.view.View;
     11 import android.view.ViewGroup;
     12 import android.widget.Button;
     13 import android.widget.FrameLayout;
     14 import com.xtremelabs.robolectric.Robolectric;
     15 import com.xtremelabs.robolectric.WithTestDefaultsRunner;
     16 import com.xtremelabs.robolectric.tester.android.util.TestFragmentManager;
     17 import com.xtremelabs.robolectric.util.Scheduler;
     18 import com.xtremelabs.robolectric.util.TestRunnable;
     19 import org.junit.Before;
     20 import org.junit.Test;
     21 import org.junit.runner.RunWith;
     22 
     23 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
     24 import static org.hamcrest.CoreMatchers.equalTo;
     25 import static org.hamcrest.CoreMatchers.sameInstance;
     26 import static org.hamcrest.MatcherAssert.assertThat;
     27 import static org.junit.Assert.*;
     28 
     29 @RunWith(WithTestDefaultsRunner.class)
     30 public class FragmentManagerTest {
     31 
     32     public static final int CONTAINER_VIEW_ID = 888;
     33     private TestFragmentManager manager;
     34     private TestFragment fragment;
     35     private TestFragmentActivity activity;
     36     private ViewGroup containerView;
     37 
     38     @Before
     39     public void setUp() throws Exception {
     40         activity = new TestFragmentActivity();
     41         activity.onCreate(null);
     42         manager = (TestFragmentManager) activity.getSupportFragmentManager();
     43         fragment = new TestFragment();
     44         containerView = (ViewGroup) activity.findViewById(CONTAINER_VIEW_ID);
     45     }
     46 
     47     @Test
     48     public void shouldFindFragmentById() throws Exception {
     49         manager.addFragment(CONTAINER_VIEW_ID, "tag1", fragment, false);
     50 
     51         assertThat(manager.findFragmentById(CONTAINER_VIEW_ID), sameInstance((Fragment) fragment));
     52     }
     53 
     54     @Test
     55     public void shouldFindFragmentByTag() throws Exception {
     56         manager.addFragment(CONTAINER_VIEW_ID, "tag1", fragment, false);
     57 
     58         assertThat(manager.findFragmentByTag("tag1"), sameInstance((Fragment) fragment));
     59     }
     60 
     61     @Test
     62     public void addFragment_shouldCallLifecycleMethods() throws Exception {
     63         manager.addFragment(View.NO_ID, null, fragment, false);
     64 
     65         fragment.transcript.assertEventsSoFar(
     66                 "onAttach",
     67                 "onCreate"
     68         );
     69 
     70         assertSame(activity, fragment.onAttachActivity);
     71         assertSame(activity, fragment.getActivity());
     72     }
     73 
     74     @Test
     75     public void startFragment_shouldCallLifecycleMethods() throws Exception {
     76         manager.addFragment(View.NO_ID, null, fragment, false);
     77         fragment.transcript.clear();
     78         manager.startFragment(fragment);
     79 
     80         fragment.transcript.assertEventsSoFar(
     81                 "onCreateView",
     82                 "onViewCreated",
     83                 "onActivityCreated",
     84                 "onStart"
     85         );
     86 
     87         assertEquals(fragment.onCreateViewInflater, activity.getLayoutInflater());
     88         assertNotNull(fragment.getView());
     89     }
     90 
     91     @Test
     92     public void addFragment_shouldSetTheFragmentsView() throws Exception {
     93         manager.addFragment(View.NO_ID, null, fragment, false);
     94 
     95         assertThat(fragment.getView(), sameInstance(fragment.onCreateViewReturnValue));
     96     }
     97 
     98     @Test
     99     public void addFragment_shouldSetTheFragmentsTag() throws Exception {
    100         manager.addFragment(View.NO_ID, "expected tag", fragment, false);
    101 
    102         assertThat(fragment.getTag(), equalTo("expected tag"));
    103     }
    104 
    105     @Test
    106     public void startFragment_shouldInsertTheFragmentViewIntoTheContainerView() throws Exception {
    107         manager.addFragment(CONTAINER_VIEW_ID, null, fragment, false);
    108         manager.startFragment(fragment);
    109 
    110         View fragmentViewParent = (View) activity.findViewById(TestFragment.FRAGMENT_VIEW_ID).getParent();
    111         assertThat(activity.findViewById(TestFragment.FRAGMENT_VIEW_ID), sameInstance(fragment.onCreateViewReturnValue));
    112         assertThat(fragmentViewParent, sameInstance((View) containerView));
    113     }
    114 
    115     @Test
    116     public void addFragmentWithReplace_shouldEmptyTheContainer() throws Exception {
    117         containerView.addView(new Button(activity));
    118         assertEquals(1, containerView.getChildCount());
    119 
    120         manager.addFragment(CONTAINER_VIEW_ID, null, fragment, true);
    121 
    122         assertEquals(1, containerView.getChildCount());
    123     }
    124 
    125     @Test
    126     public void addFragmentWithReplace_withNoContainer_shouldNotThrow() throws Exception {
    127         manager.addFragment(0, null, fragment, true);
    128         // pass
    129     }
    130 
    131     @Test
    132     public void addFragment_shouldSetFragmentsActivity() throws Exception {
    133         manager.addFragment(0, null, fragment, false);
    134 
    135         assertSame(activity, fragment.getActivity());
    136     }
    137 
    138     @Test
    139     public void addFragment_shouldPassTheSavedInstanceStateToOnCreate() throws Exception {
    140         Bundle bundle = new Bundle();
    141         shadowOf(fragment).setSavedInstanceState(bundle);
    142         manager.addFragment(0, null, fragment, false);
    143         assertSame(bundle, fragment.onCreateSavedInstanceState);
    144     }
    145 
    146     @Test
    147     public void getFragment_whenBundleSavedByShadowFragmentActivity_shouldGetFragmentByTagFromBundle() throws Exception {
    148         manager.addFragment(CONTAINER_VIEW_ID, "fragment tag", fragment, true);
    149 
    150         Bundle outState = new Bundle();
    151         shadowOf(activity).onSaveInstanceState(outState);
    152 
    153         Fragment retrievedFragment = manager.getFragment(outState, "fragment tag");
    154         assertEquals(TestFragment.class, retrievedFragment.getClass());
    155     }
    156 
    157     @Test
    158     public void startFragment_shouldPassSavedInstanceStateToOnCreateMethodOfFragment() throws Exception {
    159         shadowOf(fragment).setSavedInstanceState(new Bundle());
    160         manager.addFragment(CONTAINER_VIEW_ID, null, fragment, true);
    161         manager.startFragment(fragment);
    162 
    163         assertTrue(fragment.onActivityCreated_savedInstanceState != null);
    164     }
    165 
    166     @Test
    167     public void getCommittedTransactions_shouldReturnListOfOnlyCommittedTransactions() throws Exception {
    168         assertTrue(manager.getCommittedTransactions().isEmpty());
    169 
    170         FragmentTransaction transaction = manager.beginTransaction();
    171         assertTrue(manager.getCommittedTransactions().isEmpty());
    172 
    173         transaction.add(new Fragment(), "tag");
    174         transaction.commit();
    175         assertEquals(1, manager.getCommittedTransactions().size());
    176         assertSame(transaction, manager.getCommittedTransactions().get(0));
    177 
    178         FragmentTransaction anotherTransaction = manager.beginTransaction();
    179         anotherTransaction.add(new Fragment(), "tag");
    180         anotherTransaction.commit();
    181         assertEquals(2, manager.getCommittedTransactions().size());
    182         assertSame(anotherTransaction, manager.getCommittedTransactions().get(1));
    183     }
    184 
    185     @Test
    186     public void shouldBeAbleToCommitTransactions_whenTheFragmentHasNoView() throws Exception {
    187         TestFragment fragment = new TestFragment() {
    188             @Override
    189             public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    190                 return null;
    191             }
    192         };
    193 
    194         activity.getSupportFragmentManager().beginTransaction().add(CONTAINER_VIEW_ID, fragment).commit();
    195 
    196         assertSame(fragment, activity.getSupportFragmentManager().findFragmentById(CONTAINER_VIEW_ID));
    197     }
    198 
    199     @Test
    200     public void executePendingTransactions_shouldRunPendingCommitsAsIfTheMainLooperWereNotPaused() throws Exception {
    201         Robolectric.pauseMainLooper();
    202         Scheduler scheduler = shadowOf(Looper.getMainLooper()).getScheduler();
    203         Fragment fragment2 = new Fragment();
    204 
    205         TestRunnable otherEnqueuedTask = new TestRunnable();
    206         new Handler(Looper.getMainLooper()).post(otherEnqueuedTask);
    207 
    208         manager.beginTransaction().add(fragment, "fragment1").commit();
    209         manager.beginTransaction().add(fragment2, "fragment2").commit();
    210 
    211         assertEquals(3, scheduler.enqueuedTaskCount());
    212         assertNull(manager.findFragmentByTag("fragment1"));
    213         assertNull(manager.findFragmentByTag("fragment2"));
    214 
    215         boolean ranSomeTransactions = manager.executePendingTransactions();
    216         assertTrue(ranSomeTransactions);
    217         assertSame(fragment, manager.findFragmentByTag("fragment1"));
    218         assertSame(fragment2, manager.findFragmentByTag("fragment2"));
    219         assertEquals(1, scheduler.enqueuedTaskCount());
    220 
    221         assertFalse(otherEnqueuedTask.wasRun);
    222         Robolectric.unPauseMainLooper();
    223         assertTrue(otherEnqueuedTask.wasRun);
    224 
    225         ranSomeTransactions = manager.executePendingTransactions();
    226         assertFalse(ranSomeTransactions);
    227     }
    228 
    229     @Test
    230     public void executePendingTransactions_shouldAvoidRunningTransactionsThatWereAlreadyRun() throws Exception {
    231         manager.beginTransaction().add(fragment, "tag").commit();
    232         assertEquals(1, manager.getCommittedTransactions().size());
    233 
    234         boolean ranSomeTransactions = manager.executePendingTransactions();
    235         assertFalse(ranSomeTransactions);
    236         assertEquals(1, manager.getCommittedTransactions().size());
    237     }
    238 
    239     private static class TestFragmentActivity extends FragmentActivity {
    240         @Override
    241         public void onCreate(Bundle savedInstanceState) {
    242             super.onCreate(savedInstanceState);
    243             View view = new FrameLayout(this);
    244             view.setId(CONTAINER_VIEW_ID);
    245             setContentView(view);
    246         }
    247     }
    248 
    249 }
    250