• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.Compilers.compilerWithOptions;
21 
22 import com.google.testing.compile.Compilation;
23 import com.google.testing.compile.JavaFileObjects;
24 import java.util.Collection;
25 import javax.tools.JavaFileObject;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 import org.junit.runners.Parameterized;
29 import org.junit.runners.Parameterized.Parameters;
30 
31 @RunWith(Parameterized.class)
32 public class SetBindingRequestFulfillmentWithGuavaTest {
33   @Parameters(name = "{0}")
parameters()34   public static Collection<Object[]> parameters() {
35     return CompilerMode.TEST_PARAMETERS;
36   }
37 
38   private final CompilerMode compilerMode;
39 
SetBindingRequestFulfillmentWithGuavaTest(CompilerMode compilerMode)40   public SetBindingRequestFulfillmentWithGuavaTest(CompilerMode compilerMode) {
41     this.compilerMode = compilerMode;
42   }
43 
44   @Test
setBindings()45   public void setBindings() {
46     JavaFileObject emptySetModuleFile = JavaFileObjects.forSourceLines("test.EmptySetModule",
47         "package test;",
48         "",
49         "import dagger.Module;",
50         "import dagger.Provides;",
51         "import dagger.multibindings.ElementsIntoSet;",
52         "import dagger.multibindings.Multibinds;",
53         "import java.util.Collections;",
54         "import java.util.Set;",
55         "",
56         "@Module",
57         "abstract class EmptySetModule {",
58         "  @Multibinds abstract Set<Object> objects();",
59         "",
60         "  @Provides @ElementsIntoSet",
61         "  static Set<String> emptySet() { ",
62         "    return Collections.emptySet();",
63         "  }",
64         "  @Provides @ElementsIntoSet",
65         "  static Set<Integer> onlyContributionIsElementsIntoSet() { ",
66         "    return Collections.emptySet();",
67         "  }",
68         "}");
69     JavaFileObject setModuleFile = JavaFileObjects.forSourceLines("test.SetModule",
70         "package test;",
71         "",
72         "import dagger.Module;",
73         "import dagger.Provides;",
74         "import dagger.multibindings.IntoSet;",
75         "",
76         "@Module",
77         "final class SetModule {",
78         "  @Provides @IntoSet static String string() { return \"\"; }",
79         "}");
80     JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
81         "package test;",
82         "",
83         "import dagger.Component;",
84         "import java.util.Set;",
85         "import javax.inject.Provider;",
86         "",
87         "@Component(modules = {EmptySetModule.class, SetModule.class})",
88         "interface TestComponent {",
89         "  Set<String> strings();",
90         "  Set<Object> objects();",
91         "  Set<Integer> onlyContributionIsElementsIntoSet();",
92         "}");
93     JavaFileObject generatedComponent =
94         JavaFileObjects.forSourceLines(
95             "test.DaggerTestComponent",
96             "package test;",
97             "",
98             "import com.google.common.collect.ImmutableSet;",
99             "",
100             GeneratedLines.generatedAnnotations(),
101             "final class DaggerTestComponent implements TestComponent {",
102             "  @Override",
103             "  public Set<String> strings() {",
104             "    return ImmutableSet.<String>builderWithExpectedSize(2)",
105             "        .addAll(EmptySetModule_EmptySetFactory.emptySet())",
106             "        .add(SetModule_StringFactory.string())",
107             "        .build();",
108             "  }",
109             "",
110             "  @Override",
111             "  public Set<Object> objects() {",
112             "    return ImmutableSet.<Object>of();",
113             "  }",
114             "",
115             "  @Override",
116             "  public Set<Integer> onlyContributionIsElementsIntoSet() {",
117             "    return ImmutableSet.<Integer>copyOf(",
118             "        EmptySetModule_OnlyContributionIsElementsIntoSetFactory",
119             "            .onlyContributionIsElementsIntoSet());",
120             "  }",
121             "}");
122     Compilation compilation =
123         compilerWithOptions(compilerMode.javacopts())
124             .compile(emptySetModuleFile, setModuleFile, componentFile);
125     assertThat(compilation).succeeded();
126     assertThat(compilation)
127         .generatedSourceFile("test.DaggerTestComponent")
128         .containsElementsIn(generatedComponent);
129   }
130 
131   @Test
inaccessible()132   public void inaccessible() {
133     JavaFileObject inaccessible =
134         JavaFileObjects.forSourceLines(
135             "other.Inaccessible",
136             "package other;",
137             "",
138             "class Inaccessible {}");
139     JavaFileObject inaccessible2 =
140         JavaFileObjects.forSourceLines(
141             "other.Inaccessible2",
142             "package other;",
143             "",
144             "class Inaccessible2 {}");
145     JavaFileObject usesInaccessible =
146         JavaFileObjects.forSourceLines(
147             "other.UsesInaccessible",
148             "package other;",
149             "",
150             "import java.util.Set;",
151             "import javax.inject.Inject;",
152             "",
153             "public class UsesInaccessible {",
154             "  @Inject UsesInaccessible(Set<Inaccessible> set1, Set<Inaccessible2> set2) {}",
155             "}");
156 
157     JavaFileObject module =
158         JavaFileObjects.forSourceLines(
159             "other.TestModule",
160             "package other;",
161             "",
162             "import dagger.Module;",
163             "import dagger.Provides;",
164             "import dagger.multibindings.ElementsIntoSet;",
165             "import dagger.multibindings.Multibinds;",
166             "import java.util.Collections;",
167             "import java.util.Set;",
168             "",
169             "@Module",
170             "public abstract class TestModule {",
171             "  @Multibinds abstract Set<Inaccessible> objects();",
172             "",
173             "  @Provides @ElementsIntoSet",
174             "  static Set<Inaccessible2> emptySet() { ",
175             "    return Collections.emptySet();",
176             "  }",
177             "}");
178     JavaFileObject componentFile =
179         JavaFileObjects.forSourceLines(
180             "test.TestComponent",
181             "package test;",
182             "",
183             "import dagger.Component;",
184             "import java.util.Set;",
185             "import javax.inject.Provider;",
186             "import other.TestModule;",
187             "import other.UsesInaccessible;",
188             "",
189             "@Component(modules = TestModule.class)",
190             "interface TestComponent {",
191             "  UsesInaccessible usesInaccessible();",
192             "}");
193     JavaFileObject generatedComponent =
194         JavaFileObjects.forSourceLines(
195             "test.DaggerTestComponent",
196             "package test;",
197             "",
198             "import com.google.common.collect.ImmutableSet;",
199             "import other.TestModule_EmptySetFactory;",
200             "import other.UsesInaccessible;",
201             "import other.UsesInaccessible_Factory;",
202             "",
203             GeneratedLines.generatedAnnotations(),
204             "final class DaggerTestComponent implements TestComponent {",
205             "  private Set setOfInaccessible2() {",
206             "    return ImmutableSet.copyOf(TestModule_EmptySetFactory.emptySet());",
207             "  }",
208             "",
209             "  @Override",
210             "  public UsesInaccessible usesInaccessible() {",
211             "    return UsesInaccessible_Factory.newInstance(",
212             "        (Set) ImmutableSet.of(),",
213             "        (Set) setOfInaccessible2());",
214             "  }",
215             "}");
216     Compilation compilation =
217         compilerWithOptions(compilerMode.javacopts())
218             .compile(module, inaccessible, inaccessible2, usesInaccessible, componentFile);
219     assertThat(compilation).succeeded();
220     assertThat(compilation)
221         .generatedSourceFile("test.DaggerTestComponent")
222         .containsElementsIn(generatedComponent);
223   }
224 
225   @Test
subcomponentOmitsInheritedBindings()226   public void subcomponentOmitsInheritedBindings() {
227     JavaFileObject parent =
228         JavaFileObjects.forSourceLines(
229             "test.Parent",
230             "package test;",
231             "",
232             "import dagger.Component;",
233             "",
234             "@Component(modules = ParentModule.class)",
235             "interface Parent {",
236             "  Child child();",
237             "}");
238     JavaFileObject parentModule =
239         JavaFileObjects.forSourceLines(
240             "test.ParentModule",
241             "package test;",
242             "",
243             "import dagger.Module;",
244             "import dagger.Provides;",
245             "import dagger.multibindings.IntoSet;",
246             "import dagger.multibindings.StringKey;",
247             "",
248             "@Module",
249             "class ParentModule {",
250             "  @Provides @IntoSet static Object parentObject() {",
251             "    return \"parent object\";",
252             "  }",
253             "}");
254     JavaFileObject child =
255         JavaFileObjects.forSourceLines(
256             "test.Child",
257             "package test;",
258             "",
259             "import dagger.Subcomponent;",
260             "import java.util.Set;",
261             "",
262             "@Subcomponent",
263             "interface Child {",
264             "  Set<Object> objectSet();",
265             "}");
266     JavaFileObject generatedComponent =
267         JavaFileObjects.forSourceLines(
268             "test.DaggerParent",
269             "package test;",
270             "",
271             "import com.google.common.collect.ImmutableSet;",
272             "",
273             GeneratedLines.generatedAnnotations(),
274             "final class DaggerParent implements Parent {",
275             "  private static final class ChildImpl implements Child {",
276             "    @Override",
277             "    public Set<Object> objectSet() {",
278             "      return ImmutableSet.<Object>of(",
279             "          ParentModule_ParentObjectFactory.parentObject());",
280             "    }",
281             "  }",
282             "}");
283     Compilation compilation =
284         compilerWithOptions(compilerMode.javacopts()).compile(parent, parentModule, child);
285     assertThat(compilation).succeeded();
286     assertThat(compilation)
287         .generatedSourceFile("test.DaggerParent")
288         .containsElementsIn(generatedComponent);
289   }
290 
291   @Test
productionComponents()292   public void productionComponents() {
293     JavaFileObject emptySetModuleFile = JavaFileObjects.forSourceLines("test.EmptySetModule",
294         "package test;",
295         "",
296         "import dagger.Module;",
297         "import dagger.Provides;",
298         "import dagger.multibindings.ElementsIntoSet;",
299         "import java.util.Collections;",
300         "import java.util.Set;",
301         "",
302         "@Module",
303         "abstract class EmptySetModule {",
304         "  @Provides @ElementsIntoSet",
305         "  static Set<String> emptySet() { ",
306         "    return Collections.emptySet();",
307         "  }",
308         "}");
309     JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
310         "package test;",
311         "",
312         "import com.google.common.util.concurrent.ListenableFuture;",
313         "import dagger.producers.ProductionComponent;",
314         "import java.util.Set;",
315         "",
316         "@ProductionComponent(modules = EmptySetModule.class)",
317         "interface TestComponent {",
318         "  ListenableFuture<Set<String>> strings();",
319         "}");
320     JavaFileObject generatedComponent =
321         JavaFileObjects.forSourceLines(
322             "test.DaggerTestComponent",
323             "package test;",
324             "",
325             GeneratedLines.generatedImports(
326                 "import com.google.common.collect.ImmutableSet;",
327                 "import com.google.common.util.concurrent.Futures;",
328                 "import com.google.common.util.concurrent.ListenableFuture;",
329                 "import dagger.producers.internal.CancellationListener;",
330                 "import java.util.Set;"),
331             "",
332             GeneratedLines.generatedAnnotations(),
333             "final class DaggerTestComponent implements TestComponent, ",
334             "    CancellationListener {",
335             "  private final DaggerTestComponent testComponent = this;",
336             "",
337             "  private DaggerTestComponent() {}",
338             "",
339             "  public static Builder builder() {",
340             "    return new Builder();",
341             "  }",
342             "",
343             "  public static TestComponent create() {",
344             "    return new Builder().build();",
345             "  }",
346             "",
347             "  private Set<String> setOfString() {",
348             "    return ImmutableSet.<String>copyOf(",
349             "        EmptySetModule_EmptySetFactory.emptySet());",
350             "  }",
351             "",
352             "  @Override",
353             "  public ListenableFuture<Set<String>> strings() {",
354             "    return Futures.immediateFuture(setOfString());",
355             "  }",
356             "",
357             "  @Override",
358             "  public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {}",
359             "",
360             "  static final class Builder {",
361             "    private Builder() {}",
362             "",
363             "    public TestComponent build() {",
364             "      return new DaggerTestComponent();",
365             "    }",
366             "  }",
367             "}");
368 
369     Compilation compilation =
370         compilerWithOptions(compilerMode.javacopts())
371             .compile(emptySetModuleFile, componentFile);
372     assertThat(compilation).succeeded();
373     assertThat(compilation)
374         .generatedSourceFile("test.DaggerTestComponent")
375         .hasSourceEquivalentTo(generatedComponent);
376   }
377 }
378