/* * Copyright (C) 2021 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.hilt.android; import static com.google.common.truth.Truth.assertThat; import static java.lang.annotation.RetentionPolicy.CLASS; import android.content.Context; import android.os.Build; import androidx.activity.ComponentActivity; import androidx.test.core.app.ActivityScenario; import androidx.test.ext.junit.runners.AndroidJUnit4; import dagger.Module; import dagger.Provides; import dagger.hilt.DefineComponent; import dagger.hilt.EntryPoint; import dagger.hilt.EntryPoints; import dagger.hilt.InstallIn; import dagger.hilt.android.components.ActivityComponent; import dagger.hilt.android.qualifiers.ApplicationContext; import dagger.hilt.android.scopes.ActivityScoped; import dagger.hilt.android.testing.HiltAndroidRule; import dagger.hilt.android.testing.HiltAndroidTest; import dagger.hilt.android.testing.HiltTestApplication; import dagger.hilt.components.SingletonComponent; import dagger.hilt.migration.AliasOf; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Scope; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; @HiltAndroidTest @RunWith(AndroidJUnit4.class) @Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class) public final class AliasOfMultipleScopesTest { @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this); @Inject @ApplicationContext Context context; @Inject CustomComponent.Builder customComponentBuilder; @Scope @Retention(CLASS) @Target({ElementType.METHOD, ElementType.TYPE}) public @interface CustomScoped {} @DefineComponent(parent = SingletonComponent.class) @CustomScoped public interface CustomComponent { @DefineComponent.Builder public interface Builder { CustomComponent build(); } } @Scope @AliasOf({ActivityScoped.class, CustomScoped.class}) public @interface AliasScoped {} public interface UnscopedDep {} public interface ActivityScopedDep {} public interface CustomScopedDep {} public interface AliasScopedDep {} @Module @InstallIn(SingletonComponent.class) interface SingletonTestModule { @Provides static UnscopedDep unscopedDep() { return new UnscopedDep() {}; } } @Module @InstallIn(ActivityComponent.class) interface ActivityTestModule { @Provides @ActivityScoped static ActivityScopedDep activityScopedDep() { return new ActivityScopedDep() {}; } @Provides @AliasScoped static AliasScopedDep aliasScopedDep() { return new AliasScopedDep() {}; } } @Module @InstallIn(CustomComponent.class) interface CustomTestModule { @Provides @CustomScoped static CustomScopedDep customScopedDep() { return new CustomScopedDep() {}; } @Provides @AliasScoped static AliasScopedDep aliasScopedDep() { return new AliasScopedDep() {}; } } /** An activity to test injection. */ @AndroidEntryPoint(ComponentActivity.class) public static final class TestActivity extends Hilt_AliasOfMultipleScopesTest_TestActivity { @Inject Provider unscopedDep; @Inject Provider activityScopedDep; @Inject Provider aliasScopedDep; } @EntryPoint @InstallIn(SingletonComponent.class) interface CustomComponentBuilderEntryPoint { CustomComponent.Builder customComponentBuilder(); } @EntryPoint @InstallIn(CustomComponent.class) interface CustomComponentEntryPoint { Provider unscopedDep(); Provider customScopedDep(); Provider aliasScopedDep(); } @Before public void setUp() { rule.inject(); } @Test public void testActivityScoped() { try (ActivityScenario scenario = ActivityScenario.launch(TestActivity.class)) { scenario.onActivity( activity -> { assertThat(activity.unscopedDep.get()).isNotSameInstanceAs(activity.unscopedDep.get()); assertThat(activity.activityScopedDep.get()) .isSameInstanceAs(activity.activityScopedDep.get()); assertThat(activity.aliasScopedDep.get()) .isSameInstanceAs(activity.aliasScopedDep.get()); }); } } @Test public void testCustomScoped() { CustomComponent customComponent = EntryPoints.get(context, CustomComponentBuilderEntryPoint.class) .customComponentBuilder() .build(); CustomComponentEntryPoint entryPoint = EntryPoints.get(customComponent, CustomComponentEntryPoint.class); assertThat(entryPoint.unscopedDep().get()).isNotSameInstanceAs(entryPoint.unscopedDep().get()); assertThat(entryPoint.customScopedDep().get()) .isSameInstanceAs(entryPoint.customScopedDep().get()); assertThat(entryPoint.aliasScopedDep().get()) .isSameInstanceAs(entryPoint.aliasScopedDep().get()); } }