TestFragmentManager.java revision 99fafb79bf98b7aa1946bbda1f0a225cefa2d35d
1package com.xtremelabs.robolectric.tester.android.util;
2
3import android.os.Bundle;
4import android.os.Handler;
5import android.os.Looper;
6import android.support.v4.app.*;
7import android.view.View;
8import android.view.ViewGroup;
9import com.xtremelabs.robolectric.Robolectric;
10import com.xtremelabs.robolectric.shadows.SerializedFragmentState;
11import com.xtremelabs.robolectric.shadows.ShadowFragment;
12import com.xtremelabs.robolectric.shadows.ShadowFragmentActivity;
13
14import java.io.FileDescriptor;
15import java.io.PrintWriter;
16import java.util.ArrayList;
17import java.util.HashMap;
18import java.util.HashSet;
19import java.util.List;
20import java.util.Map;
21
22import static com.xtremelabs.robolectric.Robolectric.shadowOf;
23
24public class TestFragmentManager extends FragmentManager {
25    private Map<Integer, Fragment> fragmentsById = new HashMap<Integer, Fragment>();
26    private Map<String, Fragment> fragmentsByTag = new HashMap<String, Fragment>();
27    private FragmentActivity activity;
28    private List<TestFragmentTransaction> transactions = new ArrayList<TestFragmentTransaction>();
29    private List<Runnable> transactionsToRunLater = new ArrayList<Runnable>();
30
31    public TestFragmentManager(FragmentActivity activity) {
32        this.activity = activity;
33    }
34
35    public FragmentActivity getActivity() {
36        return activity;
37    }
38
39    @Override
40    public FragmentTransaction beginTransaction() {
41        return new TestFragmentTransaction(this);
42    }
43
44    @Override
45    public boolean executePendingTransactions() {
46        if (transactionsToRunLater.size() > 0) {
47            for (Runnable runnable : new ArrayList<Runnable>(transactionsToRunLater)) {
48                runnable.run();
49                shadowOf(Looper.getMainLooper()).getScheduler().remove(runnable);
50            }
51            return true;
52        }
53        return false;
54    }
55
56    @Override
57    public Fragment findFragmentById(int id) {
58        return fragmentsById.get(id);
59    }
60
61    @Override
62    public Fragment findFragmentByTag(String tag) {
63        return fragmentsByTag.get(tag);
64    }
65
66    @Override
67    public void popBackStack() {
68    }
69
70    @Override
71    public boolean popBackStackImmediate() {
72        return false;
73    }
74
75    @Override
76    public void popBackStack(String name, int flags) {
77    }
78
79    @Override
80    public boolean popBackStackImmediate(String name, int flags) {
81        return false;
82    }
83
84    @Override
85    public void popBackStack(int id, int flags) {
86    }
87
88    @Override
89    public boolean popBackStackImmediate(int id, int flags) {
90        return false;
91    }
92
93    @Override
94    public int getBackStackEntryCount() {
95        return 0;
96    }
97
98    @Override
99    public BackStackEntry getBackStackEntryAt(int index) {
100        return null;
101    }
102
103    @Override
104    public void addOnBackStackChangedListener(OnBackStackChangedListener listener) {
105    }
106
107    @Override
108    public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) {
109    }
110
111    @Override
112    public void putFragment(Bundle bundle, String key, Fragment fragment) {
113    }
114
115    @Override
116    public Fragment getFragment(Bundle bundle, String key) {
117        Object[] fragments = (Object[]) bundle.getSerializable(ShadowFragmentActivity.FRAGMENTS_TAG);
118        for (Object object : fragments) {
119            SerializedFragmentState fragment = (SerializedFragmentState) object;
120            if (fragment.tag.equals(key)) {
121                // TODO deserialize state
122                return Robolectric.newInstanceOf(fragment.fragmentClass);
123            }
124        }
125        return null;
126    }
127
128    @Override
129    public Fragment.SavedState saveFragmentInstanceState(Fragment f) {
130        return null;
131    }
132
133    @Override
134    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
135    }
136
137    public void addDialogFragment(String tag, DialogFragment fragment) {
138        fragmentsByTag.put(tag, fragment);
139    }
140
141    public void addFragment(int containerViewId, String tag, Fragment fragment, boolean replace) {
142        fragmentsById.put(containerViewId, fragment);
143        fragmentsByTag.put(tag, fragment);
144
145        ShadowFragment shadowFragment = shadowOf(fragment);
146        shadowFragment.setTag(tag);
147        shadowFragment.setContainerViewId(containerViewId);
148        shadowFragment.setShouldReplace(replace);
149        shadowFragment.setActivity(activity);
150
151        fragment.onAttach(activity);
152        fragment.onCreate(shadowFragment.getSavedInstanceState());
153    }
154
155    public void startFragment(Fragment fragment) {
156        ViewGroup container = null;
157        ShadowFragment shadowFragment = shadowOf(fragment);
158        if (shadowOf(activity).getContentView() != null) {
159            container = (ViewGroup) activity.findViewById(shadowFragment.getContainerViewId());
160        }
161
162        View view = fragment.onCreateView(activity.getLayoutInflater(), container, shadowFragment.getSavedInstanceState());
163        shadowFragment.setView(view);
164
165        fragment.onViewCreated(view, null);
166        if (container != null) {
167            if (shadowFragment.getShouldReplace()) {
168                container.removeAllViews();
169            }
170            if (view != null) {
171                container.addView(view);
172            }
173        }
174
175        fragment.onActivityCreated(shadowFragment.getSavedInstanceState());
176        fragment.onStart();
177    }
178
179    public HashMap<Integer, Fragment> getFragmentsById() {
180        return new HashMap<Integer, Fragment>(fragmentsById);
181    }
182
183    public HashSet<Fragment> getFragments() {
184        HashSet<Fragment> fragments = new HashSet<Fragment>();
185        fragments.addAll(fragmentsById.values());
186        fragments.addAll(fragmentsByTag.values());
187        return fragments;
188    }
189
190    public List<TestFragmentTransaction> getCommittedTransactions() {
191        return transactions;
192    }
193
194    public void commitTransaction(TestFragmentTransaction t) {
195        transactions.add(t);
196        if (t.isStarting()) {
197            addFragment(t.getContainerViewId(), t.getTag(), t.getFragment(), t.isReplacing());
198            shadowOf(t.getFragment()).setAdded(true);
199            startFragment(t.getFragment());
200        }
201        if (t.isRemoving()) {
202            Fragment fragment = t.getFragmentToRemove();
203            shadowOf(fragment).setAdded(false);
204            if (fragment instanceof DialogFragment) {
205                ((DialogFragment)fragment).dismiss();
206            }
207        }
208        if (t.isAttaching()) {
209            shadowOf(t.getFragmentToAttach()).setAttached(true);
210        }
211        if (t.isHiding()) {
212            Fragment fragment = t.getFragment();
213            if (!fragment.isHidden()) {
214                shadowOf(fragment).setHidden(true);
215                fragment.onHiddenChanged(true);
216            }
217        }
218        if (t.isShowing()) {
219            Fragment fragment = t.getFragment();
220            if (fragment.isHidden()) {
221                shadowOf(fragment).setHidden(false);
222                fragment.onHiddenChanged(false);
223            }
224        }
225    }
226
227    void commitLater(final TestFragmentTransaction testFragmentTransaction) {
228        Runnable transactionCommit = new Runnable() {
229            @Override
230            public void run() {
231                commitTransaction(testFragmentTransaction);
232                transactionsToRunLater.remove(this);
233            }
234        };
235        transactionsToRunLater.add(transactionCommit);
236        new Handler().post(transactionCommit);
237    }
238}
239