• 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 static com.google.testing.compile.CompilationSubject.assertThat;
20 import static dagger.internal.codegen.CompilerMode.DEFAULT_MODE;
21 import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE;
22 import static dagger.internal.codegen.Compilers.compilerWithOptions;
23 
24 import com.google.common.collect.ImmutableCollection;
25 import com.google.testing.compile.Compilation;
26 import com.google.testing.compile.JavaFileObjects;
27 import javax.tools.JavaFileObject;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.junit.runners.Parameterized;
31 import org.junit.runners.Parameterized.Parameters;
32 
33 @RunWith(Parameterized.class)
34 public class AssistedFactoryTest {
35   @Parameters(name = "{0}")
parameters()36   public static ImmutableCollection<Object[]> parameters() {
37     return CompilerMode.TEST_PARAMETERS;
38   }
39 
40   private final CompilerMode compilerMode;
41 
AssistedFactoryTest(CompilerMode compilerMode)42   public AssistedFactoryTest(CompilerMode compilerMode) {
43     this.compilerMode = compilerMode;
44   }
45 
46   @Test
testAssistedFactory()47   public void testAssistedFactory() {
48     JavaFileObject foo =
49         JavaFileObjects.forSourceLines(
50             "test.Foo",
51             "package test;",
52             "",
53             "import dagger.assisted.Assisted;",
54             "import dagger.assisted.AssistedInject;",
55             "",
56             "class Foo {",
57             "  @AssistedInject",
58             "  Foo(@Assisted String str, Bar bar) {}",
59             "}");
60     JavaFileObject fooFactory =
61         JavaFileObjects.forSourceLines(
62             "test.FooFactory",
63             "package test;",
64             "",
65             "import dagger.assisted.AssistedFactory;",
66             "",
67             "@AssistedFactory",
68             "interface FooFactory {",
69             "  Foo create(String factoryStr);",
70             "}");
71     JavaFileObject bar =
72         JavaFileObjects.forSourceLines(
73             "test.Bar",
74             "package test;",
75             "",
76             "import javax.inject.Inject;",
77             "",
78             "class Bar {",
79             "  @Inject Bar() {}",
80             "}");
81     JavaFileObject component =
82         JavaFileObjects.forSourceLines(
83             "test.TestComponent",
84             "package test;",
85             "",
86             "import dagger.Component;",
87             "",
88             "@Component",
89             "interface TestComponent {",
90             "  FooFactory fooFactory();",
91             "}");
92     Compilation compilation =
93         compilerWithOptions(compilerMode.javacopts()).compile(foo, bar, fooFactory, component);
94     assertThat(compilation).succeeded();
95     JavaFileObject generatedComponent =
96         compilerMode
97             .javaFileBuilder("test.DaggerTestComponent")
98             .addLines("package test;", "", GeneratedLines.generatedAnnotations())
99             .addLinesIn(
100                 FAST_INIT_MODE,
101                 "final class DaggerTestComponent implements TestComponent {",
102                 "",
103                 "  private Foo foo(String str) {",
104                 "    return new Foo(str, new Bar());",
105                 "  }",
106                 "",
107                 "  @Override",
108                 "  public FooFactory fooFactory() {",
109                 "    return new FooFactory() {",
110                 "      @Override",
111                 "      public Foo create(String str) {",
112                 "        return DaggerTestComponent.this.foo(str);",
113                 "      }",
114                 "    };",
115                 "  }",
116                 "}")
117             .addLinesIn(
118                 DEFAULT_MODE,
119                 "final class DaggerTestComponent implements TestComponent {",
120                 "",
121                 "  private Foo_Factory fooProvider;",
122                 "",
123                 "  private Provider<FooFactory> fooFactoryProvider;",
124                 "",
125                 "  @SuppressWarnings(\"unchecked\")",
126                 "  private void initialize() {",
127                 "    this.fooProvider = Foo_Factory.create(Bar_Factory.create());",
128                 "    this.fooFactoryProvider = FooFactory_Impl.create(fooProvider);",
129                 "  }",
130                 "",
131                 "  @Override",
132                 "  public FooFactory fooFactory() {",
133                 "    return fooFactoryProvider.get();",
134                 "  }",
135                 "}")
136             .build();
137     assertThat(compilation)
138         .generatedSourceFile("test.DaggerTestComponent")
139         .containsElementsIn(generatedComponent);
140   }
141 
142   @Test
testAssistedFactoryCycle()143   public void testAssistedFactoryCycle() {
144     JavaFileObject foo =
145         JavaFileObjects.forSourceLines(
146             "test.Foo",
147             "package test;",
148             "",
149             "import dagger.assisted.Assisted;",
150             "import dagger.assisted.AssistedInject;",
151             "",
152             "class Foo {",
153             "  @AssistedInject",
154             "  Foo(@Assisted String str, Bar bar) {}",
155             "}");
156     JavaFileObject fooFactory =
157         JavaFileObjects.forSourceLines(
158             "test.FooFactory",
159             "package test;",
160             "",
161             "import dagger.assisted.AssistedFactory;",
162             "",
163             "@AssistedFactory",
164             "interface FooFactory {",
165             "  Foo create(String factoryStr);",
166             "}");
167     JavaFileObject bar =
168         JavaFileObjects.forSourceLines(
169             "test.Bar",
170             "package test;",
171             "",
172             "import javax.inject.Inject;",
173             "",
174             "class Bar {",
175             "  @Inject Bar(FooFactory fooFactory) {}",
176             "}");
177     JavaFileObject component =
178         JavaFileObjects.forSourceLines(
179             "test.TestComponent",
180             "package test;",
181             "",
182             "import dagger.Component;",
183             "",
184             "@Component",
185             "interface TestComponent {",
186             "  FooFactory fooFactory();",
187             "}");
188     Compilation compilation =
189         compilerWithOptions(compilerMode.javacopts()).compile(foo, bar, fooFactory, component);
190     assertThat(compilation).succeeded();
191     JavaFileObject generatedComponent =
192         compilerMode
193             .javaFileBuilder("test.DaggerTestComponent")
194             .addLines("package test;", "", GeneratedLines.generatedAnnotations())
195             .addLinesIn(
196                 FAST_INIT_MODE,
197                 "final class DaggerTestComponent implements TestComponent {",
198                 "",
199                 "  private Bar bar() {",
200                 "    return new Bar(fooFactory());",
201                 "  }",
202                 "",
203                 "  private Foo foo(String str) {",
204                 "    return new Foo(str, bar());",
205                 "  }",
206                 "",
207                 "  @Override",
208                 "  public FooFactory fooFactory() {",
209                 "    return new FooFactory() {",
210                 "      @Override",
211                 "      public Foo create(String str) {",
212                 "        return DaggerTestComponent.this.foo(str);",
213                 "      }",
214                 "    };",
215                 "  }",
216                 "}")
217             .addLinesIn(
218                 DEFAULT_MODE,
219                 "final class DaggerTestComponent implements TestComponent {",
220                 "",
221                 "  private Provider<FooFactory> fooFactoryProvider;",
222                 "",
223                 "  private Provider<Bar> barProvider;",
224                 "",
225                 "  private Foo_Factory fooProvider;",
226                 "",
227                 "  @SuppressWarnings(\"unchecked\")",
228                 "  private void initialize() {",
229                 "    this.fooFactoryProvider = new DelegateFactory<>();",
230                 "    this.barProvider = Bar_Factory.create(fooFactoryProvider);",
231                 "    this.fooProvider = Foo_Factory.create(barProvider);",
232                 "    DelegateFactory.setDelegate(",
233                 "        fooFactoryProvider, FooFactory_Impl.create(fooProvider));",
234                 "  }",
235                 "",
236                 "  @Override",
237                 "  public FooFactory fooFactory() {",
238                 "    return fooFactoryProvider.get();",
239                 "  }",
240                 "}")
241             .build();
242     assertThat(compilation)
243         .generatedSourceFile("test.DaggerTestComponent")
244         .containsElementsIn(generatedComponent);
245   }
246 }
247