• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.internal.codegen;
18 
19 import androidx.room.compiler.processing.util.Source;
20 import com.google.common.collect.ImmutableCollection;
21 import dagger.testing.compile.CompilerTests;
22 import dagger.testing.golden.GoldenFileRule;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 import org.junit.runners.Parameterized;
27 import org.junit.runners.Parameterized.Parameters;
28 
29 @RunWith(Parameterized.class)
30 public class AssistedFactoryTest {
31   @Parameters(name = "{0}")
parameters()32   public static ImmutableCollection<Object[]> parameters() {
33     return CompilerMode.TEST_PARAMETERS;
34   }
35 
36   @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule();
37 
38   private final CompilerMode compilerMode;
39 
AssistedFactoryTest(CompilerMode compilerMode)40   public AssistedFactoryTest(CompilerMode compilerMode) {
41     this.compilerMode = compilerMode;
42   }
43 
44   @Test
testAssistedFactory()45   public void testAssistedFactory() throws Exception {
46     Source foo =
47         CompilerTests.javaSource(
48             "test.Foo",
49             "package test;",
50             "",
51             "import dagger.assisted.Assisted;",
52             "import dagger.assisted.AssistedInject;",
53             "",
54             "class Foo {",
55             "  @AssistedInject",
56             "  Foo(@Assisted String str, Bar bar) {}",
57             "}");
58 
59     Source fooFactory =
60         CompilerTests.javaSource(
61             "test.FooFactory",
62             "package test;",
63             "",
64             "import dagger.assisted.AssistedFactory;",
65             "",
66             "@AssistedFactory",
67             "interface FooFactory {",
68             "  Foo create(String factoryStr);",
69             "}");
70 
71     Source bar =
72         CompilerTests.javaSource(
73             "test.Bar",
74             "package test;",
75             "",
76             "import javax.inject.Inject;",
77             "",
78             "class Bar {",
79             "  @Inject Bar() {}",
80             "}");
81 
82     Source component =
83         CompilerTests.javaSource(
84             "test.TestComponent",
85             "package test;",
86             "",
87             "import dagger.Component;",
88             "",
89             "@Component",
90             "interface TestComponent {",
91             "  FooFactory fooFactory();",
92             "}");
93 
94     CompilerTests.daggerCompiler(foo, bar, fooFactory, component)
95         .withProcessingOptions(compilerMode.processorOptions())
96         .compile(
97             subject -> {
98               subject.hasErrorCount(0);
99               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
100             });
101   }
102 
103   @Test
testAssistedFactoryCycle()104   public void testAssistedFactoryCycle() throws Exception {
105     Source foo =
106         CompilerTests.javaSource(
107             "test.Foo",
108             "package test;",
109             "",
110             "import dagger.assisted.Assisted;",
111             "import dagger.assisted.AssistedInject;",
112             "",
113             "class Foo {",
114             "  @AssistedInject",
115             "  Foo(@Assisted String str, Bar bar) {}",
116             "}");
117 
118     Source fooFactory =
119         CompilerTests.javaSource(
120             "test.FooFactory",
121             "package test;",
122             "",
123             "import dagger.assisted.AssistedFactory;",
124             "",
125             "@AssistedFactory",
126             "interface FooFactory {",
127             "  Foo create(String factoryStr);",
128             "}");
129 
130     Source bar =
131         CompilerTests.javaSource(
132             "test.Bar",
133             "package test;",
134             "",
135             "import javax.inject.Inject;",
136             "",
137             "class Bar {",
138             "  @Inject Bar(FooFactory fooFactory) {}",
139             "}");
140 
141     Source component =
142         CompilerTests.javaSource(
143             "test.TestComponent",
144             "package test;",
145             "",
146             "import dagger.Component;",
147             "",
148             "@Component",
149             "interface TestComponent {",
150             "  FooFactory fooFactory();",
151             "}");
152 
153     CompilerTests.daggerCompiler(foo, bar, fooFactory, component)
154         .withProcessingOptions(compilerMode.processorOptions())
155         .compile(
156             subject -> {
157               subject.hasErrorCount(0);
158               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
159             });
160   }
161 
162   @Test
assistedParamConflictsWithComponentFieldName_successfulyDeduped()163   public void assistedParamConflictsWithComponentFieldName_successfulyDeduped() throws Exception {
164     Source foo =
165         CompilerTests.javaSource(
166             "test.Foo",
167             "package test;",
168             "",
169             "import dagger.assisted.Assisted;",
170             "import dagger.assisted.AssistedInject;",
171             "import javax.inject.Provider;",
172             "",
173             "class Foo {",
174             "  @AssistedInject",
175             "  Foo(@Assisted String testComponentImpl, Provider<Bar> bar) {}",
176             "}");
177 
178     Source fooFactory =
179         CompilerTests.javaSource(
180             "test.FooFactory",
181             "package test;",
182             "",
183             "import dagger.assisted.AssistedFactory;",
184             "",
185             "@AssistedFactory",
186             "interface FooFactory {",
187             "  Foo create(String factoryStr);",
188             "}");
189 
190     Source bar =
191         CompilerTests.javaSource(
192             "test.Bar",
193             "package test;",
194             "",
195             "import javax.inject.Inject;",
196             "",
197             "class Bar {",
198             "  @Inject Bar() {}",
199             "}");
200 
201     Source component =
202         CompilerTests.javaSource(
203             "test.TestComponent",
204             "package test;",
205             "",
206             "import dagger.Component;",
207             "",
208             "@Component",
209             "interface TestComponent {",
210             "  FooFactory fooFactory();",
211             "}");
212 
213     CompilerTests.daggerCompiler(foo, bar, fooFactory, component)
214         .withProcessingOptions(compilerMode.processorOptions())
215         .compile(
216             subject -> {
217               subject.hasErrorCount(0);
218               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
219             });
220   }
221 
222   @Test
testFactoryGeneratorDuplicatedParamNames()223   public void testFactoryGeneratorDuplicatedParamNames() throws Exception {
224     Source component =
225         CompilerTests.javaSource(
226             "test.TestComponent",
227             "package test;",
228             "",
229             "import dagger.BindsInstance;",
230             "import dagger.Component;",
231             "",
232             "@Component",
233             "interface TestComponent {",
234             "  @Component.Factory",
235             "  interface Factory {",
236             "    TestComponent create(@BindsInstance Bar arg);",
237             "}",
238             "  FooFactory getFooFactory();",
239             "}");
240 
241     Source fooFactory =
242         CompilerTests.javaSource(
243             "test.FooFactory",
244             "package test;",
245             "",
246             "import dagger.assisted.AssistedFactory;",
247             "",
248             "@AssistedFactory",
249             "public interface FooFactory {",
250             "  Foo create(Integer arg);",
251             "}");
252 
253     Source bar =
254         CompilerTests.javaSource(
255             "test.Bar",
256             "package test;",
257             "",
258             "interface Bar {}");
259 
260     Source foo =
261         CompilerTests.javaSource(
262             "test.Foo",
263             "package test;",
264             "",
265             "import dagger.assisted.Assisted;",
266             "import dagger.assisted.AssistedInject;",
267             "",
268             "class Foo {",
269             "  @AssistedInject",
270             "  Foo(Bar arg, @Assisted Integer argProvider) {}",
271             "}");
272 
273     CompilerTests.daggerCompiler(component, fooFactory, foo, bar)
274         .withProcessingOptions(compilerMode.processorOptions())
275         .compile(
276             subject -> {
277               subject.hasErrorCount(0);
278               subject.generatedSource(goldenFileRule.goldenSource("test/Foo_Factory"));
279             });
280   }
281 
282   @Test
testParameterizedAssistParam()283   public void testParameterizedAssistParam() throws Exception {
284     Source component =
285         CompilerTests.javaSource(
286             "test.TestComponent",
287             "package test;",
288             "",
289             "import dagger.Component;",
290             "",
291             "@Component",
292             "interface TestComponent {",
293             "  FooFactory<String> getFooFactory();",
294             "}");
295 
296     Source fooFactory =
297         CompilerTests.javaSource(
298             "test.FooFactory",
299             "package test;",
300             "",
301             "import dagger.assisted.AssistedFactory;",
302             "",
303             "@AssistedFactory",
304             "public interface FooFactory<T> {",
305             "  Foo<T> create(T arg);",
306             "}");
307 
308     Source foo =
309         CompilerTests.javaSource(
310             "test.Foo",
311             "package test;",
312             "",
313             "import dagger.assisted.Assisted;",
314             "import dagger.assisted.AssistedInject;",
315             "",
316             "class Foo<T> {",
317             "  @AssistedInject",
318             "  Foo(@Assisted T arg) {}",
319             "}");
320 
321     CompilerTests.daggerCompiler(component, fooFactory, foo)
322         .withProcessingOptions(compilerMode.processorOptions())
323         .compile(
324             subject -> {
325               subject.hasErrorCount(0);
326               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
327             });
328   }
329 
330   // This is a regression test for b/305748522
331   // The important thing for this test is that we have two assisted factories for the same assisted
332   // injection class and that they are requested in different components.
333   @Test
testMultipleAssistedFactoryInDifferentComponents()334   public void testMultipleAssistedFactoryInDifferentComponents() throws Exception {
335     Source component =
336         CompilerTests.javaSource(
337             "test.MyComponent",
338             "package test;",
339             "",
340             "import dagger.Component;",
341             "",
342             "@Component",
343             "interface MyComponent {",
344             "  MyComponentAssistedFactory myComponentAssistedFactory();",
345             "  MySubcomponent mySubcomponent();",
346             "}");
347     Source subcomponent =
348         CompilerTests.javaSource(
349             "test.MySubcomponent",
350             "package test;",
351             "",
352             "import dagger.Subcomponent;",
353             "",
354             "@Subcomponent",
355             "interface MySubcomponent {",
356             "  MySubcomponentAssistedFactory mySubcomponentAssistedFactory();",
357             "}");
358     Source assistedClass =
359         CompilerTests.javaSource(
360             "test.MyAssistedClass",
361             "package test;",
362             "",
363             "import dagger.assisted.Assisted;",
364             "import dagger.assisted.AssistedInject;",
365             "",
366             "final class MyAssistedClass {",
367             "  private final Foo foo;",
368             "  private final Bar bar;",
369             "",
370             "  @AssistedInject",
371             "  MyAssistedClass(@Assisted Foo foo, Baz baz, @Assisted Bar bar) {",
372             "    this.foo = foo;",
373             "    this.bar = bar;",
374             "  }",
375             "}");
376     Source componentAssistedFactory =
377         CompilerTests.javaSource(
378             "test.MyComponentAssistedFactory",
379             "package test;",
380             "",
381             "import dagger.assisted.AssistedFactory;",
382             "",
383             "@AssistedFactory",
384             "interface MyComponentAssistedFactory {",
385             "  MyAssistedClass create(Bar bar, Foo foo);",
386             "}");
387     Source subcomponentAssistedFactory =
388         CompilerTests.javaSource(
389             "test.MySubcomponentAssistedFactory",
390             "package test;",
391             "",
392             "import dagger.assisted.AssistedFactory;",
393             "",
394             "@AssistedFactory",
395             "interface MySubcomponentAssistedFactory {",
396             "  MyAssistedClass create(Bar bar, Foo foo);",
397             "}");
398     Source foo =
399         CompilerTests.javaSource(
400             "test.Foo",
401             "package test;",
402             "final class Foo {}");
403     Source bar =
404         CompilerTests.javaSource(
405             "test.Bar",
406             "package test;",
407             "final class Bar {}");
408     Source baz =
409         CompilerTests.javaSource(
410             "test.Baz",
411             "package test;",
412             "",
413             "import javax.inject.Inject;",
414             "",
415             "final class Baz {",
416             "  @Inject Baz() {}",
417             "}");
418 
419     CompilerTests.daggerCompiler(
420             component,
421             subcomponent,
422             assistedClass,
423             componentAssistedFactory,
424             subcomponentAssistedFactory,
425             foo,
426             bar,
427             baz)
428         .withProcessingOptions(compilerMode.processorOptions())
429         .compile(
430             subject -> {
431               subject.hasErrorCount(0);
432               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerMyComponent"));
433             });
434   }
435 }
436