/* * Copyright (C) 2017 The Dagger Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dagger.android.support.functional; import static com.google.common.truth.Truth.assertThat; import android.content.Intent; import android.content.res.Configuration; import android.os.Build; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; @RunWith(AndroidJUnit4.class) // Robolectric requires Java9 to run API 29 and above, so use API 28 instead @Config(sdk = Build.VERSION_CODES.P) public class InjectorsTest { private ActivityController activityController; private TestActivity activity; private TestParentFragment parentFragment; private TestChildFragment childFragment; private TestDialogFragment dialogFragment; private TestService service; private TestIntentService intentService; private TestBroadcastReceiver broadcastReceiver; private TestContentProvider contentProvider; @Before public void setUp() { activityController = Robolectric.buildActivity(TestActivity.class); activity = activityController.setup().get(); parentFragment = (TestParentFragment) activity.getSupportFragmentManager().findFragmentByTag("parent-fragment"); childFragment = (TestChildFragment) parentFragment.getChildFragmentManager().findFragmentByTag("child-fragment"); dialogFragment = (TestDialogFragment) activity.getSupportFragmentManager().findFragmentByTag("dialog-fragment"); service = Robolectric.buildService(TestService.class).create().get(); intentService = Robolectric.buildIntentService(TestIntentService.class).create().get(); broadcastReceiver = new TestBroadcastReceiver(); broadcastReceiver.onReceive(ApplicationProvider.getApplicationContext(), new Intent()); contentProvider = Robolectric.setupContentProvider(TestContentProvider.class); } @Test @Config(application = ComponentStructureFollowsControllerStructureApplication.class) public void componentStructureFollowsControllerStructure() { assertThat(activity.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.class); assertThat(parentFragment.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.ParentFragmentSubcomponent.class); assertThat(childFragment.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.ParentFragmentSubcomponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.ParentFragmentSubcomponent.ChildFragmentSubcomponent.class); assertThat(dialogFragment.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ActivitySubcomponent.DialogFragmentSubcomponent.class); assertThat(service.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ServiceSubcomponent.class); assertThat(intentService.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .IntentServiceSubcomponent.class); assertThat(broadcastReceiver.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .BroadcastReceiverSubcomponent.class); assertThat(contentProvider.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .ContentProviderSubcomponent.class); changeConfiguration(); OuterClass.TestInnerClassActivity innerClassActivity = Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class); assertThat(innerClassActivity.componentHierarchy) .containsExactly( ComponentStructureFollowsControllerStructureApplication.ApplicationComponent.class, ComponentStructureFollowsControllerStructureApplication.ApplicationComponent .InnerActivitySubcomponent.class); } @Test @Config(application = AllControllersAreDirectChildrenOfApplication.class) public void allControllersAreDirectChildrenOfApplication() { assertThat(activity.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ActivitySubcomponent .class); assertThat(parentFragment.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent .ParentFragmentSubcomponent.class); assertThat(childFragment.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent .ChildFragmentSubcomponent.class); assertThat(dialogFragment.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent .DialogFragmentSubcomponent.class); assertThat(service.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent.ServiceSubcomponent .class); assertThat(intentService.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent .IntentServiceSubcomponent.class); assertThat(broadcastReceiver.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent .BroadcastReceiverSubcomponent.class); assertThat(contentProvider.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent .ContentProviderSubcomponent.class); changeConfiguration(); OuterClass.TestInnerClassActivity innerClassActivity = Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class); assertThat(innerClassActivity.componentHierarchy) .containsExactly( AllControllersAreDirectChildrenOfApplication.ApplicationComponent.class, AllControllersAreDirectChildrenOfApplication.ApplicationComponent .InnerActivitySubcomponent.class); } @Test @Config(application = UsesGeneratedModulesApplication.class) public void usesGeneratedModules() { assertThat(activity.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyActivitySubcomponent.class); assertThat(parentFragment.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyParentFragmentSubcomponent.class); assertThat(childFragment.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyChildFragmentSubcomponent.class); assertThat(dialogFragment.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyDialogFragmentSubcomponent.class); assertThat(service.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyServiceSubcomponent.class); assertThat(intentService.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyIntentServiceSubcomponent.class); assertThat(broadcastReceiver.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyBroadcastReceiverSubcomponent.class); assertThat(contentProvider.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyContentProviderSubcomponent.class); changeConfiguration(); TestActivityWithScope activityWithScope = Robolectric.setupActivity(TestActivityWithScope.class); assertThat(activityWithScope.scopedStringProvider.get()) .isSameInstanceAs(activityWithScope.scopedStringProvider.get()); OuterClass.TestInnerClassActivity innerClassActivity = Robolectric.setupActivity(OuterClass.TestInnerClassActivity.class); assertThat(innerClassActivity.componentHierarchy) .containsExactly( UsesGeneratedModulesApplication.ApplicationComponent.class, UsesGeneratedModulesApplication.DummyInnerActivitySubcomponent.class); } // https://github.com/google/dagger/issues/598 private void changeConfiguration() { Configuration oldConfiguration = activity.getResources().getConfiguration(); Configuration newConfiguration = new Configuration(oldConfiguration); newConfiguration.orientation = oldConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; activityController.configurationChange(newConfiguration); } }