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