FragmentTransactionTest.java revision 0765353c002bfdf681c982565810aa4be3499dd0
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.support.v4.app;
17
18import static junit.framework.TestCase.assertFalse;
19import static junit.framework.TestCase.assertTrue;
20
21import static org.junit.Assert.assertEquals;
22
23import android.app.Activity;
24import android.app.Instrumentation;
25import android.content.Intent;
26import android.os.SystemClock;
27import android.support.fragment.test.R;
28import android.support.test.InstrumentationRegistry;
29import android.support.test.filters.MediumTest;
30import android.support.test.rule.ActivityTestRule;
31import android.support.test.runner.AndroidJUnit4;
32import android.support.v4.app.test.FragmentTestActivity;
33import android.support.v4.app.test.NewIntentActivity;
34
35import org.junit.Before;
36import org.junit.Rule;
37import org.junit.Test;
38import org.junit.runner.RunWith;
39
40import java.util.concurrent.TimeUnit;
41
42/**
43 * Tests usage of the {@link FragmentTransaction} class.
44 */
45@MediumTest
46@RunWith(AndroidJUnit4.class)
47public class FragmentTransactionTest {
48
49    @Rule
50    public ActivityTestRule<FragmentTestActivity> mActivityRule =
51            new ActivityTestRule<>(FragmentTestActivity.class);
52
53    private FragmentTestActivity mActivity;
54
55    @Before
56    public void setUp() {
57        mActivity = mActivityRule.getActivity();
58    }
59
60    @Test
61    public void testAddTransactionWithValidFragment() throws Throwable {
62        final Fragment fragment = new CorrectFragment();
63        mActivityRule.runOnUiThread(new Runnable() {
64            @Override
65            public void run() {
66                mActivity.getSupportFragmentManager().beginTransaction()
67                        .add(R.id.content, fragment)
68                        .addToBackStack(null)
69                        .commit();
70                mActivity.getSupportFragmentManager().executePendingTransactions();
71            }
72        });
73        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
74        assertTrue(fragment.isAdded());
75    }
76
77    @Test
78    public void testAddTransactionWithPrivateFragment() throws Throwable {
79        final Fragment fragment = new PrivateFragment();
80        mActivityRule.runOnUiThread(new Runnable() {
81            @Override
82            public void run() {
83                boolean exceptionThrown = false;
84                try {
85                    mActivity.getSupportFragmentManager().beginTransaction()
86                            .add(R.id.content, fragment)
87                            .addToBackStack(null)
88                            .commit();
89                    mActivity.getSupportFragmentManager().executePendingTransactions();
90                } catch (IllegalStateException e) {
91                    exceptionThrown = true;
92                } finally {
93                    assertTrue("Exception should be thrown", exceptionThrown);
94                    assertFalse("Fragment shouldn't be added", fragment.isAdded());
95                }
96            }
97        });
98        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
99    }
100
101    @Test
102    public void testAddTransactionWithPackagePrivateFragment() throws Throwable {
103        final Fragment fragment = new PackagePrivateFragment();
104        mActivityRule.runOnUiThread(new Runnable() {
105            @Override
106            public void run() {
107                boolean exceptionThrown = false;
108                try {
109                    mActivity.getSupportFragmentManager().beginTransaction()
110                            .add(R.id.content, fragment)
111                            .addToBackStack(null)
112                            .commit();
113                    mActivity.getSupportFragmentManager().executePendingTransactions();
114                } catch (IllegalStateException e) {
115                    exceptionThrown = true;
116                } finally {
117                    assertTrue("Exception should be thrown", exceptionThrown);
118                    assertFalse("Fragment shouldn't be added", fragment.isAdded());
119                }
120            }
121        });
122        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
123    }
124
125    @Test
126    public void testAddTransactionWithAnonymousFragment() throws Throwable {
127        final Fragment fragment = new Fragment() {};
128        mActivityRule.runOnUiThread(new Runnable() {
129            @Override
130            public void run() {
131                boolean exceptionThrown = false;
132                try {
133                    mActivity.getSupportFragmentManager().beginTransaction()
134                            .add(R.id.content, fragment)
135                            .addToBackStack(null)
136                            .commit();
137                    mActivity.getSupportFragmentManager().executePendingTransactions();
138                } catch (IllegalStateException e) {
139                    exceptionThrown = true;
140                } finally {
141                    assertTrue("Exception should be thrown", exceptionThrown);
142                    assertFalse("Fragment shouldn't be added", fragment.isAdded());
143                }
144            }
145        });
146        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
147    }
148
149    @Test
150    public void testAddTransactionWithNonStaticFragment() throws Throwable {
151        final Fragment fragment = new NonStaticFragment();
152        mActivityRule.runOnUiThread(new Runnable() {
153            @Override
154            public void run() {
155                boolean exceptionThrown = false;
156                try {
157                    mActivity.getSupportFragmentManager().beginTransaction()
158                            .add(R.id.content, fragment)
159                            .addToBackStack(null)
160                            .commit();
161                    mActivity.getSupportFragmentManager().executePendingTransactions();
162                } catch (IllegalStateException e) {
163                    exceptionThrown = true;
164                } finally {
165                    assertTrue("Exception should be thrown", exceptionThrown);
166                    assertFalse("Fragment shouldn't be added", fragment.isAdded());
167                }
168            }
169        });
170        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
171    }
172
173    /**
174     * onNewIntent() should note that the state is not saved so that child fragment
175     * managers can execute transactions.
176     */
177    @Test
178    public void newIntentUnlocks() throws Throwable {
179        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
180        Intent intent1 = new Intent(mActivity, NewIntentActivity.class)
181                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
182        NewIntentActivity newIntentActivity =
183                (NewIntentActivity) instrumentation.startActivitySync(intent1);
184        FragmentTestUtil.waitForExecution(mActivityRule);
185
186        Intent intent2 = new Intent(mActivity, FragmentTestActivity.class);
187        intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
188        Activity coveringActivity = instrumentation.startActivitySync(intent2);
189        FragmentTestUtil.waitForExecution(mActivityRule);
190
191        Intent intent3 = new Intent(mActivity, NewIntentActivity.class)
192                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
193        mActivity.startActivity(intent3);
194        assertTrue(newIntentActivity.newIntent.await(1, TimeUnit.SECONDS));
195        FragmentTestUtil.waitForExecution(mActivityRule);
196
197        for (Fragment fragment : newIntentActivity.getSupportFragmentManager().getFragments()) {
198            // There really should only be one fragment in newIntentActivity.
199            assertEquals(1, fragment.getChildFragmentManager().getFragments().size());
200        }
201    }
202
203    private void getFragmentsUntilSize(int expectedSize) {
204        final long endTime = SystemClock.uptimeMillis() + 3000;
205
206        do {
207            assertTrue(SystemClock.uptimeMillis() < endTime);
208        } while (mActivity.getSupportFragmentManager().getFragments().size() != expectedSize);
209    }
210
211    public static class CorrectFragment extends Fragment {}
212
213    private static class PrivateFragment extends Fragment {}
214
215    static class PackagePrivateFragment extends Fragment {}
216
217    private class NonStaticFragment extends Fragment {}
218}
219