xref: /aosp_15_r20/external/dagger2/javatests/dagger/internal/codegen/MembersInjectionTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2015 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.internal.codegen;
18*f585d8a3SJacky Wang 
19*f585d8a3SJacky Wang import androidx.room.compiler.processing.util.Source;
20*f585d8a3SJacky Wang import com.google.common.collect.ImmutableList;
21*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap;
22*f585d8a3SJacky Wang import com.squareup.javapoet.MethodSpec;
23*f585d8a3SJacky Wang import com.squareup.javapoet.TypeSpec;
24*f585d8a3SJacky Wang import dagger.internal.codegen.javapoet.TypeNames;
25*f585d8a3SJacky Wang import dagger.testing.compile.CompilerTests;
26*f585d8a3SJacky Wang import dagger.testing.golden.GoldenFileRule;
27*f585d8a3SJacky Wang import org.junit.Rule;
28*f585d8a3SJacky Wang import org.junit.Test;
29*f585d8a3SJacky Wang import org.junit.runner.RunWith;
30*f585d8a3SJacky Wang import org.junit.runners.Parameterized;
31*f585d8a3SJacky Wang import org.junit.runners.Parameterized.Parameters;
32*f585d8a3SJacky Wang 
33*f585d8a3SJacky Wang @RunWith(Parameterized.class)
34*f585d8a3SJacky Wang public class MembersInjectionTest {
35*f585d8a3SJacky Wang   @Parameters(name = "{0}")
parameters()36*f585d8a3SJacky Wang   public static ImmutableList<Object[]> parameters() {
37*f585d8a3SJacky Wang     return CompilerMode.TEST_PARAMETERS;
38*f585d8a3SJacky Wang   }
39*f585d8a3SJacky Wang 
40*f585d8a3SJacky Wang   @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule();
41*f585d8a3SJacky Wang 
42*f585d8a3SJacky Wang   private final CompilerMode compilerMode;
43*f585d8a3SJacky Wang 
MembersInjectionTest(CompilerMode compilerMode)44*f585d8a3SJacky Wang   public MembersInjectionTest(CompilerMode compilerMode) {
45*f585d8a3SJacky Wang     this.compilerMode = compilerMode;
46*f585d8a3SJacky Wang   }
47*f585d8a3SJacky Wang 
48*f585d8a3SJacky Wang   @Test
injectKotlinProtectField_fails()49*f585d8a3SJacky Wang   public void injectKotlinProtectField_fails() {
50*f585d8a3SJacky Wang     Source injectFieldSrc =
51*f585d8a3SJacky Wang         CompilerTests.kotlinSource(
52*f585d8a3SJacky Wang             "MyClass.kt",
53*f585d8a3SJacky Wang             "package test",
54*f585d8a3SJacky Wang             "",
55*f585d8a3SJacky Wang             "import javax.inject.Inject",
56*f585d8a3SJacky Wang             "",
57*f585d8a3SJacky Wang             "class MyClass @Inject constructor() {",
58*f585d8a3SJacky Wang             "  @Inject protected lateinit var protectedField: String",
59*f585d8a3SJacky Wang             "}");
60*f585d8a3SJacky Wang     Source moduleSrc =
61*f585d8a3SJacky Wang         CompilerTests.kotlinSource(
62*f585d8a3SJacky Wang             "MyModule.kt",
63*f585d8a3SJacky Wang             "package test",
64*f585d8a3SJacky Wang             "",
65*f585d8a3SJacky Wang             "import dagger.Module",
66*f585d8a3SJacky Wang             "import dagger.Provides",
67*f585d8a3SJacky Wang             "",
68*f585d8a3SJacky Wang             "@Module",
69*f585d8a3SJacky Wang             "object MyModule {",
70*f585d8a3SJacky Wang             "  @Provides",
71*f585d8a3SJacky Wang             "  fun providesString() = \"hello\"",
72*f585d8a3SJacky Wang             "}");
73*f585d8a3SJacky Wang     Source componentSrc =
74*f585d8a3SJacky Wang         CompilerTests.kotlinSource(
75*f585d8a3SJacky Wang             "MyComponent.kt",
76*f585d8a3SJacky Wang             "package test",
77*f585d8a3SJacky Wang             "",
78*f585d8a3SJacky Wang             "import dagger.Component",
79*f585d8a3SJacky Wang             "@Component(modules = [MyModule::class])",
80*f585d8a3SJacky Wang             "interface MyComponent {}");
81*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(injectFieldSrc, moduleSrc, componentSrc)
82*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
83*f585d8a3SJacky Wang         .compile(
84*f585d8a3SJacky Wang             subject -> {
85*f585d8a3SJacky Wang               subject.hasErrorCount(1);
86*f585d8a3SJacky Wang               subject.hasErrorContaining(
87*f585d8a3SJacky Wang                   "Dagger injector does not have access to kotlin protected fields");
88*f585d8a3SJacky Wang             });
89*f585d8a3SJacky Wang   }
90*f585d8a3SJacky Wang 
91*f585d8a3SJacky Wang   @Test
injectJavaProtectField_succeeds()92*f585d8a3SJacky Wang   public void injectJavaProtectField_succeeds() {
93*f585d8a3SJacky Wang     Source injectFieldSrc =
94*f585d8a3SJacky Wang         CompilerTests.javaSource(
95*f585d8a3SJacky Wang             "test.MyClass",
96*f585d8a3SJacky Wang             "package test;",
97*f585d8a3SJacky Wang             "",
98*f585d8a3SJacky Wang             "import javax.inject.Inject;",
99*f585d8a3SJacky Wang             "",
100*f585d8a3SJacky Wang             "public final class MyClass {",
101*f585d8a3SJacky Wang             "  @Inject MyClass() {}",
102*f585d8a3SJacky Wang             "  @Inject protected String protectedField;",
103*f585d8a3SJacky Wang             "}");
104*f585d8a3SJacky Wang     Source moduleSrc =
105*f585d8a3SJacky Wang         CompilerTests.kotlinSource(
106*f585d8a3SJacky Wang             "MyModule.kt",
107*f585d8a3SJacky Wang             "package test",
108*f585d8a3SJacky Wang             "",
109*f585d8a3SJacky Wang             "import dagger.Module",
110*f585d8a3SJacky Wang             "import dagger.Provides",
111*f585d8a3SJacky Wang             "",
112*f585d8a3SJacky Wang             "@Module",
113*f585d8a3SJacky Wang             "object MyModule {",
114*f585d8a3SJacky Wang             "  @Provides",
115*f585d8a3SJacky Wang             "  fun providesString() = \"hello\"",
116*f585d8a3SJacky Wang             "}");
117*f585d8a3SJacky Wang     Source componentSrc =
118*f585d8a3SJacky Wang         CompilerTests.kotlinSource(
119*f585d8a3SJacky Wang             "MyComponent.kt",
120*f585d8a3SJacky Wang             "package test",
121*f585d8a3SJacky Wang             "",
122*f585d8a3SJacky Wang             "import dagger.Component",
123*f585d8a3SJacky Wang             "@Component(modules = [MyModule::class])",
124*f585d8a3SJacky Wang             "interface MyComponent {}");
125*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(injectFieldSrc, moduleSrc, componentSrc)
126*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
127*f585d8a3SJacky Wang         .compile(subject -> subject.hasErrorCount(0));
128*f585d8a3SJacky Wang   }
129*f585d8a3SJacky Wang 
130*f585d8a3SJacky Wang   @Test
parentClass_noInjectedMembers()131*f585d8a3SJacky Wang   public void parentClass_noInjectedMembers() throws Exception {
132*f585d8a3SJacky Wang     Source childFile =
133*f585d8a3SJacky Wang         CompilerTests.javaSource(
134*f585d8a3SJacky Wang             "test.Child",
135*f585d8a3SJacky Wang             "package test;",
136*f585d8a3SJacky Wang             "",
137*f585d8a3SJacky Wang             "import javax.inject.Inject;",
138*f585d8a3SJacky Wang             "",
139*f585d8a3SJacky Wang             "public final class Child extends Parent {",
140*f585d8a3SJacky Wang             "  @Inject Child() {}",
141*f585d8a3SJacky Wang             "}");
142*f585d8a3SJacky Wang     Source parentFile =
143*f585d8a3SJacky Wang         CompilerTests.javaSource(
144*f585d8a3SJacky Wang             "test.Parent",
145*f585d8a3SJacky Wang             "package test;",
146*f585d8a3SJacky Wang             "",
147*f585d8a3SJacky Wang             "public abstract class Parent {}");
148*f585d8a3SJacky Wang 
149*f585d8a3SJacky Wang     Source componentFile =
150*f585d8a3SJacky Wang         CompilerTests.javaSource(
151*f585d8a3SJacky Wang             "test.TestComponent",
152*f585d8a3SJacky Wang             "package test;",
153*f585d8a3SJacky Wang             "",
154*f585d8a3SJacky Wang             "import dagger.Component;",
155*f585d8a3SJacky Wang             "",
156*f585d8a3SJacky Wang             "@Component",
157*f585d8a3SJacky Wang             "interface TestComponent {",
158*f585d8a3SJacky Wang             "  Child child();",
159*f585d8a3SJacky Wang             "}");
160*f585d8a3SJacky Wang 
161*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(childFile, parentFile, componentFile)
162*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
163*f585d8a3SJacky Wang         .compile(
164*f585d8a3SJacky Wang             subject -> {
165*f585d8a3SJacky Wang               subject.hasErrorCount(0);
166*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
167*f585d8a3SJacky Wang             });
168*f585d8a3SJacky Wang   }
169*f585d8a3SJacky Wang 
170*f585d8a3SJacky Wang   @Test
parentClass_injectedMembersInSupertype()171*f585d8a3SJacky Wang   public void parentClass_injectedMembersInSupertype() throws Exception {
172*f585d8a3SJacky Wang     Source childFile =
173*f585d8a3SJacky Wang         CompilerTests.javaSource(
174*f585d8a3SJacky Wang             "test.Child",
175*f585d8a3SJacky Wang             "package test;",
176*f585d8a3SJacky Wang             "",
177*f585d8a3SJacky Wang             "import javax.inject.Inject;",
178*f585d8a3SJacky Wang             "",
179*f585d8a3SJacky Wang             "public final class Child extends Parent {",
180*f585d8a3SJacky Wang             "  @Inject Child() {}",
181*f585d8a3SJacky Wang             "}");
182*f585d8a3SJacky Wang     Source parentFile =
183*f585d8a3SJacky Wang         CompilerTests.javaSource(
184*f585d8a3SJacky Wang             "test.Parent",
185*f585d8a3SJacky Wang             "package test;",
186*f585d8a3SJacky Wang             "",
187*f585d8a3SJacky Wang             "import javax.inject.Inject;",
188*f585d8a3SJacky Wang             "",
189*f585d8a3SJacky Wang             "public abstract class Parent {",
190*f585d8a3SJacky Wang             "  @Inject Dep dep;",
191*f585d8a3SJacky Wang             "}");
192*f585d8a3SJacky Wang     Source depFile =
193*f585d8a3SJacky Wang         CompilerTests.javaSource(
194*f585d8a3SJacky Wang             "test.Dep",
195*f585d8a3SJacky Wang             "package test;",
196*f585d8a3SJacky Wang             "",
197*f585d8a3SJacky Wang             "import javax.inject.Inject;",
198*f585d8a3SJacky Wang             "",
199*f585d8a3SJacky Wang             "final class Dep {",
200*f585d8a3SJacky Wang             "  @Inject Dep() {}",
201*f585d8a3SJacky Wang             "}");
202*f585d8a3SJacky Wang     Source componentFile =
203*f585d8a3SJacky Wang         CompilerTests.javaSource(
204*f585d8a3SJacky Wang             "test.TestComponent",
205*f585d8a3SJacky Wang             "package test;",
206*f585d8a3SJacky Wang             "",
207*f585d8a3SJacky Wang             "import dagger.Component;",
208*f585d8a3SJacky Wang             "",
209*f585d8a3SJacky Wang             "@Component",
210*f585d8a3SJacky Wang             "interface TestComponent {",
211*f585d8a3SJacky Wang             "  Child child();",
212*f585d8a3SJacky Wang             "}");
213*f585d8a3SJacky Wang 
214*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(childFile, parentFile, depFile, componentFile)
215*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
216*f585d8a3SJacky Wang         .compile(
217*f585d8a3SJacky Wang             subject -> {
218*f585d8a3SJacky Wang               subject.hasErrorCount(0);
219*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
220*f585d8a3SJacky Wang             });
221*f585d8a3SJacky Wang   }
222*f585d8a3SJacky Wang 
fieldAndMethodGenerics()223*f585d8a3SJacky Wang   @Test public void fieldAndMethodGenerics() {
224*f585d8a3SJacky Wang     Source file =
225*f585d8a3SJacky Wang         CompilerTests.javaSource(
226*f585d8a3SJacky Wang             "test.GenericClass",
227*f585d8a3SJacky Wang             "package test;",
228*f585d8a3SJacky Wang             "",
229*f585d8a3SJacky Wang             "import javax.inject.Inject;",
230*f585d8a3SJacky Wang             "",
231*f585d8a3SJacky Wang             "class GenericClass<A, B> {",
232*f585d8a3SJacky Wang             "  @Inject A a;",
233*f585d8a3SJacky Wang             "",
234*f585d8a3SJacky Wang             "  @Inject GenericClass() {}",
235*f585d8a3SJacky Wang             "",
236*f585d8a3SJacky Wang             " @Inject void register(B b) {}",
237*f585d8a3SJacky Wang             "}");
238*f585d8a3SJacky Wang 
239*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
240*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
241*f585d8a3SJacky Wang         .compile(
242*f585d8a3SJacky Wang             subject -> {
243*f585d8a3SJacky Wang               subject.hasErrorCount(0);
244*f585d8a3SJacky Wang               subject.generatedSource(
245*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/GenericClass_MembersInjector"));
246*f585d8a3SJacky Wang             });
247*f585d8a3SJacky Wang   }
248*f585d8a3SJacky Wang 
subclassedGenericMembersInjectors()249*f585d8a3SJacky Wang   @Test public void subclassedGenericMembersInjectors() {
250*f585d8a3SJacky Wang     Source a =
251*f585d8a3SJacky Wang         CompilerTests.javaSource(
252*f585d8a3SJacky Wang             "test.A",
253*f585d8a3SJacky Wang             "package test;",
254*f585d8a3SJacky Wang             "",
255*f585d8a3SJacky Wang             "import javax.inject.Inject;",
256*f585d8a3SJacky Wang             "",
257*f585d8a3SJacky Wang             "final class A {",
258*f585d8a3SJacky Wang             "  @Inject A() {}",
259*f585d8a3SJacky Wang             "}");
260*f585d8a3SJacky Wang     Source a2 =
261*f585d8a3SJacky Wang         CompilerTests.javaSource(
262*f585d8a3SJacky Wang             "test.A2",
263*f585d8a3SJacky Wang             "package test;",
264*f585d8a3SJacky Wang             "",
265*f585d8a3SJacky Wang             "import javax.inject.Inject;",
266*f585d8a3SJacky Wang             "",
267*f585d8a3SJacky Wang             "final class A2 {",
268*f585d8a3SJacky Wang             "  @Inject A2() {}",
269*f585d8a3SJacky Wang             "}");
270*f585d8a3SJacky Wang     Source parent =
271*f585d8a3SJacky Wang         CompilerTests.javaSource(
272*f585d8a3SJacky Wang             "test.Parent",
273*f585d8a3SJacky Wang             "package test;",
274*f585d8a3SJacky Wang             "",
275*f585d8a3SJacky Wang             "import javax.inject.Inject;",
276*f585d8a3SJacky Wang             "",
277*f585d8a3SJacky Wang             "class Parent<X, Y> {",
278*f585d8a3SJacky Wang             "  @Inject X x;",
279*f585d8a3SJacky Wang             "  @Inject Y y;",
280*f585d8a3SJacky Wang             "  @Inject A2 a2;",
281*f585d8a3SJacky Wang             "",
282*f585d8a3SJacky Wang             "  @Inject Parent() {}",
283*f585d8a3SJacky Wang             "}");
284*f585d8a3SJacky Wang     Source child =
285*f585d8a3SJacky Wang         CompilerTests.javaSource(
286*f585d8a3SJacky Wang             "test.Child",
287*f585d8a3SJacky Wang             "package test;",
288*f585d8a3SJacky Wang             "",
289*f585d8a3SJacky Wang             "import javax.inject.Inject;",
290*f585d8a3SJacky Wang             "",
291*f585d8a3SJacky Wang             "class Child<T> extends Parent<T, A> {",
292*f585d8a3SJacky Wang             "  @Inject A a;",
293*f585d8a3SJacky Wang             "  @Inject T t;",
294*f585d8a3SJacky Wang             "",
295*f585d8a3SJacky Wang             "  @Inject Child() {}",
296*f585d8a3SJacky Wang             "}");
297*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(a, a2, parent, child)
298*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
299*f585d8a3SJacky Wang         .compile(
300*f585d8a3SJacky Wang             subject -> {
301*f585d8a3SJacky Wang               subject.hasErrorCount(0);
302*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/Child_MembersInjector"));
303*f585d8a3SJacky Wang             });
304*f585d8a3SJacky Wang   }
305*f585d8a3SJacky Wang 
fieldInjection()306*f585d8a3SJacky Wang   @Test public void fieldInjection() {
307*f585d8a3SJacky Wang     Source file =
308*f585d8a3SJacky Wang         CompilerTests.javaSource(
309*f585d8a3SJacky Wang             "test.FieldInjection",
310*f585d8a3SJacky Wang             "package test;",
311*f585d8a3SJacky Wang             "",
312*f585d8a3SJacky Wang             "import dagger.Lazy;",
313*f585d8a3SJacky Wang             "import javax.inject.Inject;",
314*f585d8a3SJacky Wang             "import javax.inject.Provider;",
315*f585d8a3SJacky Wang             "",
316*f585d8a3SJacky Wang             "class FieldInjection {",
317*f585d8a3SJacky Wang             "  @Inject String string;",
318*f585d8a3SJacky Wang             "  @Inject Lazy<String> lazyString;",
319*f585d8a3SJacky Wang             "  @Inject Provider<String> stringProvider;",
320*f585d8a3SJacky Wang             "}");
321*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
322*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
323*f585d8a3SJacky Wang         .compile(
324*f585d8a3SJacky Wang             subject -> {
325*f585d8a3SJacky Wang               subject.hasErrorCount(0);
326*f585d8a3SJacky Wang               subject.generatedSource(
327*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/FieldInjection_MembersInjector"));
328*f585d8a3SJacky Wang             });
329*f585d8a3SJacky Wang   }
330*f585d8a3SJacky Wang 
331*f585d8a3SJacky Wang   @Test
fieldInjectionWithQualifier()332*f585d8a3SJacky Wang   public void fieldInjectionWithQualifier() {
333*f585d8a3SJacky Wang     Source file =
334*f585d8a3SJacky Wang         CompilerTests.javaSource(
335*f585d8a3SJacky Wang             "test.FieldInjectionWithQualifier",
336*f585d8a3SJacky Wang             "package test;",
337*f585d8a3SJacky Wang             "",
338*f585d8a3SJacky Wang             "import dagger.Lazy;",
339*f585d8a3SJacky Wang             "import javax.inject.Inject;",
340*f585d8a3SJacky Wang             "import javax.inject.Named;",
341*f585d8a3SJacky Wang             "import javax.inject.Provider;",
342*f585d8a3SJacky Wang             "",
343*f585d8a3SJacky Wang             "class FieldInjectionWithQualifier {",
344*f585d8a3SJacky Wang             "  @Inject @Named(\"A\") String a;",
345*f585d8a3SJacky Wang             "  @Inject @Named(\"B\") String b;",
346*f585d8a3SJacky Wang             "}");
347*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
348*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
349*f585d8a3SJacky Wang         .compile(
350*f585d8a3SJacky Wang             subject -> {
351*f585d8a3SJacky Wang               subject.hasErrorCount(0);
352*f585d8a3SJacky Wang               subject.generatedSource(
353*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/FieldInjectionWithQualifier_MembersInjector"));
354*f585d8a3SJacky Wang             });
355*f585d8a3SJacky Wang   }
356*f585d8a3SJacky Wang 
methodInjection()357*f585d8a3SJacky Wang   @Test public void methodInjection() {
358*f585d8a3SJacky Wang     Source file =
359*f585d8a3SJacky Wang         CompilerTests.javaSource(
360*f585d8a3SJacky Wang             "test.MethodInjection",
361*f585d8a3SJacky Wang             "package test;",
362*f585d8a3SJacky Wang             "",
363*f585d8a3SJacky Wang             "import dagger.Lazy;",
364*f585d8a3SJacky Wang             "import javax.inject.Inject;",
365*f585d8a3SJacky Wang             "import javax.inject.Provider;",
366*f585d8a3SJacky Wang             "",
367*f585d8a3SJacky Wang             "class MethodInjection {",
368*f585d8a3SJacky Wang             "  @Inject void noArgs() {}",
369*f585d8a3SJacky Wang             "  @Inject void oneArg(String string) {}",
370*f585d8a3SJacky Wang             "  @Inject void manyArgs(",
371*f585d8a3SJacky Wang             "      String string, Lazy<String> lazyString, Provider<String> stringProvider) {}",
372*f585d8a3SJacky Wang             "}");
373*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
374*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
375*f585d8a3SJacky Wang         .compile(
376*f585d8a3SJacky Wang             subject -> {
377*f585d8a3SJacky Wang               subject.hasErrorCount(0);
378*f585d8a3SJacky Wang               subject.generatedSource(
379*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/MethodInjection_MembersInjector"));
380*f585d8a3SJacky Wang             });
381*f585d8a3SJacky Wang   }
382*f585d8a3SJacky Wang 
383*f585d8a3SJacky Wang   @Test
mixedMemberInjection()384*f585d8a3SJacky Wang   public void mixedMemberInjection() {
385*f585d8a3SJacky Wang     Source file =
386*f585d8a3SJacky Wang         CompilerTests.javaSource(
387*f585d8a3SJacky Wang             "test.MixedMemberInjection",
388*f585d8a3SJacky Wang             "package test;",
389*f585d8a3SJacky Wang             "",
390*f585d8a3SJacky Wang             "import dagger.Lazy;",
391*f585d8a3SJacky Wang             "import javax.inject.Inject;",
392*f585d8a3SJacky Wang             "import javax.inject.Provider;",
393*f585d8a3SJacky Wang             "",
394*f585d8a3SJacky Wang             "class MixedMemberInjection {",
395*f585d8a3SJacky Wang             "  @Inject String string;",
396*f585d8a3SJacky Wang             "  @Inject void setString(String s) {}",
397*f585d8a3SJacky Wang             "  @Inject Object object;",
398*f585d8a3SJacky Wang             "  @Inject void setObject(Object o) {}",
399*f585d8a3SJacky Wang             "}");
400*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
401*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
402*f585d8a3SJacky Wang         .compile(
403*f585d8a3SJacky Wang             subject -> {
404*f585d8a3SJacky Wang               subject.hasErrorCount(0);
405*f585d8a3SJacky Wang               subject.generatedSource(
406*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/MixedMemberInjection_MembersInjector"));
407*f585d8a3SJacky Wang             });
408*f585d8a3SJacky Wang   }
409*f585d8a3SJacky Wang 
injectConstructorAndMembersInjection()410*f585d8a3SJacky Wang   @Test public void injectConstructorAndMembersInjection() {
411*f585d8a3SJacky Wang     Source file =
412*f585d8a3SJacky Wang         CompilerTests.javaSource(
413*f585d8a3SJacky Wang             "test.AllInjections",
414*f585d8a3SJacky Wang             "package test;",
415*f585d8a3SJacky Wang             "",
416*f585d8a3SJacky Wang             "import javax.inject.Inject;",
417*f585d8a3SJacky Wang             "",
418*f585d8a3SJacky Wang             "class AllInjections {",
419*f585d8a3SJacky Wang             "  @Inject String s;",
420*f585d8a3SJacky Wang             "  @Inject AllInjections(String s) {}",
421*f585d8a3SJacky Wang             "  @Inject void s(String s) {}",
422*f585d8a3SJacky Wang             "}");
423*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
424*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
425*f585d8a3SJacky Wang         .compile(
426*f585d8a3SJacky Wang             subject -> {
427*f585d8a3SJacky Wang               subject.hasErrorCount(0);
428*f585d8a3SJacky Wang               subject.generatedSource(
429*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/AllInjections_MembersInjector"));
430*f585d8a3SJacky Wang             });
431*f585d8a3SJacky Wang   }
432*f585d8a3SJacky Wang 
supertypeMembersInjection()433*f585d8a3SJacky Wang   @Test public void supertypeMembersInjection() {
434*f585d8a3SJacky Wang     Source aFile =
435*f585d8a3SJacky Wang         CompilerTests.javaSource(
436*f585d8a3SJacky Wang             "test.A",
437*f585d8a3SJacky Wang             "package test;",
438*f585d8a3SJacky Wang             "",
439*f585d8a3SJacky Wang             "class A {}");
440*f585d8a3SJacky Wang     Source bFile =
441*f585d8a3SJacky Wang         CompilerTests.javaSource(
442*f585d8a3SJacky Wang             "test.B",
443*f585d8a3SJacky Wang             "package test;",
444*f585d8a3SJacky Wang             "",
445*f585d8a3SJacky Wang             "import javax.inject.Inject;",
446*f585d8a3SJacky Wang             "",
447*f585d8a3SJacky Wang             "class B extends A {",
448*f585d8a3SJacky Wang             "  @Inject String s;",
449*f585d8a3SJacky Wang             "}");
450*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(aFile, bFile)
451*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
452*f585d8a3SJacky Wang         .compile(
453*f585d8a3SJacky Wang             subject -> {
454*f585d8a3SJacky Wang               subject.hasErrorCount(0);
455*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/B_MembersInjector"));
456*f585d8a3SJacky Wang             });
457*f585d8a3SJacky Wang   }
458*f585d8a3SJacky Wang 
459*f585d8a3SJacky Wang   @Test
simpleComponentWithNesting()460*f585d8a3SJacky Wang   public void simpleComponentWithNesting() {
461*f585d8a3SJacky Wang     Source nestedTypesFile =
462*f585d8a3SJacky Wang         CompilerTests.javaSource(
463*f585d8a3SJacky Wang             "test.OuterType",
464*f585d8a3SJacky Wang             "package test;",
465*f585d8a3SJacky Wang             "",
466*f585d8a3SJacky Wang             "import dagger.Component;",
467*f585d8a3SJacky Wang             "import javax.inject.Inject;",
468*f585d8a3SJacky Wang             "",
469*f585d8a3SJacky Wang             "final class OuterType {",
470*f585d8a3SJacky Wang             "  static class A {",
471*f585d8a3SJacky Wang             "    @Inject A() {}",
472*f585d8a3SJacky Wang             "  }",
473*f585d8a3SJacky Wang             "  static class B {",
474*f585d8a3SJacky Wang             "    @Inject A a;",
475*f585d8a3SJacky Wang             "  }",
476*f585d8a3SJacky Wang             "  @Component interface SimpleComponent {",
477*f585d8a3SJacky Wang             "    A a();",
478*f585d8a3SJacky Wang             "    void inject(B b);",
479*f585d8a3SJacky Wang             "  }",
480*f585d8a3SJacky Wang             "}");
481*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(nestedTypesFile)
482*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
483*f585d8a3SJacky Wang         .compile(
484*f585d8a3SJacky Wang             subject -> {
485*f585d8a3SJacky Wang               subject.hasErrorCount(0);
486*f585d8a3SJacky Wang               subject.generatedSource(
487*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/OuterType_B_MembersInjector"));
488*f585d8a3SJacky Wang             });
489*f585d8a3SJacky Wang   }
490*f585d8a3SJacky Wang 
491*f585d8a3SJacky Wang   @Test
componentWithNestingAndGeneratedType()492*f585d8a3SJacky Wang   public void componentWithNestingAndGeneratedType() {
493*f585d8a3SJacky Wang     Source nestedTypesFile =
494*f585d8a3SJacky Wang         CompilerTests.javaSource(
495*f585d8a3SJacky Wang             "test.OuterType",
496*f585d8a3SJacky Wang             "package test;",
497*f585d8a3SJacky Wang             "",
498*f585d8a3SJacky Wang             "import dagger.Component;",
499*f585d8a3SJacky Wang             "import javax.inject.Inject;",
500*f585d8a3SJacky Wang             "",
501*f585d8a3SJacky Wang             "final class OuterType {",
502*f585d8a3SJacky Wang             "  @Inject GeneratedInjectType generated;",
503*f585d8a3SJacky Wang             "  static class A {",
504*f585d8a3SJacky Wang             "    @Inject A() {}",
505*f585d8a3SJacky Wang             "  }",
506*f585d8a3SJacky Wang             "  static class B {",
507*f585d8a3SJacky Wang             "    @Inject A a;",
508*f585d8a3SJacky Wang             "  }",
509*f585d8a3SJacky Wang             "  @Component interface SimpleComponent {",
510*f585d8a3SJacky Wang             "    A a();",
511*f585d8a3SJacky Wang             "    void inject(B b);",
512*f585d8a3SJacky Wang             "  }",
513*f585d8a3SJacky Wang             "}");
514*f585d8a3SJacky Wang     TypeSpec generatedInjectType =
515*f585d8a3SJacky Wang         TypeSpec.classBuilder("GeneratedInjectType")
516*f585d8a3SJacky Wang             .addMethod(
517*f585d8a3SJacky Wang                 MethodSpec.constructorBuilder()
518*f585d8a3SJacky Wang                     .addAnnotation(TypeNames.INJECT_JAVAX)
519*f585d8a3SJacky Wang                     .build())
520*f585d8a3SJacky Wang             .build();
521*f585d8a3SJacky Wang 
522*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(nestedTypesFile)
523*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
524*f585d8a3SJacky Wang         .withProcessingSteps(() -> new GeneratingProcessingStep("test", generatedInjectType))
525*f585d8a3SJacky Wang         .compile(
526*f585d8a3SJacky Wang             subject -> {
527*f585d8a3SJacky Wang               subject.hasErrorCount(0);
528*f585d8a3SJacky Wang               subject.generatedSource(
529*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/OuterType_B_MembersInjector"));
530*f585d8a3SJacky Wang             });
531*f585d8a3SJacky Wang   }
532*f585d8a3SJacky Wang 
533*f585d8a3SJacky Wang   @Test
lowerCaseNamedMembersInjector_forLowerCaseType()534*f585d8a3SJacky Wang   public void lowerCaseNamedMembersInjector_forLowerCaseType() {
535*f585d8a3SJacky Wang     Source foo =
536*f585d8a3SJacky Wang         CompilerTests.javaSource(
537*f585d8a3SJacky Wang             "test.foo",
538*f585d8a3SJacky Wang             "package test;",
539*f585d8a3SJacky Wang             "",
540*f585d8a3SJacky Wang             "import javax.inject.Inject;",
541*f585d8a3SJacky Wang             "",
542*f585d8a3SJacky Wang             "class foo {",
543*f585d8a3SJacky Wang             "  @Inject String string;",
544*f585d8a3SJacky Wang             "}");
545*f585d8a3SJacky Wang     Source fooModule =
546*f585d8a3SJacky Wang         CompilerTests.javaSource(
547*f585d8a3SJacky Wang             "test.fooModule",
548*f585d8a3SJacky Wang             "package test;",
549*f585d8a3SJacky Wang             "",
550*f585d8a3SJacky Wang             "import dagger.Module;",
551*f585d8a3SJacky Wang             "import dagger.Provides;",
552*f585d8a3SJacky Wang             "",
553*f585d8a3SJacky Wang             "@Module",
554*f585d8a3SJacky Wang             "class fooModule {",
555*f585d8a3SJacky Wang             "  @Provides String string() { return \"foo\"; }",
556*f585d8a3SJacky Wang             "}");
557*f585d8a3SJacky Wang     Source fooComponent =
558*f585d8a3SJacky Wang         CompilerTests.javaSource(
559*f585d8a3SJacky Wang             "test.fooComponent",
560*f585d8a3SJacky Wang             "package test;",
561*f585d8a3SJacky Wang             "",
562*f585d8a3SJacky Wang             "import dagger.Component;",
563*f585d8a3SJacky Wang             "",
564*f585d8a3SJacky Wang             "@Component(modules = fooModule.class)",
565*f585d8a3SJacky Wang             "interface fooComponent {",
566*f585d8a3SJacky Wang             "  void inject(foo target);",
567*f585d8a3SJacky Wang             "}");
568*f585d8a3SJacky Wang 
569*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(foo, fooModule, fooComponent)
570*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
571*f585d8a3SJacky Wang         .compile(
572*f585d8a3SJacky Wang             subject -> {
573*f585d8a3SJacky Wang               subject.hasErrorCount(0);
574*f585d8a3SJacky Wang               subject.generatedSourceFileWithPath("test/foo_MembersInjector.java");
575*f585d8a3SJacky Wang             });
576*f585d8a3SJacky Wang   }
577*f585d8a3SJacky Wang 
578*f585d8a3SJacky Wang   @Test
fieldInjectionForShadowedMember()579*f585d8a3SJacky Wang   public void fieldInjectionForShadowedMember() {
580*f585d8a3SJacky Wang     Source foo =
581*f585d8a3SJacky Wang         CompilerTests.javaSource(
582*f585d8a3SJacky Wang             "test.Foo",
583*f585d8a3SJacky Wang             "package test;",
584*f585d8a3SJacky Wang             "",
585*f585d8a3SJacky Wang             "import javax.inject.Inject;",
586*f585d8a3SJacky Wang             "",
587*f585d8a3SJacky Wang             "class Foo {",
588*f585d8a3SJacky Wang             "  @Inject Foo() {}",
589*f585d8a3SJacky Wang             "}");
590*f585d8a3SJacky Wang     Source bar =
591*f585d8a3SJacky Wang         CompilerTests.javaSource(
592*f585d8a3SJacky Wang             "test.Bar",
593*f585d8a3SJacky Wang             "package test;",
594*f585d8a3SJacky Wang             "",
595*f585d8a3SJacky Wang             "import javax.inject.Inject;",
596*f585d8a3SJacky Wang             "",
597*f585d8a3SJacky Wang             "class Bar {",
598*f585d8a3SJacky Wang             "  @Inject Bar() {}",
599*f585d8a3SJacky Wang             "}");
600*f585d8a3SJacky Wang     Source parent =
601*f585d8a3SJacky Wang         CompilerTests.javaSource(
602*f585d8a3SJacky Wang             "test.Parent",
603*f585d8a3SJacky Wang             "package test;",
604*f585d8a3SJacky Wang             "",
605*f585d8a3SJacky Wang             "import javax.inject.Inject;",
606*f585d8a3SJacky Wang             "",
607*f585d8a3SJacky Wang             "class Parent { ",
608*f585d8a3SJacky Wang             "  @Inject Foo object;",
609*f585d8a3SJacky Wang             "}");
610*f585d8a3SJacky Wang     Source child =
611*f585d8a3SJacky Wang         CompilerTests.javaSource(
612*f585d8a3SJacky Wang             "test.Child",
613*f585d8a3SJacky Wang             "package test;",
614*f585d8a3SJacky Wang             "",
615*f585d8a3SJacky Wang             "import javax.inject.Inject;",
616*f585d8a3SJacky Wang             "",
617*f585d8a3SJacky Wang             "class Child extends Parent { ",
618*f585d8a3SJacky Wang             "  @Inject Bar object;",
619*f585d8a3SJacky Wang             "}");
620*f585d8a3SJacky Wang     Source component =
621*f585d8a3SJacky Wang         CompilerTests.javaSource(
622*f585d8a3SJacky Wang             "test.C",
623*f585d8a3SJacky Wang             "package test;",
624*f585d8a3SJacky Wang             "",
625*f585d8a3SJacky Wang             "import dagger.Component;",
626*f585d8a3SJacky Wang             "",
627*f585d8a3SJacky Wang             "@Component",
628*f585d8a3SJacky Wang             "interface C { ",
629*f585d8a3SJacky Wang             "  void inject(Child child);",
630*f585d8a3SJacky Wang             "}");
631*f585d8a3SJacky Wang 
632*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(foo, bar, parent, child, component)
633*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
634*f585d8a3SJacky Wang         .compile(
635*f585d8a3SJacky Wang             subject -> {
636*f585d8a3SJacky Wang               subject.hasErrorCount(0);
637*f585d8a3SJacky Wang               subject.generatedSource(
638*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/Child_MembersInjector"));
639*f585d8a3SJacky Wang             });
640*f585d8a3SJacky Wang   }
641*f585d8a3SJacky Wang 
privateNestedClassError()642*f585d8a3SJacky Wang   @Test public void privateNestedClassError() {
643*f585d8a3SJacky Wang     Source file =
644*f585d8a3SJacky Wang         CompilerTests.javaSource(
645*f585d8a3SJacky Wang             "test.OuterClass",
646*f585d8a3SJacky Wang             "package test;",
647*f585d8a3SJacky Wang             "",
648*f585d8a3SJacky Wang             "import javax.inject.Inject;",
649*f585d8a3SJacky Wang             "",
650*f585d8a3SJacky Wang             "final class OuterClass {",
651*f585d8a3SJacky Wang             "  private static final class InnerClass {",
652*f585d8a3SJacky Wang             "    @Inject int field;",
653*f585d8a3SJacky Wang             "  }",
654*f585d8a3SJacky Wang             "}");
655*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
656*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
657*f585d8a3SJacky Wang         .compile(
658*f585d8a3SJacky Wang             subject -> {
659*f585d8a3SJacky Wang               subject.hasErrorCount(1);
660*f585d8a3SJacky Wang               subject.hasErrorContaining("Dagger does not support injection into private classes")
661*f585d8a3SJacky Wang                   .onSource(file)
662*f585d8a3SJacky Wang                   .onLine(6);
663*f585d8a3SJacky Wang             });
664*f585d8a3SJacky Wang   }
665*f585d8a3SJacky Wang 
privateNestedClassWarning()666*f585d8a3SJacky Wang   @Test public void privateNestedClassWarning() {
667*f585d8a3SJacky Wang     Source file =
668*f585d8a3SJacky Wang         CompilerTests.javaSource(
669*f585d8a3SJacky Wang             "test.OuterClass",
670*f585d8a3SJacky Wang             "package test;",
671*f585d8a3SJacky Wang             "",
672*f585d8a3SJacky Wang             "import javax.inject.Inject;",
673*f585d8a3SJacky Wang             "",
674*f585d8a3SJacky Wang             "final class OuterClass {",
675*f585d8a3SJacky Wang             "  private static final class InnerClass {",
676*f585d8a3SJacky Wang             "    @Inject int field;",
677*f585d8a3SJacky Wang             "  }",
678*f585d8a3SJacky Wang             "}");
679*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
680*f585d8a3SJacky Wang         .withProcessingOptions(
681*f585d8a3SJacky Wang             ImmutableMap.<String, String>builder()
682*f585d8a3SJacky Wang                 .putAll(compilerMode.processorOptions())
683*f585d8a3SJacky Wang                 .put("dagger.privateMemberValidation", "WARNING")
684*f585d8a3SJacky Wang                 .buildOrThrow())
685*f585d8a3SJacky Wang         .compile(
686*f585d8a3SJacky Wang             subject -> {
687*f585d8a3SJacky Wang               subject.hasErrorCount(0);
688*f585d8a3SJacky Wang               subject.hasWarningCount(1);
689*f585d8a3SJacky Wang               subject.hasWarningContaining("Dagger does not support injection into private classes")
690*f585d8a3SJacky Wang                   .onSource(file)
691*f585d8a3SJacky Wang                   .onLine(6);
692*f585d8a3SJacky Wang             });
693*f585d8a3SJacky Wang   }
694*f585d8a3SJacky Wang 
privateSuperclassIsOkIfNotInjectedInto()695*f585d8a3SJacky Wang   @Test public void privateSuperclassIsOkIfNotInjectedInto() {
696*f585d8a3SJacky Wang     Source file =
697*f585d8a3SJacky Wang         CompilerTests.javaSource(
698*f585d8a3SJacky Wang             "test.OuterClass",
699*f585d8a3SJacky Wang             "package test;",
700*f585d8a3SJacky Wang             "",
701*f585d8a3SJacky Wang             "import javax.inject.Inject;",
702*f585d8a3SJacky Wang             "",
703*f585d8a3SJacky Wang             "final class OuterClass {",
704*f585d8a3SJacky Wang             "  private static class BaseClass {}",
705*f585d8a3SJacky Wang             "",
706*f585d8a3SJacky Wang             "  static final class DerivedClass extends BaseClass {",
707*f585d8a3SJacky Wang             "    @Inject int field;",
708*f585d8a3SJacky Wang             "  }",
709*f585d8a3SJacky Wang             "}");
710*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
711*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
712*f585d8a3SJacky Wang         .compile(subject -> subject.hasErrorCount(0));
713*f585d8a3SJacky Wang   }
714*f585d8a3SJacky Wang 
715*f585d8a3SJacky Wang   @Test
rawFrameworkTypeField()716*f585d8a3SJacky Wang   public void rawFrameworkTypeField() {
717*f585d8a3SJacky Wang     Source file =
718*f585d8a3SJacky Wang         CompilerTests.javaSource(
719*f585d8a3SJacky Wang             "test.RawFrameworkTypes",
720*f585d8a3SJacky Wang             "package test;",
721*f585d8a3SJacky Wang             "",
722*f585d8a3SJacky Wang             "import javax.inject.Inject;",
723*f585d8a3SJacky Wang             "import javax.inject.Provider;",
724*f585d8a3SJacky Wang             "",
725*f585d8a3SJacky Wang             "class RawProviderField {",
726*f585d8a3SJacky Wang             "  @Inject",
727*f585d8a3SJacky Wang             "  Provider fieldWithRawProvider;",
728*f585d8a3SJacky Wang             "}");
729*f585d8a3SJacky Wang 
730*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
731*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
732*f585d8a3SJacky Wang         .compile(
733*f585d8a3SJacky Wang             subject -> {
734*f585d8a3SJacky Wang               subject.hasErrorCount(1);
735*f585d8a3SJacky Wang               subject.hasErrorContaining(
736*f585d8a3SJacky Wang                       "Dagger does not support injecting raw type: javax.inject.Provider")
737*f585d8a3SJacky Wang                   .onSource(file)
738*f585d8a3SJacky Wang                   .onLineContaining("Provider fieldWithRawProvider");
739*f585d8a3SJacky Wang             });
740*f585d8a3SJacky Wang   }
741*f585d8a3SJacky Wang 
742*f585d8a3SJacky Wang   @Test
throwExceptionInjectedMethod()743*f585d8a3SJacky Wang   public void throwExceptionInjectedMethod() {
744*f585d8a3SJacky Wang     Source file =
745*f585d8a3SJacky Wang         CompilerTests.javaSource(
746*f585d8a3SJacky Wang             "test.",
747*f585d8a3SJacky Wang             "package test;",
748*f585d8a3SJacky Wang             "",
749*f585d8a3SJacky Wang             "import javax.inject.Inject;",
750*f585d8a3SJacky Wang             "class SomeClass {",
751*f585d8a3SJacky Wang             "@Inject void inject() throws Exception {}",
752*f585d8a3SJacky Wang             "}");
753*f585d8a3SJacky Wang 
754*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
755*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
756*f585d8a3SJacky Wang         .compile(
757*f585d8a3SJacky Wang             subject -> {
758*f585d8a3SJacky Wang               subject.hasErrorCount(1);
759*f585d8a3SJacky Wang               subject.hasErrorContaining(
760*f585d8a3SJacky Wang                       "Methods with @Inject may not throw checked exceptions. "
761*f585d8a3SJacky Wang                           + "Please wrap your exceptions in a RuntimeException instead.")
762*f585d8a3SJacky Wang                   .onSource(file)
763*f585d8a3SJacky Wang                   .onLineContaining("throws Exception");
764*f585d8a3SJacky Wang             });
765*f585d8a3SJacky Wang   }
766*f585d8a3SJacky Wang 
767*f585d8a3SJacky Wang   @Test
rawFrameworkMethodTypeParameter()768*f585d8a3SJacky Wang   public void rawFrameworkMethodTypeParameter() {
769*f585d8a3SJacky Wang     Source file =
770*f585d8a3SJacky Wang         CompilerTests.javaSource(
771*f585d8a3SJacky Wang             "test.RawFrameworkTypes",
772*f585d8a3SJacky Wang             "package test;",
773*f585d8a3SJacky Wang             "",
774*f585d8a3SJacky Wang             "import javax.inject.Inject;",
775*f585d8a3SJacky Wang             "import javax.inject.Provider;",
776*f585d8a3SJacky Wang             "",
777*f585d8a3SJacky Wang             "class RawProviderParameter {",
778*f585d8a3SJacky Wang             "  @Inject",
779*f585d8a3SJacky Wang             "  void methodInjection(",
780*f585d8a3SJacky Wang             "      Provider rawProviderParameter) {}",
781*f585d8a3SJacky Wang             "}");
782*f585d8a3SJacky Wang 
783*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
784*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
785*f585d8a3SJacky Wang         .compile(
786*f585d8a3SJacky Wang             subject -> {
787*f585d8a3SJacky Wang               subject.hasErrorCount(1);
788*f585d8a3SJacky Wang               subject.hasErrorContaining(
789*f585d8a3SJacky Wang                       "Dagger does not support injecting raw type: javax.inject.Provider")
790*f585d8a3SJacky Wang                   .onSource(file)
791*f585d8a3SJacky Wang                   .onLineContaining("Provider rawProviderParameter");
792*f585d8a3SJacky Wang             });
793*f585d8a3SJacky Wang   }
794*f585d8a3SJacky Wang 
795*f585d8a3SJacky Wang   @Test
rawFrameworkConstructorTypeParameter()796*f585d8a3SJacky Wang   public void rawFrameworkConstructorTypeParameter() {
797*f585d8a3SJacky Wang     Source file =
798*f585d8a3SJacky Wang         CompilerTests.javaSource(
799*f585d8a3SJacky Wang             "test.RawFrameworkTypes",
800*f585d8a3SJacky Wang             "package test;",
801*f585d8a3SJacky Wang             "",
802*f585d8a3SJacky Wang             "import dagger.Component;",
803*f585d8a3SJacky Wang             "import javax.inject.Inject;",
804*f585d8a3SJacky Wang             "import javax.inject.Provider;",
805*f585d8a3SJacky Wang             "",
806*f585d8a3SJacky Wang             "class RawProviderParameter {",
807*f585d8a3SJacky Wang             "  @Inject",
808*f585d8a3SJacky Wang             "  RawProviderParameter(",
809*f585d8a3SJacky Wang             "      Provider rawProviderParameter) {}",
810*f585d8a3SJacky Wang             "}");
811*f585d8a3SJacky Wang 
812*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(file)
813*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
814*f585d8a3SJacky Wang         .compile(
815*f585d8a3SJacky Wang             subject -> {
816*f585d8a3SJacky Wang               subject.hasErrorCount(1);
817*f585d8a3SJacky Wang               subject.hasErrorContaining(
818*f585d8a3SJacky Wang                       "Dagger does not support injecting raw type: javax.inject.Provider")
819*f585d8a3SJacky Wang                   .onSource(file)
820*f585d8a3SJacky Wang                   .onLineContaining("Provider rawProviderParameter");
821*f585d8a3SJacky Wang             });
822*f585d8a3SJacky Wang   }
823*f585d8a3SJacky Wang 
824*f585d8a3SJacky Wang   @Test
injectsPrimitive()825*f585d8a3SJacky Wang   public void injectsPrimitive() throws Exception {
826*f585d8a3SJacky Wang     Source injectedType =
827*f585d8a3SJacky Wang         CompilerTests.javaSource(
828*f585d8a3SJacky Wang             "test.InjectedType",
829*f585d8a3SJacky Wang             "package test;",
830*f585d8a3SJacky Wang             "",
831*f585d8a3SJacky Wang             "import javax.inject.Inject;",
832*f585d8a3SJacky Wang             "",
833*f585d8a3SJacky Wang             "class InjectedType {",
834*f585d8a3SJacky Wang             "  @Inject InjectedType() {}",
835*f585d8a3SJacky Wang             "",
836*f585d8a3SJacky Wang             "  @Inject int primitiveInt;",
837*f585d8a3SJacky Wang             "  @Inject Integer boxedInt;",
838*f585d8a3SJacky Wang             "}");
839*f585d8a3SJacky Wang 
840*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(injectedType)
841*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
842*f585d8a3SJacky Wang         .compile(
843*f585d8a3SJacky Wang             subject -> {
844*f585d8a3SJacky Wang               subject.hasErrorCount(0);
845*f585d8a3SJacky Wang               subject.generatedSource(
846*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/InjectedType_MembersInjector"));
847*f585d8a3SJacky Wang               subject.generatedSource(
848*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/InjectedType_Factory"));
849*f585d8a3SJacky Wang             });
850*f585d8a3SJacky Wang   }
851*f585d8a3SJacky Wang 
852*f585d8a3SJacky Wang   @Test
accessibility()853*f585d8a3SJacky Wang   public void accessibility() throws Exception {
854*f585d8a3SJacky Wang     Source foo =
855*f585d8a3SJacky Wang         CompilerTests.javaSource(
856*f585d8a3SJacky Wang             "other.Foo",
857*f585d8a3SJacky Wang             "package other;",
858*f585d8a3SJacky Wang             "",
859*f585d8a3SJacky Wang             "import javax.inject.Inject;",
860*f585d8a3SJacky Wang             "",
861*f585d8a3SJacky Wang             "class Foo {",
862*f585d8a3SJacky Wang             "  @Inject Foo() {}",
863*f585d8a3SJacky Wang             "}");
864*f585d8a3SJacky Wang     Source inaccessible =
865*f585d8a3SJacky Wang         CompilerTests.javaSource(
866*f585d8a3SJacky Wang             "other.Inaccessible",
867*f585d8a3SJacky Wang             "package other;",
868*f585d8a3SJacky Wang             "",
869*f585d8a3SJacky Wang             "import javax.inject.Inject;",
870*f585d8a3SJacky Wang             "",
871*f585d8a3SJacky Wang             "class Inaccessible {",
872*f585d8a3SJacky Wang             "  @Inject Inaccessible() {}",
873*f585d8a3SJacky Wang             "  @Inject Foo foo;",
874*f585d8a3SJacky Wang             "  @Inject void method(Foo foo) {}",
875*f585d8a3SJacky Wang             "}");
876*f585d8a3SJacky Wang     Source usesInaccessible =
877*f585d8a3SJacky Wang         CompilerTests.javaSource(
878*f585d8a3SJacky Wang             "other.UsesInaccessible",
879*f585d8a3SJacky Wang             "package other;",
880*f585d8a3SJacky Wang             "",
881*f585d8a3SJacky Wang             "import javax.inject.Inject;",
882*f585d8a3SJacky Wang             "",
883*f585d8a3SJacky Wang             "public class UsesInaccessible {",
884*f585d8a3SJacky Wang             "  @Inject UsesInaccessible(Inaccessible inaccessible) {}",
885*f585d8a3SJacky Wang             "}");
886*f585d8a3SJacky Wang     Source component =
887*f585d8a3SJacky Wang         CompilerTests.javaSource(
888*f585d8a3SJacky Wang             "test.TestComponent",
889*f585d8a3SJacky Wang             "package test;",
890*f585d8a3SJacky Wang             "",
891*f585d8a3SJacky Wang             "import dagger.Component;",
892*f585d8a3SJacky Wang             "import other.UsesInaccessible;",
893*f585d8a3SJacky Wang             "",
894*f585d8a3SJacky Wang             "@Component",
895*f585d8a3SJacky Wang             "interface TestComponent {",
896*f585d8a3SJacky Wang             "  UsesInaccessible usesInaccessible();",
897*f585d8a3SJacky Wang             "}");
898*f585d8a3SJacky Wang 
899*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(foo, inaccessible, usesInaccessible, component)
900*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
901*f585d8a3SJacky Wang         .compile(
902*f585d8a3SJacky Wang             subject -> {
903*f585d8a3SJacky Wang               subject.hasErrorCount(0);
904*f585d8a3SJacky Wang               subject.generatedSource(
905*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("other/Inaccessible_MembersInjector"));
906*f585d8a3SJacky Wang               subject.generatedSource(
907*f585d8a3SJacky Wang                   goldenFileRule.goldenSource("test/DaggerTestComponent"));
908*f585d8a3SJacky Wang             });
909*f585d8a3SJacky Wang   }
910*f585d8a3SJacky Wang 
911*f585d8a3SJacky Wang   @Test
accessibleRawType_ofInaccessibleType()912*f585d8a3SJacky Wang   public void accessibleRawType_ofInaccessibleType() throws Exception {
913*f585d8a3SJacky Wang     Source inaccessible =
914*f585d8a3SJacky Wang         CompilerTests.javaSource(
915*f585d8a3SJacky Wang             "other.Inaccessible",
916*f585d8a3SJacky Wang             "package other;",
917*f585d8a3SJacky Wang             "",
918*f585d8a3SJacky Wang             "class Inaccessible {}");
919*f585d8a3SJacky Wang     Source inaccessiblesModule =
920*f585d8a3SJacky Wang         CompilerTests.javaSource(
921*f585d8a3SJacky Wang             "other.InaccessiblesModule",
922*f585d8a3SJacky Wang             "package other;",
923*f585d8a3SJacky Wang             "",
924*f585d8a3SJacky Wang             "import dagger.Module;",
925*f585d8a3SJacky Wang             "import dagger.Provides;",
926*f585d8a3SJacky Wang             "import java.util.ArrayList;",
927*f585d8a3SJacky Wang             "import java.util.List;",
928*f585d8a3SJacky Wang             "import javax.inject.Provider;",
929*f585d8a3SJacky Wang             "import javax.inject.Singleton;",
930*f585d8a3SJacky Wang             "",
931*f585d8a3SJacky Wang             "@Module",
932*f585d8a3SJacky Wang             "public class InaccessiblesModule {",
933*f585d8a3SJacky Wang             // force Provider initialization
934*f585d8a3SJacky Wang             "  @Provides @Singleton static List<Inaccessible> inaccessibles() {",
935*f585d8a3SJacky Wang             "    return new ArrayList<>();",
936*f585d8a3SJacky Wang             "  }",
937*f585d8a3SJacky Wang             "}");
938*f585d8a3SJacky Wang     Source usesInaccessibles =
939*f585d8a3SJacky Wang         CompilerTests.javaSource(
940*f585d8a3SJacky Wang             "other.UsesInaccessibles",
941*f585d8a3SJacky Wang             "package other;",
942*f585d8a3SJacky Wang             "",
943*f585d8a3SJacky Wang             "import java.util.List;",
944*f585d8a3SJacky Wang             "import javax.inject.Inject;",
945*f585d8a3SJacky Wang             "",
946*f585d8a3SJacky Wang             "public class UsesInaccessibles {",
947*f585d8a3SJacky Wang             "  @Inject UsesInaccessibles() {}",
948*f585d8a3SJacky Wang             "  @Inject List<Inaccessible> inaccessibles;",
949*f585d8a3SJacky Wang             "}");
950*f585d8a3SJacky Wang     Source component =
951*f585d8a3SJacky Wang         CompilerTests.javaSource(
952*f585d8a3SJacky Wang             "test.TestComponent",
953*f585d8a3SJacky Wang             "package test;",
954*f585d8a3SJacky Wang             "",
955*f585d8a3SJacky Wang             "import dagger.Component;",
956*f585d8a3SJacky Wang             "import javax.inject.Singleton;",
957*f585d8a3SJacky Wang             "import other.UsesInaccessibles;",
958*f585d8a3SJacky Wang             "",
959*f585d8a3SJacky Wang             "@Singleton",
960*f585d8a3SJacky Wang             "@Component(modules = other.InaccessiblesModule.class)",
961*f585d8a3SJacky Wang             "interface TestComponent {",
962*f585d8a3SJacky Wang             "  UsesInaccessibles usesInaccessibles();",
963*f585d8a3SJacky Wang             "}");
964*f585d8a3SJacky Wang 
965*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(inaccessible, inaccessiblesModule, usesInaccessibles, component)
966*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
967*f585d8a3SJacky Wang         .compile(
968*f585d8a3SJacky Wang             subject -> {
969*f585d8a3SJacky Wang               subject.hasErrorCount(0);
970*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
971*f585d8a3SJacky Wang             });
972*f585d8a3SJacky Wang   }
973*f585d8a3SJacky Wang 
974*f585d8a3SJacky Wang   @Test
publicSupertypeHiddenSubtype()975*f585d8a3SJacky Wang   public void publicSupertypeHiddenSubtype() throws Exception {
976*f585d8a3SJacky Wang     Source foo =
977*f585d8a3SJacky Wang         CompilerTests.javaSource(
978*f585d8a3SJacky Wang             "other.Foo",
979*f585d8a3SJacky Wang             "package other;",
980*f585d8a3SJacky Wang             "",
981*f585d8a3SJacky Wang             "import javax.inject.Inject;",
982*f585d8a3SJacky Wang             "",
983*f585d8a3SJacky Wang             "class Foo {",
984*f585d8a3SJacky Wang             "  @Inject Foo() {}",
985*f585d8a3SJacky Wang             "}");
986*f585d8a3SJacky Wang     Source supertype =
987*f585d8a3SJacky Wang         CompilerTests.javaSource(
988*f585d8a3SJacky Wang             "other.Supertype",
989*f585d8a3SJacky Wang             "package other;",
990*f585d8a3SJacky Wang             "",
991*f585d8a3SJacky Wang             "import javax.inject.Inject;",
992*f585d8a3SJacky Wang             "",
993*f585d8a3SJacky Wang             "public class Supertype<T> {",
994*f585d8a3SJacky Wang             "  @Inject T t;",
995*f585d8a3SJacky Wang             "}");
996*f585d8a3SJacky Wang     Source subtype =
997*f585d8a3SJacky Wang         CompilerTests.javaSource(
998*f585d8a3SJacky Wang             "other.Subtype",
999*f585d8a3SJacky Wang             "package other;",
1000*f585d8a3SJacky Wang             "",
1001*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1002*f585d8a3SJacky Wang             "",
1003*f585d8a3SJacky Wang             "class Subtype extends Supertype<Foo> {",
1004*f585d8a3SJacky Wang             "  @Inject Subtype() {}",
1005*f585d8a3SJacky Wang             "}");
1006*f585d8a3SJacky Wang     Source injectsSubtype =
1007*f585d8a3SJacky Wang         CompilerTests.javaSource(
1008*f585d8a3SJacky Wang             "other.InjectsSubtype",
1009*f585d8a3SJacky Wang             "package other;",
1010*f585d8a3SJacky Wang             "",
1011*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1012*f585d8a3SJacky Wang             "",
1013*f585d8a3SJacky Wang             "public class InjectsSubtype {",
1014*f585d8a3SJacky Wang             "  @Inject InjectsSubtype(Subtype s) {}",
1015*f585d8a3SJacky Wang             "}");
1016*f585d8a3SJacky Wang     Source component =
1017*f585d8a3SJacky Wang         CompilerTests.javaSource(
1018*f585d8a3SJacky Wang             "test.TestComponent",
1019*f585d8a3SJacky Wang             "package test;",
1020*f585d8a3SJacky Wang             "",
1021*f585d8a3SJacky Wang             "import dagger.Component;",
1022*f585d8a3SJacky Wang             "",
1023*f585d8a3SJacky Wang             "@Component",
1024*f585d8a3SJacky Wang             "interface TestComponent {",
1025*f585d8a3SJacky Wang             "  other.InjectsSubtype injectsSubtype();",
1026*f585d8a3SJacky Wang             "}");
1027*f585d8a3SJacky Wang 
1028*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(foo, supertype, subtype, injectsSubtype, component)
1029*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
1030*f585d8a3SJacky Wang         .compile(
1031*f585d8a3SJacky Wang             subject -> {
1032*f585d8a3SJacky Wang               subject.hasErrorCount(0);
1033*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
1034*f585d8a3SJacky Wang             });
1035*f585d8a3SJacky Wang   }
1036*f585d8a3SJacky Wang 
1037*f585d8a3SJacky Wang   // Shows that we shouldn't create a members injector for a type that doesn't have
1038*f585d8a3SJacky Wang   // @Inject fields or @Inject constructor even if it extends and is extended by types that do.
1039*f585d8a3SJacky Wang   @Test
middleClassNoFieldInjection()1040*f585d8a3SJacky Wang   public void middleClassNoFieldInjection() throws Exception {
1041*f585d8a3SJacky Wang     Source classA =
1042*f585d8a3SJacky Wang         CompilerTests.javaSource(
1043*f585d8a3SJacky Wang             "test.A",
1044*f585d8a3SJacky Wang             "package test;",
1045*f585d8a3SJacky Wang             "",
1046*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1047*f585d8a3SJacky Wang             "",
1048*f585d8a3SJacky Wang             "class A extends B {",
1049*f585d8a3SJacky Wang             "  @Inject String valueA;",
1050*f585d8a3SJacky Wang             "}");
1051*f585d8a3SJacky Wang     Source classB =
1052*f585d8a3SJacky Wang         CompilerTests.javaSource(
1053*f585d8a3SJacky Wang             "test.B",
1054*f585d8a3SJacky Wang             "package test;",
1055*f585d8a3SJacky Wang             "",
1056*f585d8a3SJacky Wang             "class B extends C {",
1057*f585d8a3SJacky Wang             "}");
1058*f585d8a3SJacky Wang     Source classC =
1059*f585d8a3SJacky Wang         CompilerTests.javaSource(
1060*f585d8a3SJacky Wang             "test.C",
1061*f585d8a3SJacky Wang             "package test;",
1062*f585d8a3SJacky Wang             "",
1063*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1064*f585d8a3SJacky Wang             "",
1065*f585d8a3SJacky Wang             "class C { ",
1066*f585d8a3SJacky Wang             "  @Inject String valueC;",
1067*f585d8a3SJacky Wang             "}");
1068*f585d8a3SJacky Wang 
1069*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(classA, classB, classC)
1070*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
1071*f585d8a3SJacky Wang         .compile(
1072*f585d8a3SJacky Wang             subject -> {
1073*f585d8a3SJacky Wang               subject.hasErrorCount(0);
1074*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/A_MembersInjector"));
1075*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/C_MembersInjector"));
1076*f585d8a3SJacky Wang 
1077*f585d8a3SJacky Wang               try {
1078*f585d8a3SJacky Wang                 subject.generatedSourceFileWithPath("test/B_MembersInjector");
1079*f585d8a3SJacky Wang                 // Can't throw an assertion error since it would be caught.
1080*f585d8a3SJacky Wang                 throw new IllegalStateException("Test generated a B_MembersInjector");
1081*f585d8a3SJacky Wang               } catch (AssertionError expected) {}
1082*f585d8a3SJacky Wang             });
1083*f585d8a3SJacky Wang   }
1084*f585d8a3SJacky Wang 
1085*f585d8a3SJacky Wang   // Shows that we do generate a MembersInjector for a type that has an @Inject
1086*f585d8a3SJacky Wang   // constructor and that extends a type with @Inject fields, even if it has no local field
1087*f585d8a3SJacky Wang   // injection sites
1088*f585d8a3SJacky Wang   // TODO(erichang): Are these even used anymore?
1089*f585d8a3SJacky Wang   @Test
testConstructorInjectedFieldInjection()1090*f585d8a3SJacky Wang   public void testConstructorInjectedFieldInjection() throws Exception {
1091*f585d8a3SJacky Wang     Source classA =
1092*f585d8a3SJacky Wang         CompilerTests.javaSource(
1093*f585d8a3SJacky Wang             "test.A",
1094*f585d8a3SJacky Wang             "package test;",
1095*f585d8a3SJacky Wang             "",
1096*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1097*f585d8a3SJacky Wang             "",
1098*f585d8a3SJacky Wang             "class A extends B {",
1099*f585d8a3SJacky Wang             "  @Inject A() {}",
1100*f585d8a3SJacky Wang             "}");
1101*f585d8a3SJacky Wang     Source classB =
1102*f585d8a3SJacky Wang         CompilerTests.javaSource(
1103*f585d8a3SJacky Wang             "test.B",
1104*f585d8a3SJacky Wang             "package test;",
1105*f585d8a3SJacky Wang             "",
1106*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1107*f585d8a3SJacky Wang             "",
1108*f585d8a3SJacky Wang             "class B { ",
1109*f585d8a3SJacky Wang             "  @Inject String valueB;",
1110*f585d8a3SJacky Wang             "}");
1111*f585d8a3SJacky Wang 
1112*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(classA, classB)
1113*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
1114*f585d8a3SJacky Wang         .compile(
1115*f585d8a3SJacky Wang             subject -> {
1116*f585d8a3SJacky Wang               subject.hasErrorCount(0);
1117*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/A_MembersInjector"));
1118*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/B_MembersInjector"));
1119*f585d8a3SJacky Wang             });
1120*f585d8a3SJacky Wang   }
1121*f585d8a3SJacky Wang 
1122*f585d8a3SJacky Wang   // Regression test for https://github.com/google/dagger/issues/3143
1123*f585d8a3SJacky Wang   @Test
testMembersInjectionBindingExistsInParentComponent()1124*f585d8a3SJacky Wang   public void testMembersInjectionBindingExistsInParentComponent() throws Exception {
1125*f585d8a3SJacky Wang     Source component =
1126*f585d8a3SJacky Wang         CompilerTests.javaSource(
1127*f585d8a3SJacky Wang             "test.MyComponent",
1128*f585d8a3SJacky Wang             "package test;",
1129*f585d8a3SJacky Wang             "",
1130*f585d8a3SJacky Wang             "import dagger.Component;",
1131*f585d8a3SJacky Wang             "",
1132*f585d8a3SJacky Wang             "@Component(modules = MyComponentModule.class)",
1133*f585d8a3SJacky Wang             "public interface MyComponent {",
1134*f585d8a3SJacky Wang             "  void inject(Bar bar);",
1135*f585d8a3SJacky Wang             "",
1136*f585d8a3SJacky Wang             "  MySubcomponent subcomponent();",
1137*f585d8a3SJacky Wang             "}");
1138*f585d8a3SJacky Wang 
1139*f585d8a3SJacky Wang     Source subcomponent =
1140*f585d8a3SJacky Wang         CompilerTests.javaSource(
1141*f585d8a3SJacky Wang             "test.MySubcomponent",
1142*f585d8a3SJacky Wang             "package test;",
1143*f585d8a3SJacky Wang             "",
1144*f585d8a3SJacky Wang             "import dagger.Subcomponent;",
1145*f585d8a3SJacky Wang             "",
1146*f585d8a3SJacky Wang             "@Subcomponent(modules = MySubcomponentModule.class)",
1147*f585d8a3SJacky Wang             "interface MySubcomponent {",
1148*f585d8a3SJacky Wang             "  Foo foo();",
1149*f585d8a3SJacky Wang             "}");
1150*f585d8a3SJacky Wang 
1151*f585d8a3SJacky Wang     Source foo =
1152*f585d8a3SJacky Wang         CompilerTests.javaSource(
1153*f585d8a3SJacky Wang             "test.Foo",
1154*f585d8a3SJacky Wang             "package test;",
1155*f585d8a3SJacky Wang             "",
1156*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1157*f585d8a3SJacky Wang             "",
1158*f585d8a3SJacky Wang             "class Foo {",
1159*f585d8a3SJacky Wang             "  @Inject Foo(Bar bar) {}",
1160*f585d8a3SJacky Wang             "}");
1161*f585d8a3SJacky Wang 
1162*f585d8a3SJacky Wang     Source bar =
1163*f585d8a3SJacky Wang         CompilerTests.javaSource(
1164*f585d8a3SJacky Wang             "test.Bar",
1165*f585d8a3SJacky Wang             "package test;",
1166*f585d8a3SJacky Wang             "",
1167*f585d8a3SJacky Wang             "import java.util.Set;",
1168*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1169*f585d8a3SJacky Wang             "",
1170*f585d8a3SJacky Wang             "class Bar {",
1171*f585d8a3SJacky Wang             "  @Inject Set<String> multibindingStrings;",
1172*f585d8a3SJacky Wang             "  @Inject Bar() {}",
1173*f585d8a3SJacky Wang             "}");
1174*f585d8a3SJacky Wang 
1175*f585d8a3SJacky Wang     Source componentModule =
1176*f585d8a3SJacky Wang         CompilerTests.javaSource(
1177*f585d8a3SJacky Wang             "test.MyComponentModule",
1178*f585d8a3SJacky Wang             "package test;",
1179*f585d8a3SJacky Wang             "",
1180*f585d8a3SJacky Wang             "import dagger.Module;",
1181*f585d8a3SJacky Wang             "import dagger.Provides;",
1182*f585d8a3SJacky Wang             "import dagger.multibindings.IntoSet;",
1183*f585d8a3SJacky Wang             "",
1184*f585d8a3SJacky Wang             "@Module",
1185*f585d8a3SJacky Wang             "interface MyComponentModule {",
1186*f585d8a3SJacky Wang             "  @Provides",
1187*f585d8a3SJacky Wang             "  @IntoSet",
1188*f585d8a3SJacky Wang             "  static String provideString() {",
1189*f585d8a3SJacky Wang             "    return \"\";",
1190*f585d8a3SJacky Wang             "  }",
1191*f585d8a3SJacky Wang             "}");
1192*f585d8a3SJacky Wang 
1193*f585d8a3SJacky Wang     Source subcomponentModule =
1194*f585d8a3SJacky Wang         CompilerTests.javaSource(
1195*f585d8a3SJacky Wang             "test.MySubcomponentModule",
1196*f585d8a3SJacky Wang             "package test;",
1197*f585d8a3SJacky Wang             "",
1198*f585d8a3SJacky Wang             "import dagger.Module;",
1199*f585d8a3SJacky Wang             "import dagger.Provides;",
1200*f585d8a3SJacky Wang             "import dagger.multibindings.IntoSet;",
1201*f585d8a3SJacky Wang             "",
1202*f585d8a3SJacky Wang             "@Module",
1203*f585d8a3SJacky Wang             "interface MySubcomponentModule {",
1204*f585d8a3SJacky Wang             "  @Provides",
1205*f585d8a3SJacky Wang             "  @IntoSet",
1206*f585d8a3SJacky Wang             "  static String provideString() {",
1207*f585d8a3SJacky Wang             "    return \"\";",
1208*f585d8a3SJacky Wang             "  }",
1209*f585d8a3SJacky Wang             "}");
1210*f585d8a3SJacky Wang 
1211*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
1212*f585d8a3SJacky Wang             component, subcomponent, foo, bar, componentModule, subcomponentModule)
1213*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
1214*f585d8a3SJacky Wang         .compile(
1215*f585d8a3SJacky Wang             subject -> {
1216*f585d8a3SJacky Wang               subject.hasErrorCount(0);
1217*f585d8a3SJacky Wang               // Check that the injectBar() method is not shared across components.
1218*f585d8a3SJacky Wang               // We avoid sharing them in general because they may be different (e.g. in this case
1219*f585d8a3SJacky Wang               // we inject multibindings that are different across components).
1220*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerMyComponent"));
1221*f585d8a3SJacky Wang             });
1222*f585d8a3SJacky Wang 
1223*f585d8a3SJacky Wang   }
1224*f585d8a3SJacky Wang 
1225*f585d8a3SJacky Wang   // Test that if both a MembersInjectionBinding and ProvisionBinding both exist in the same
1226*f585d8a3SJacky Wang   // component they share the same inject methods rather than generating their own.
1227*f585d8a3SJacky Wang   @Test
testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding()1228*f585d8a3SJacky Wang   public void testMembersInjectionBindingSharesInjectMethodsWithProvisionBinding()
1229*f585d8a3SJacky Wang       throws Exception {
1230*f585d8a3SJacky Wang     Source component =
1231*f585d8a3SJacky Wang         CompilerTests.javaSource(
1232*f585d8a3SJacky Wang             "test.MyComponent",
1233*f585d8a3SJacky Wang             "package test;",
1234*f585d8a3SJacky Wang             "",
1235*f585d8a3SJacky Wang             "import dagger.Component;",
1236*f585d8a3SJacky Wang             "",
1237*f585d8a3SJacky Wang             "@Component",
1238*f585d8a3SJacky Wang             "public interface MyComponent {",
1239*f585d8a3SJacky Wang             "  Foo foo();",
1240*f585d8a3SJacky Wang             "",
1241*f585d8a3SJacky Wang             "  void inject(Foo foo);",
1242*f585d8a3SJacky Wang             "}");
1243*f585d8a3SJacky Wang 
1244*f585d8a3SJacky Wang     Source foo =
1245*f585d8a3SJacky Wang         CompilerTests.javaSource(
1246*f585d8a3SJacky Wang             "test.Foo",
1247*f585d8a3SJacky Wang             "package test;",
1248*f585d8a3SJacky Wang             "",
1249*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1250*f585d8a3SJacky Wang             "",
1251*f585d8a3SJacky Wang             "class Foo {",
1252*f585d8a3SJacky Wang             "  @Inject Bar bar;",
1253*f585d8a3SJacky Wang             "  @Inject Foo() {}",
1254*f585d8a3SJacky Wang             "}");
1255*f585d8a3SJacky Wang 
1256*f585d8a3SJacky Wang     Source bar =
1257*f585d8a3SJacky Wang         CompilerTests.javaSource(
1258*f585d8a3SJacky Wang             "test.Bar",
1259*f585d8a3SJacky Wang             "package test;",
1260*f585d8a3SJacky Wang             "",
1261*f585d8a3SJacky Wang             "import javax.inject.Inject;",
1262*f585d8a3SJacky Wang             "",
1263*f585d8a3SJacky Wang             "class Bar {",
1264*f585d8a3SJacky Wang             "  @Inject Bar() {}",
1265*f585d8a3SJacky Wang             "}");
1266*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(component, foo, bar)
1267*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
1268*f585d8a3SJacky Wang         .compile(
1269*f585d8a3SJacky Wang             subject -> {
1270*f585d8a3SJacky Wang               subject.hasErrorCount(0);
1271*f585d8a3SJacky Wang               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerMyComponent"));
1272*f585d8a3SJacky Wang             });
1273*f585d8a3SJacky Wang   }
1274*f585d8a3SJacky Wang }
1275