xref: /aosp_15_r20/external/dagger2/javatests/dagger/hilt/android/AliasOfMultipleScopesTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1 /*
2  * Copyright (C) 2021 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.hilt.android;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static java.lang.annotation.RetentionPolicy.CLASS;
21 
22 import android.content.Context;
23 import android.os.Build;
24 import androidx.activity.ComponentActivity;
25 import androidx.test.core.app.ActivityScenario;
26 import androidx.test.ext.junit.runners.AndroidJUnit4;
27 import dagger.Module;
28 import dagger.Provides;
29 import dagger.hilt.DefineComponent;
30 import dagger.hilt.EntryPoint;
31 import dagger.hilt.EntryPoints;
32 import dagger.hilt.InstallIn;
33 import dagger.hilt.android.components.ActivityComponent;
34 import dagger.hilt.android.qualifiers.ApplicationContext;
35 import dagger.hilt.android.scopes.ActivityScoped;
36 import dagger.hilt.android.testing.HiltAndroidRule;
37 import dagger.hilt.android.testing.HiltAndroidTest;
38 import dagger.hilt.android.testing.HiltTestApplication;
39 import dagger.hilt.components.SingletonComponent;
40 import dagger.hilt.migration.AliasOf;
41 import java.lang.annotation.ElementType;
42 import java.lang.annotation.Retention;
43 import java.lang.annotation.Target;
44 import javax.inject.Inject;
45 import javax.inject.Provider;
46 import javax.inject.Scope;
47 import org.junit.Before;
48 import org.junit.Rule;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.robolectric.annotation.Config;
52 
53 @HiltAndroidTest
54 @RunWith(AndroidJUnit4.class)
55 @Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class)
56 public final class AliasOfMultipleScopesTest {
57 
58   @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this);
59 
60   @Inject @ApplicationContext Context context;
61   @Inject CustomComponent.Builder customComponentBuilder;
62 
63   @Scope
64   @Retention(CLASS)
65   @Target({ElementType.METHOD, ElementType.TYPE})
66   public @interface CustomScoped {}
67 
68   @DefineComponent(parent = SingletonComponent.class)
69   @CustomScoped
70   public interface CustomComponent {
71     @DefineComponent.Builder
72     public interface Builder {
build()73       CustomComponent build();
74     }
75   }
76 
77   @Scope
78   @AliasOf({ActivityScoped.class, CustomScoped.class})
79   public @interface AliasScoped {}
80 
81   public interface UnscopedDep {}
82 
83   public interface ActivityScopedDep {}
84 
85   public interface CustomScopedDep {}
86 
87   public interface AliasScopedDep {}
88 
89   @Module
90   @InstallIn(SingletonComponent.class)
91   interface SingletonTestModule {
92     @Provides
unscopedDep()93     static UnscopedDep unscopedDep() {
94       return new UnscopedDep() {};
95     }
96   }
97 
98   @Module
99   @InstallIn(ActivityComponent.class)
100   interface ActivityTestModule {
101     @Provides
102     @ActivityScoped
activityScopedDep()103     static ActivityScopedDep activityScopedDep() {
104       return new ActivityScopedDep() {};
105     }
106 
107     @Provides
108     @AliasScoped
aliasScopedDep()109     static AliasScopedDep aliasScopedDep() {
110       return new AliasScopedDep() {};
111     }
112   }
113 
114   @Module
115   @InstallIn(CustomComponent.class)
116   interface CustomTestModule {
117     @Provides
118     @CustomScoped
customScopedDep()119     static CustomScopedDep customScopedDep() {
120       return new CustomScopedDep() {};
121     }
122 
123     @Provides
124     @AliasScoped
aliasScopedDep()125     static AliasScopedDep aliasScopedDep() {
126       return new AliasScopedDep() {};
127     }
128   }
129 
130   /** An activity to test injection. */
131   @AndroidEntryPoint(ComponentActivity.class)
132   public static final class TestActivity extends Hilt_AliasOfMultipleScopesTest_TestActivity {
133     @Inject Provider<UnscopedDep> unscopedDep;
134     @Inject Provider<ActivityScopedDep> activityScopedDep;
135     @Inject Provider<AliasScopedDep> aliasScopedDep;
136   }
137 
138   @EntryPoint
139   @InstallIn(SingletonComponent.class)
140   interface CustomComponentBuilderEntryPoint {
customComponentBuilder()141     CustomComponent.Builder customComponentBuilder();
142   }
143 
144   @EntryPoint
145   @InstallIn(CustomComponent.class)
146   interface CustomComponentEntryPoint {
unscopedDep()147     Provider<UnscopedDep> unscopedDep();
148 
customScopedDep()149     Provider<CustomScopedDep> customScopedDep();
150 
aliasScopedDep()151     Provider<AliasScopedDep> aliasScopedDep();
152   }
153 
154   @Before
setUp()155   public void setUp() {
156     rule.inject();
157   }
158 
159   @Test
testActivityScoped()160   public void testActivityScoped() {
161     try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
162       scenario.onActivity(
163           activity -> {
164             assertThat(activity.unscopedDep.get()).isNotSameInstanceAs(activity.unscopedDep.get());
165             assertThat(activity.activityScopedDep.get())
166                 .isSameInstanceAs(activity.activityScopedDep.get());
167             assertThat(activity.aliasScopedDep.get())
168                 .isSameInstanceAs(activity.aliasScopedDep.get());
169           });
170     }
171   }
172 
173   @Test
testCustomScoped()174   public void testCustomScoped() {
175     CustomComponent customComponent =
176         EntryPoints.get(context, CustomComponentBuilderEntryPoint.class)
177             .customComponentBuilder()
178             .build();
179     CustomComponentEntryPoint entryPoint =
180         EntryPoints.get(customComponent, CustomComponentEntryPoint.class);
181     assertThat(entryPoint.unscopedDep().get()).isNotSameInstanceAs(entryPoint.unscopedDep().get());
182     assertThat(entryPoint.customScopedDep().get())
183         .isSameInstanceAs(entryPoint.customScopedDep().get());
184     assertThat(entryPoint.aliasScopedDep().get())
185         .isSameInstanceAs(entryPoint.aliasScopedDep().get());
186   }
187 }
188