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 androidx.room.compiler.processing.util.Source;
20 import dagger.testing.compile.CompilerTests;
21 import dagger.testing.golden.GoldenFileRule;
22 import java.util.Collection;
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 SetBindingRequestFulfillmentWithGuavaTest {
31   @Parameters(name = "{0}")
parameters()32   public static Collection<Object[]> parameters() {
33     return CompilerMode.TEST_PARAMETERS;
34   }
35 
36   @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule();
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() throws Exception {
46     Source emptySetModuleFile =
47         CompilerTests.javaSource(
48             "test.EmptySetModule",
49             "package test;",
50             "",
51             "import dagger.Module;",
52             "import dagger.Provides;",
53             "import dagger.multibindings.ElementsIntoSet;",
54             "import dagger.multibindings.Multibinds;",
55             "import java.util.Collections;",
56             "import java.util.Set;",
57             "",
58             "@Module",
59             "abstract class EmptySetModule {",
60             "  @Multibinds abstract Set<Object> objects();",
61             "",
62             "  @Provides @ElementsIntoSet",
63             "  static Set<String> emptySet() { ",
64             "    return Collections.emptySet();",
65             "  }",
66             "  @Provides @ElementsIntoSet",
67             "  static Set<Integer> onlyContributionIsElementsIntoSet() { ",
68             "    return Collections.emptySet();",
69             "  }",
70             "}");
71     Source setModuleFile =
72         CompilerTests.javaSource(
73             "test.SetModule",
74             "package test;",
75             "",
76             "import dagger.Module;",
77             "import dagger.Provides;",
78             "import dagger.multibindings.IntoSet;",
79             "",
80             "@Module",
81             "final class SetModule {",
82             "  @Provides @IntoSet static String string() { return \"\"; }",
83             "}");
84     Source componentFile =
85         CompilerTests.javaSource(
86             "test.TestComponent",
87             "package test;",
88             "",
89             "import dagger.Component;",
90             "import java.util.Set;",
91             "import javax.inject.Provider;",
92             "",
93             "@Component(modules = {EmptySetModule.class, SetModule.class})",
94             "interface TestComponent {",
95             "  Set<String> strings();",
96             "  Set<Object> objects();",
97             "  Set<Integer> onlyContributionIsElementsIntoSet();",
98             "}");
99 
100     CompilerTests.daggerCompiler(emptySetModuleFile, setModuleFile, componentFile)
101         .withProcessingOptions(compilerMode.processorOptions())
102         .compile(
103             subject -> {
104               subject.hasErrorCount(0);
105               subject.generatedSource(
106                   goldenFileRule.goldenSource("test/DaggerTestComponent"));
107             });
108   }
109 
110   @Test
inaccessible()111   public void inaccessible() throws Exception {
112     Source inaccessible =
113         CompilerTests.javaSource(
114             "other.Inaccessible",
115             "package other;",
116             "",
117             "class Inaccessible {}");
118     Source inaccessible2 =
119         CompilerTests.javaSource(
120             "other.Inaccessible2",
121             "package other;",
122             "",
123             "class Inaccessible2 {}");
124     Source usesInaccessible =
125         CompilerTests.javaSource(
126             "other.UsesInaccessible",
127             "package other;",
128             "",
129             "import java.util.Set;",
130             "import javax.inject.Inject;",
131             "",
132             "public class UsesInaccessible {",
133             "  @Inject UsesInaccessible(Set<Inaccessible> set1, Set<Inaccessible2> set2) {}",
134             "}");
135 
136     Source module =
137         CompilerTests.javaSource(
138             "other.TestModule",
139             "package other;",
140             "",
141             "import dagger.Module;",
142             "import dagger.Provides;",
143             "import dagger.multibindings.ElementsIntoSet;",
144             "import dagger.multibindings.Multibinds;",
145             "import java.util.Collections;",
146             "import java.util.Set;",
147             "",
148             "@Module",
149             "public abstract class TestModule {",
150             "  @Multibinds abstract Set<Inaccessible> objects();",
151             "",
152             "  @Provides @ElementsIntoSet",
153             "  static Set<Inaccessible2> emptySet() { ",
154             "    return Collections.emptySet();",
155             "  }",
156             "}");
157     Source componentFile =
158         CompilerTests.javaSource(
159             "test.TestComponent",
160             "package test;",
161             "",
162             "import dagger.Component;",
163             "import java.util.Set;",
164             "import javax.inject.Provider;",
165             "import other.TestModule;",
166             "import other.UsesInaccessible;",
167             "",
168             "@Component(modules = TestModule.class)",
169             "interface TestComponent {",
170             "  UsesInaccessible usesInaccessible();",
171             "}");
172 
173     CompilerTests.daggerCompiler(
174             module, inaccessible, inaccessible2, usesInaccessible, componentFile)
175         .withProcessingOptions(compilerMode.processorOptions())
176         .compile(
177             subject -> {
178               subject.hasErrorCount(0);
179               subject.generatedSource(
180                   goldenFileRule.goldenSource("test/DaggerTestComponent"));
181             });
182   }
183 
184   @Test
subcomponentOmitsInheritedBindings()185   public void subcomponentOmitsInheritedBindings() throws Exception {
186     Source parent =
187         CompilerTests.javaSource(
188             "test.Parent",
189             "package test;",
190             "",
191             "import dagger.Component;",
192             "",
193             "@Component(modules = ParentModule.class)",
194             "interface Parent {",
195             "  Child child();",
196             "}");
197     Source parentModule =
198         CompilerTests.javaSource(
199             "test.ParentModule",
200             "package test;",
201             "",
202             "import dagger.Module;",
203             "import dagger.Provides;",
204             "import dagger.multibindings.IntoSet;",
205             "import dagger.multibindings.StringKey;",
206             "",
207             "@Module",
208             "class ParentModule {",
209             "  @Provides @IntoSet static Object parentObject() {",
210             "    return \"parent object\";",
211             "  }",
212             "}");
213     Source child =
214         CompilerTests.javaSource(
215             "test.Child",
216             "package test;",
217             "",
218             "import dagger.Subcomponent;",
219             "import java.util.Set;",
220             "",
221             "@Subcomponent",
222             "interface Child {",
223             "  Set<Object> objectSet();",
224             "}");
225 
226     CompilerTests.daggerCompiler(parent, parentModule, child)
227         .withProcessingOptions(compilerMode.processorOptions())
228         .compile(
229             subject -> {
230               subject.hasErrorCount(0);
231               subject.generatedSource(
232                   goldenFileRule.goldenSource("test/DaggerParent"));
233             });
234   }
235 
236   @Test
productionComponents()237   public void productionComponents() throws Exception {
238     Source emptySetModuleFile =
239         CompilerTests.javaSource(
240             "test.EmptySetModule",
241             "package test;",
242             "",
243             "import dagger.Module;",
244             "import dagger.Provides;",
245             "import dagger.multibindings.ElementsIntoSet;",
246             "import java.util.Collections;",
247             "import java.util.Set;",
248             "",
249             "@Module",
250             "abstract class EmptySetModule {",
251             "  @Provides @ElementsIntoSet",
252             "  static Set<String> emptySet() { ",
253             "    return Collections.emptySet();",
254             "  }",
255             "}");
256     Source componentFile =
257         CompilerTests.javaSource(
258             "test.TestComponent",
259             "package test;",
260             "",
261             "import com.google.common.util.concurrent.ListenableFuture;",
262             "import dagger.producers.ProductionComponent;",
263             "import java.util.Set;",
264             "",
265             "@ProductionComponent(modules = EmptySetModule.class)",
266             "interface TestComponent {",
267             "  ListenableFuture<Set<String>> strings();",
268             "}");
269 
270     CompilerTests.daggerCompiler(emptySetModuleFile, componentFile)
271         .withProcessingOptions(compilerMode.processorOptions())
272         .compile(
273             subject -> {
274               subject.hasErrorCount(0);
275               subject.generatedSource(
276                   goldenFileRule.goldenSource("test/DaggerTestComponent"));
277             });
278   }
279 }
280