xref: /aosp_15_r20/external/dagger2/javatests/dagger/hilt/android/MultiTestRoot2Test.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2020 The Dagger Authors.
3*f585d8a3SJacky Wang  *
4*f585d8a3SJacky Wang  * Licensed under the Apache License, Version 2.0 (the "License");
5*f585d8a3SJacky Wang  * you may not use this file except in compliance with the License.
6*f585d8a3SJacky Wang  * You may obtain a copy of the License at
7*f585d8a3SJacky Wang  *
8*f585d8a3SJacky Wang  * http://www.apache.org/licenses/LICENSE-2.0
9*f585d8a3SJacky Wang  *
10*f585d8a3SJacky Wang  * Unless required by applicable law or agreed to in writing, software
11*f585d8a3SJacky Wang  * distributed under the License is distributed on an "AS IS" BASIS,
12*f585d8a3SJacky Wang  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*f585d8a3SJacky Wang  * See the License for the specific language governing permissions and
14*f585d8a3SJacky Wang  * limitations under the License.
15*f585d8a3SJacky Wang  */
16*f585d8a3SJacky Wang 
17*f585d8a3SJacky Wang package dagger.hilt.android;
18*f585d8a3SJacky Wang 
19*f585d8a3SJacky Wang import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
20*f585d8a3SJacky Wang import static com.google.common.truth.Truth.assertThat;
21*f585d8a3SJacky Wang import static org.junit.Assert.assertThrows;
22*f585d8a3SJacky Wang 
23*f585d8a3SJacky Wang import android.os.Build;
24*f585d8a3SJacky Wang import androidx.activity.ComponentActivity;
25*f585d8a3SJacky Wang import androidx.test.ext.junit.runners.AndroidJUnit4;
26*f585d8a3SJacky Wang import dagger.Module;
27*f585d8a3SJacky Wang import dagger.Provides;
28*f585d8a3SJacky Wang import dagger.hilt.EntryPoint;
29*f585d8a3SJacky Wang import dagger.hilt.EntryPoints;
30*f585d8a3SJacky Wang import dagger.hilt.InstallIn;
31*f585d8a3SJacky Wang import dagger.hilt.android.components.ActivityComponent;
32*f585d8a3SJacky Wang import dagger.hilt.android.testing.BindValue;
33*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltAndroidRule;
34*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltAndroidTest;
35*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltTestApplication;
36*f585d8a3SJacky Wang import dagger.hilt.components.SingletonComponent;
37*f585d8a3SJacky Wang import javax.inject.Inject;
38*f585d8a3SJacky Wang import javax.inject.Named;
39*f585d8a3SJacky Wang import org.junit.Rule;
40*f585d8a3SJacky Wang import org.junit.Test;
41*f585d8a3SJacky Wang import org.junit.runner.RunWith;
42*f585d8a3SJacky Wang import org.robolectric.Robolectric;
43*f585d8a3SJacky Wang import org.robolectric.android.controller.ActivityController;
44*f585d8a3SJacky Wang import org.robolectric.annotation.Config;
45*f585d8a3SJacky Wang 
46*f585d8a3SJacky Wang @HiltAndroidTest
47*f585d8a3SJacky Wang @RunWith(AndroidJUnit4.class)
48*f585d8a3SJacky Wang // Robolectric requires Java9 to run API 29 and above, so use API 28 instead
49*f585d8a3SJacky Wang @Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class)
50*f585d8a3SJacky Wang public final class MultiTestRoot2Test {
51*f585d8a3SJacky Wang   private static final int INT_VALUE = 13;
52*f585d8a3SJacky Wang   private static final String STR_VALUE = "MultiTestRoot2TestValue";
53*f585d8a3SJacky Wang   private static final long LONG_VALUE = 17L;
54*f585d8a3SJacky Wang   private static final String BIND_VALUE_STRING = "BIND_VALUE_STRING";
55*f585d8a3SJacky Wang   private static final String TEST_QUALIFIER = "TEST_QUALIFIER";
56*f585d8a3SJacky Wang 
57*f585d8a3SJacky Wang   @EntryPoint
58*f585d8a3SJacky Wang   @InstallIn(SingletonComponent.class)
59*f585d8a3SJacky Wang   public interface BindValueEntryPoint {
60*f585d8a3SJacky Wang     @Named(TEST_QUALIFIER)
bindValueString()61*f585d8a3SJacky Wang     String bindValueString();
62*f585d8a3SJacky Wang   }
63*f585d8a3SJacky Wang 
64*f585d8a3SJacky Wang   @AndroidEntryPoint(ComponentActivity.class)
65*f585d8a3SJacky Wang   public static class TestActivity extends Hilt_MultiTestRoot2Test_TestActivity {
66*f585d8a3SJacky Wang     @Inject Baz baz;
67*f585d8a3SJacky Wang     @Inject @MultiTestRootExternalModules.External Long externalLongValue;
68*f585d8a3SJacky Wang   }
69*f585d8a3SJacky Wang 
70*f585d8a3SJacky Wang   @Module
71*f585d8a3SJacky Wang   @InstallIn(ActivityComponent.class)
72*f585d8a3SJacky Wang   public interface TestActivityModule {
73*f585d8a3SJacky Wang     @Provides
provideBaz()74*f585d8a3SJacky Wang     static Baz provideBaz() {
75*f585d8a3SJacky Wang       return new Baz(LONG_VALUE);
76*f585d8a3SJacky Wang     }
77*f585d8a3SJacky Wang   }
78*f585d8a3SJacky Wang 
79*f585d8a3SJacky Wang   @Module
80*f585d8a3SJacky Wang   @InstallIn(SingletonComponent.class)
81*f585d8a3SJacky Wang   interface PkgPrivateTestModule {
82*f585d8a3SJacky Wang     @Provides
provideQux()83*f585d8a3SJacky Wang     static Qux provideQux() {
84*f585d8a3SJacky Wang       return new Qux();
85*f585d8a3SJacky Wang     }
86*f585d8a3SJacky Wang   }
87*f585d8a3SJacky Wang 
88*f585d8a3SJacky Wang   @Module
89*f585d8a3SJacky Wang   @InstallIn(SingletonComponent.class)
90*f585d8a3SJacky Wang   public interface TestModule {
91*f585d8a3SJacky Wang     @Provides
provideInt()92*f585d8a3SJacky Wang     static int provideInt() {
93*f585d8a3SJacky Wang       return INT_VALUE;
94*f585d8a3SJacky Wang     }
95*f585d8a3SJacky Wang 
96*f585d8a3SJacky Wang     @Provides
provideString()97*f585d8a3SJacky Wang     static String provideString() {
98*f585d8a3SJacky Wang       return STR_VALUE;
99*f585d8a3SJacky Wang     }
100*f585d8a3SJacky Wang   }
101*f585d8a3SJacky Wang 
102*f585d8a3SJacky Wang   public static final class Outer {
103*f585d8a3SJacky Wang     @Module
104*f585d8a3SJacky Wang     @InstallIn(SingletonComponent.class)
105*f585d8a3SJacky Wang     public interface NestedTestModule {
106*f585d8a3SJacky Wang       @Provides
provideLong()107*f585d8a3SJacky Wang       static long provideLong() {
108*f585d8a3SJacky Wang         return LONG_VALUE;
109*f585d8a3SJacky Wang       }
110*f585d8a3SJacky Wang     }
111*f585d8a3SJacky Wang 
Outer()112*f585d8a3SJacky Wang     private Outer() {}
113*f585d8a3SJacky Wang   }
114*f585d8a3SJacky Wang 
115*f585d8a3SJacky Wang   static class Foo {
116*f585d8a3SJacky Wang     final int value;
117*f585d8a3SJacky Wang 
118*f585d8a3SJacky Wang     @Inject
Foo(int value)119*f585d8a3SJacky Wang     Foo(int value) {
120*f585d8a3SJacky Wang       this.value = value;
121*f585d8a3SJacky Wang     }
122*f585d8a3SJacky Wang   }
123*f585d8a3SJacky Wang 
124*f585d8a3SJacky Wang   // Must be public due to b/183636779
125*f585d8a3SJacky Wang   public static class Bar {
126*f585d8a3SJacky Wang     final String value;
127*f585d8a3SJacky Wang 
Bar(String value)128*f585d8a3SJacky Wang     Bar(String value) {
129*f585d8a3SJacky Wang       this.value = value;
130*f585d8a3SJacky Wang     }
131*f585d8a3SJacky Wang   }
132*f585d8a3SJacky Wang 
133*f585d8a3SJacky Wang   static class Baz {
134*f585d8a3SJacky Wang     final long value;
135*f585d8a3SJacky Wang 
Baz(long value)136*f585d8a3SJacky Wang     Baz(long value) {
137*f585d8a3SJacky Wang       this.value = value;
138*f585d8a3SJacky Wang     }
139*f585d8a3SJacky Wang   }
140*f585d8a3SJacky Wang 
141*f585d8a3SJacky Wang   // Must be public due to b/183636779
142*f585d8a3SJacky Wang   public static class Qux {}
143*f585d8a3SJacky Wang 
144*f585d8a3SJacky Wang   @Module
145*f585d8a3SJacky Wang   @InstallIn(SingletonComponent.class)
146*f585d8a3SJacky Wang   public interface BarModule {
147*f585d8a3SJacky Wang     @Provides
provideBar(String value)148*f585d8a3SJacky Wang     static Bar provideBar(String value) {
149*f585d8a3SJacky Wang       return new Bar(value);
150*f585d8a3SJacky Wang     }
151*f585d8a3SJacky Wang   }
152*f585d8a3SJacky Wang 
153*f585d8a3SJacky Wang   @EntryPoint
154*f585d8a3SJacky Wang   @InstallIn(SingletonComponent.class)
155*f585d8a3SJacky Wang   public interface BarEntryPoint {
getBar()156*f585d8a3SJacky Wang     Bar getBar();
157*f585d8a3SJacky Wang   }
158*f585d8a3SJacky Wang 
159*f585d8a3SJacky Wang   @EntryPoint
160*f585d8a3SJacky Wang   @InstallIn(SingletonComponent.class)
161*f585d8a3SJacky Wang   interface PkgPrivateQuxEntryPoint {
getQux()162*f585d8a3SJacky Wang     Qux getQux();
163*f585d8a3SJacky Wang   }
164*f585d8a3SJacky Wang 
165*f585d8a3SJacky Wang   @Rule public HiltAndroidRule rule = new HiltAndroidRule(this);
166*f585d8a3SJacky Wang 
167*f585d8a3SJacky Wang   @Inject Foo foo;
168*f585d8a3SJacky Wang   @Inject Qux qux;
169*f585d8a3SJacky Wang   @Inject String str;
170*f585d8a3SJacky Wang   @Inject Long longValue;
171*f585d8a3SJacky Wang   @Inject @MultiTestRootExternalModules.External String externalStrValue;
172*f585d8a3SJacky Wang 
173*f585d8a3SJacky Wang   @BindValue
174*f585d8a3SJacky Wang   @Named(TEST_QUALIFIER)
175*f585d8a3SJacky Wang   String bindValueString = BIND_VALUE_STRING;
176*f585d8a3SJacky Wang 
177*f585d8a3SJacky Wang   @Test
testInjectFromTestModule()178*f585d8a3SJacky Wang   public void testInjectFromTestModule() throws Exception {
179*f585d8a3SJacky Wang     assertThat(foo).isNull();
180*f585d8a3SJacky Wang     rule.inject();
181*f585d8a3SJacky Wang     assertThat(foo).isNotNull();
182*f585d8a3SJacky Wang     assertThat(foo.value).isEqualTo(INT_VALUE);
183*f585d8a3SJacky Wang   }
184*f585d8a3SJacky Wang 
185*f585d8a3SJacky Wang   @Test
testInjectFromTestModuleWithArgs()186*f585d8a3SJacky Wang   public void testInjectFromTestModuleWithArgs() throws Exception {
187*f585d8a3SJacky Wang     assertThat(str).isNull();
188*f585d8a3SJacky Wang     rule.inject();
189*f585d8a3SJacky Wang     assertThat(str).isNotNull();
190*f585d8a3SJacky Wang     assertThat(str).isEqualTo(STR_VALUE);
191*f585d8a3SJacky Wang   }
192*f585d8a3SJacky Wang 
193*f585d8a3SJacky Wang   @Test
testInjectFromNestedTestModule()194*f585d8a3SJacky Wang   public void testInjectFromNestedTestModule() throws Exception {
195*f585d8a3SJacky Wang     assertThat(longValue).isNull();
196*f585d8a3SJacky Wang     rule.inject();
197*f585d8a3SJacky Wang     assertThat(longValue).isNotNull();
198*f585d8a3SJacky Wang     assertThat(longValue).isEqualTo(LONG_VALUE);
199*f585d8a3SJacky Wang   }
200*f585d8a3SJacky Wang 
201*f585d8a3SJacky Wang   @Test
testInjectFromPkgPrivateTestModule()202*f585d8a3SJacky Wang   public void testInjectFromPkgPrivateTestModule() throws Exception {
203*f585d8a3SJacky Wang     assertThat(qux).isNull();
204*f585d8a3SJacky Wang     rule.inject();
205*f585d8a3SJacky Wang     assertThat(qux).isNotNull();
206*f585d8a3SJacky Wang   }
207*f585d8a3SJacky Wang 
208*f585d8a3SJacky Wang   @Test
testInjectFromExternalAppModule()209*f585d8a3SJacky Wang   public void testInjectFromExternalAppModule() throws Exception {
210*f585d8a3SJacky Wang     assertThat(externalStrValue).isNull();
211*f585d8a3SJacky Wang     rule.inject();
212*f585d8a3SJacky Wang     assertThat(externalStrValue).isNotNull();
213*f585d8a3SJacky Wang     assertThat(externalStrValue).isEqualTo(MultiTestRootExternalModules.EXTERNAL_STR_VALUE);
214*f585d8a3SJacky Wang   }
215*f585d8a3SJacky Wang 
216*f585d8a3SJacky Wang   @Test
testInjectFromExternalActivityModule()217*f585d8a3SJacky Wang   public void testInjectFromExternalActivityModule() throws Exception {
218*f585d8a3SJacky Wang     rule.inject();
219*f585d8a3SJacky Wang     ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
220*f585d8a3SJacky Wang     assertThat(ac.get().externalLongValue).isNull();
221*f585d8a3SJacky Wang     ac.create();
222*f585d8a3SJacky Wang     assertThat(ac.get().externalLongValue).isNotNull();
223*f585d8a3SJacky Wang     assertThat(ac.get().externalLongValue)
224*f585d8a3SJacky Wang         .isEqualTo(MultiTestRootExternalModules.EXTERNAL_LONG_VALUE);
225*f585d8a3SJacky Wang   }
226*f585d8a3SJacky Wang 
227*f585d8a3SJacky Wang   @Test
testLocalEntryPoint()228*f585d8a3SJacky Wang   public void testLocalEntryPoint() throws Exception {
229*f585d8a3SJacky Wang     rule.inject();
230*f585d8a3SJacky Wang     Bar bar = EntryPoints.get(getApplicationContext(), BarEntryPoint.class).getBar();
231*f585d8a3SJacky Wang     assertThat(bar).isNotNull();
232*f585d8a3SJacky Wang     assertThat(bar.value).isEqualTo(STR_VALUE);
233*f585d8a3SJacky Wang   }
234*f585d8a3SJacky Wang 
235*f585d8a3SJacky Wang   @Test
testLocalPkgPrivateEntryPoint()236*f585d8a3SJacky Wang   public void testLocalPkgPrivateEntryPoint() throws Exception {
237*f585d8a3SJacky Wang     rule.inject();
238*f585d8a3SJacky Wang     Qux qux = EntryPoints.get(getApplicationContext(), PkgPrivateQuxEntryPoint.class).getQux();
239*f585d8a3SJacky Wang     assertThat(qux).isNotNull();
240*f585d8a3SJacky Wang   }
241*f585d8a3SJacky Wang 
242*f585d8a3SJacky Wang   @Test
testAndroidEntryPoint()243*f585d8a3SJacky Wang   public void testAndroidEntryPoint() throws Exception {
244*f585d8a3SJacky Wang     rule.inject();
245*f585d8a3SJacky Wang     ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
246*f585d8a3SJacky Wang     assertThat(ac.get().baz).isNull();
247*f585d8a3SJacky Wang     ac.create();
248*f585d8a3SJacky Wang     assertThat(ac.get().baz).isNotNull();
249*f585d8a3SJacky Wang     assertThat(ac.get().baz.value).isEqualTo(LONG_VALUE);
250*f585d8a3SJacky Wang   }
251*f585d8a3SJacky Wang 
252*f585d8a3SJacky Wang   @Test
testMissingMultiTestRoot1EntryPoint()253*f585d8a3SJacky Wang   public void testMissingMultiTestRoot1EntryPoint() throws Exception {
254*f585d8a3SJacky Wang     rule.inject();
255*f585d8a3SJacky Wang     ClassCastException exception =
256*f585d8a3SJacky Wang         assertThrows(
257*f585d8a3SJacky Wang             ClassCastException.class,
258*f585d8a3SJacky Wang             () -> EntryPoints.get(getApplicationContext(), MultiTestRoot1Test.BarEntryPoint.class));
259*f585d8a3SJacky Wang     assertThat(exception)
260*f585d8a3SJacky Wang         .hasMessageThat()
261*f585d8a3SJacky Wang         .isEqualTo(
262*f585d8a3SJacky Wang             "Cannot cast dagger.hilt.android.internal.testing.root."
263*f585d8a3SJacky Wang                 + "DaggerMultiTestRoot2Test_HiltComponents_SingletonC$SingletonCImpl"
264*f585d8a3SJacky Wang                 + " to dagger.hilt.android.MultiTestRoot1Test$BarEntryPoint");
265*f585d8a3SJacky Wang   }
266*f585d8a3SJacky Wang 
267*f585d8a3SJacky Wang   @Test
testBindValueFieldIsProvided()268*f585d8a3SJacky Wang   public void testBindValueFieldIsProvided() throws Exception {
269*f585d8a3SJacky Wang     rule.inject();
270*f585d8a3SJacky Wang     assertThat(bindValueString).isEqualTo(BIND_VALUE_STRING);
271*f585d8a3SJacky Wang     assertThat(getBinding()).isEqualTo(BIND_VALUE_STRING);
272*f585d8a3SJacky Wang   }
273*f585d8a3SJacky Wang 
274*f585d8a3SJacky Wang   @Test
testBindValueIsMutable()275*f585d8a3SJacky Wang   public void testBindValueIsMutable() throws Exception {
276*f585d8a3SJacky Wang     rule.inject();
277*f585d8a3SJacky Wang     bindValueString = "newValue";
278*f585d8a3SJacky Wang     assertThat(getBinding()).isEqualTo("newValue");
279*f585d8a3SJacky Wang   }
280*f585d8a3SJacky Wang 
getBinding()281*f585d8a3SJacky Wang   private static String getBinding() {
282*f585d8a3SJacky Wang     return EntryPoints.get(getApplicationContext(), BindValueEntryPoint.class).bindValueString();
283*f585d8a3SJacky Wang   }
284*f585d8a3SJacky Wang }
285