1 /* 2 * Copyright (C) 2017 The Dagger Authors. 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 */ 16 17 package dagger.android.support.functional; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import android.content.Intent; 22 import android.content.res.Configuration; 23 import android.os.Build; 24 import androidx.test.core.app.ApplicationProvider; 25 import androidx.test.ext.junit.runners.AndroidJUnit4; 26 import org.junit.Before; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.robolectric.Robolectric; 30 import org.robolectric.android.controller.ActivityController; 31 import org.robolectric.annotation.Config; 32 33 @RunWith(AndroidJUnit4.class) 34 // Robolectric requires Java9 to run API 29 and above, so use API 28 instead 35 @Config(sdk = Build.VERSION_CODES.P) 36 public class InjectorsTest { 37 private ActivityController<TestActivity> activityController; 38 private TestActivity activity; 39 private TestParentFragment parentFragment; 40 private TestChildFragment childFragment; 41 private TestDialogFragment dialogFragment; 42 private TestService service; 43 private TestIntentService intentService; 44 private TestBroadcastReceiver broadcastReceiver; 45 private TestContentProvider contentProvider; 46 47 @Before setUp()48 public void setUp() { 49 activityController = Robolectric.buildActivity(TestActivity.class); 50 activity = activityController.setup().get(); 51 parentFragment = 52 (TestParentFragment) 53 activity.getSupportFragmentManager().findFragmentByTag("parent-fragment"); 54 childFragment = 55 (TestChildFragment) 56 parentFragment.getChildFragmentManager().findFragmentByTag("child-fragment"); 57 dialogFragment = 58 (TestDialogFragment) 59 activity.getSupportFragmentManager().findFragmentByTag("dialog-fragment"); 60 61 service = Robolectric.buildService(TestService.class).create().get(); 62 intentService = Robolectric.buildIntentService(TestIntentService.class).create().get(); 63 64 broadcastReceiver = new TestBroadcastReceiver(); 65 broadcastReceiver.onReceive(ApplicationProvider.getApplicationContext(), new Intent()); 66 67 contentProvider = Robolectric.setupContentProvider(TestContentProvider.class); 68 } 69 70 @Test 71 @Config(application = ComponentStructureFollowsControllerStructureApplication.class) componentStructureFollowsControllerStructure()72 public void componentStructureFollowsControllerStructure() { 73 assertThat(activity.componentHierarchy) 74 .containsExactly( 75 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 76 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 77 .ActivitySubcomponent.class); 78 assertThat(parentFragment.componentHierarchy) 79 .containsExactly( 80 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 81 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 82 .ActivitySubcomponent.class, 83 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 84 .ActivitySubcomponent.ParentFragmentSubcomponent.class); 85 assertThat(childFragment.componentHierarchy) 86 .containsExactly( 87 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 88 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 89 .ActivitySubcomponent.class, 90 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 91 .ActivitySubcomponent.ParentFragmentSubcomponent.class, 92 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 93 .ActivitySubcomponent.ParentFragmentSubcomponent.ChildFragmentSubcomponent.class); 94 assertThat(dialogFragment.componentHierarchy) 95 .containsExactly( 96 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 97 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 98 .ActivitySubcomponent.class, 99 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 100 .ActivitySubcomponent.DialogFragmentSubcomponent.class); 101 102 assertThat(service.componentHierarchy) 103 .containsExactly( 104 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 105 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 106 .ServiceSubcomponent.class); 107 assertThat(intentService.componentHierarchy) 108 .containsExactly( 109 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 110 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 111 .IntentServiceSubcomponent.class); 112 113 assertThat(broadcastReceiver.componentHierarchy) 114 .containsExactly( 115 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 116 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 117 .BroadcastReceiverSubcomponent.class); 118 119 assertThat(contentProvider.componentHierarchy) 120 .containsExactly( 121 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 122 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 123 .ContentProviderSubcomponent.class); 124 125 changeConfiguration(); 126 127 OuterClass.TestInnerClassActivity innerClassActivity = 128 Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class); 129 assertThat(innerClassActivity.componentHierarchy) 130 .containsExactly( 131 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, 132 ComponentStructureFollowsControllerStructureApplication.ApplicationComponent 133 .InnerActivitySubcomponent.class); 134 } 135 136 @Test 137 @Config(application = AllControllersAreDirectChildrenOfApplication.class) allControllersAreDirectChildrenOfApplication()138 public void allControllersAreDirectChildrenOfApplication() { 139 assertThat(activity.componentHierarchy) 140 .containsExactly( 141 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 142 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ActivitySubcomponent 143 .class); 144 assertThat(parentFragment.componentHierarchy) 145 .containsExactly( 146 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 147 AllControllersAreDirectChildrenOfApplication.ApplicationComponent 148 .ParentFragmentSubcomponent.class); 149 assertThat(childFragment.componentHierarchy) 150 .containsExactly( 151 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 152 AllControllersAreDirectChildrenOfApplication.ApplicationComponent 153 .ChildFragmentSubcomponent.class); 154 assertThat(dialogFragment.componentHierarchy) 155 .containsExactly( 156 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 157 AllControllersAreDirectChildrenOfApplication.ApplicationComponent 158 .DialogFragmentSubcomponent.class); 159 160 assertThat(service.componentHierarchy) 161 .containsExactly( 162 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 163 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ServiceSubcomponent 164 .class); 165 assertThat(intentService.componentHierarchy) 166 .containsExactly( 167 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 168 AllControllersAreDirectChildrenOfApplication.ApplicationComponent 169 .IntentServiceSubcomponent.class); 170 171 assertThat(broadcastReceiver.componentHierarchy) 172 .containsExactly( 173 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 174 AllControllersAreDirectChildrenOfApplication.ApplicationComponent 175 .BroadcastReceiverSubcomponent.class); 176 177 assertThat(contentProvider.componentHierarchy) 178 .containsExactly( 179 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 180 AllControllersAreDirectChildrenOfApplication.ApplicationComponent 181 .ContentProviderSubcomponent.class); 182 183 changeConfiguration(); 184 185 OuterClass.TestInnerClassActivity innerClassActivity = 186 Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class); 187 assertThat(innerClassActivity.componentHierarchy) 188 .containsExactly( 189 AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, 190 AllControllersAreDirectChildrenOfApplication.ApplicationComponent 191 .InnerActivitySubcomponent.class); 192 } 193 194 @Test 195 @Config(application = UsesGeneratedModulesApplication.class) usesGeneratedModules()196 public void usesGeneratedModules() { 197 assertThat(activity.componentHierarchy) 198 .containsExactly( 199 UsesGeneratedModulesApplication.ApplicationComponent.class, 200 UsesGeneratedModulesApplication.DummyActivitySubcomponent.class); 201 assertThat(parentFragment.componentHierarchy) 202 .containsExactly( 203 UsesGeneratedModulesApplication.ApplicationComponent.class, 204 UsesGeneratedModulesApplication.DummyParentFragmentSubcomponent.class); 205 assertThat(childFragment.componentHierarchy) 206 .containsExactly( 207 UsesGeneratedModulesApplication.ApplicationComponent.class, 208 UsesGeneratedModulesApplication.DummyChildFragmentSubcomponent.class); 209 assertThat(dialogFragment.componentHierarchy) 210 .containsExactly( 211 UsesGeneratedModulesApplication.ApplicationComponent.class, 212 UsesGeneratedModulesApplication.DummyDialogFragmentSubcomponent.class); 213 214 assertThat(service.componentHierarchy) 215 .containsExactly( 216 UsesGeneratedModulesApplication.ApplicationComponent.class, 217 UsesGeneratedModulesApplication.DummyServiceSubcomponent.class); 218 assertThat(intentService.componentHierarchy) 219 .containsExactly( 220 UsesGeneratedModulesApplication.ApplicationComponent.class, 221 UsesGeneratedModulesApplication.DummyIntentServiceSubcomponent.class); 222 223 assertThat(broadcastReceiver.componentHierarchy) 224 .containsExactly( 225 UsesGeneratedModulesApplication.ApplicationComponent.class, 226 UsesGeneratedModulesApplication.DummyBroadcastReceiverSubcomponent.class); 227 228 assertThat(contentProvider.componentHierarchy) 229 .containsExactly( 230 UsesGeneratedModulesApplication.ApplicationComponent.class, 231 UsesGeneratedModulesApplication.DummyContentProviderSubcomponent.class); 232 233 changeConfiguration(); 234 235 TestActivityWithScope activityWithScope = 236 Robolectric.setupActivity(TestActivityWithScope.class); 237 assertThat(activityWithScope.scopedStringProvider.get()) 238 .isSameInstanceAs(activityWithScope.scopedStringProvider.get()); 239 240 OuterClass.TestInnerClassActivity innerClassActivity = 241 Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class); 242 assertThat(innerClassActivity.componentHierarchy) 243 .containsExactly( 244 UsesGeneratedModulesApplication.ApplicationComponent.class, 245 UsesGeneratedModulesApplication.DummyInnerActivitySubcomponent.class); 246 } 247 248 // https://github.com/google/dagger/issues/598 changeConfiguration()249 private void changeConfiguration() { 250 Configuration oldConfiguration = activity.getResources().getConfiguration(); 251 Configuration newConfiguration = new Configuration(oldConfiguration); 252 newConfiguration.orientation = 253 oldConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE 254 ? Configuration.ORIENTATION_PORTRAIT 255 : Configuration.ORIENTATION_LANDSCAPE; 256 activityController.configurationChange(newConfiguration); 257 } 258 } 259