xref: /aosp_15_r20/external/dagger2/javatests/dagger/internal/codegen/SwitchingProviderTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1 /*
2  * Copyright (C) 2014 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.ImmutableList;
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 SwitchingProviderTest {
31   @Parameters(name = "{0}")
parameters()32   public static ImmutableList<Object[]> parameters() {
33     return CompilerMode.TEST_PARAMETERS;
34   }
35 
36   @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule();
37 
38   private final CompilerMode compilerMode;
39 
SwitchingProviderTest(CompilerMode compilerMode)40   public SwitchingProviderTest(CompilerMode compilerMode) {
41     this.compilerMode = compilerMode;
42   }
43 
44   @Test
switchingProviderTest()45   public void switchingProviderTest() throws Exception {
46     ImmutableList.Builder<Source> sources = ImmutableList.builder();
47     StringBuilder entryPoints = new StringBuilder();
48     for (int i = 0; i <= 100; i++) {
49       String bindingName = "Binding" + i;
50       sources.add(
51           CompilerTests.javaSource(
52               "test." + bindingName,
53               "package test;",
54               "",
55               "import javax.inject.Inject;",
56               "",
57               "final class " + bindingName + " {",
58               "  @Inject",
59               "  " + bindingName + "() {}",
60               "}"));
61       entryPoints.append(String.format("  Provider<%1$s> get%1$sProvider();\n", bindingName));
62     }
63 
64     sources.add(
65         CompilerTests.javaSource(
66             "test.TestComponent",
67             "package test;",
68             "",
69             "import dagger.Component;",
70             "import javax.inject.Provider;",
71             "",
72             "@Component",
73             "interface TestComponent {",
74             entryPoints.toString(),
75             "}"));
76 
77     CompilerTests.daggerCompiler(sources.build())
78         .withProcessingOptions(compilerMode.processorOptions())
79         .compile(
80             subject -> {
81               subject.hasErrorCount(0);
82               subject.hasWarningCount(0);
83               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
84             });
85   }
86 
87   @Test
unscopedBinds()88   public void unscopedBinds() throws Exception {
89     Source module =
90         CompilerTests.javaSource(
91             "test.TestModule",
92             "package test;",
93             "",
94             "import dagger.Binds;",
95             "import dagger.Module;",
96             "import dagger.Provides;",
97             "",
98             "@Module",
99             "interface TestModule {",
100             "  @Provides",
101             "  static String s() {",
102             "    return new String();",
103             "  }",
104             "",
105             "  @Binds CharSequence c(String s);",
106             "  @Binds Object o(CharSequence c);",
107             "}");
108     Source component =
109         CompilerTests.javaSource(
110             "test.TestComponent",
111             "package test;",
112             "",
113             "import dagger.Component;",
114             "import javax.inject.Provider;",
115             "",
116             "@Component(modules = TestModule.class)",
117             "interface TestComponent {",
118             "  Provider<Object> objectProvider();",
119             "  Provider<CharSequence> charSequenceProvider();",
120             "}");
121 
122     CompilerTests.daggerCompiler(module, component)
123         .withProcessingOptions(compilerMode.processorOptions())
124         .compile(
125             subject -> {
126               subject.hasErrorCount(0);
127               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
128             });
129   }
130 
131   @Test
scopedBinds()132   public void scopedBinds() throws Exception {
133     Source module =
134         CompilerTests.javaSource(
135             "test.TestModule",
136             "package test;",
137             "",
138             "import dagger.Binds;",
139             "import dagger.Module;",
140             "import dagger.Provides;",
141             "import javax.inject.Singleton;",
142             "",
143             "@Module",
144             "interface TestModule {",
145             "  @Provides",
146             "  static String s() {",
147             "    return new String();",
148             "  }",
149             "",
150             "  @Binds @Singleton Object o(CharSequence s);",
151             "  @Binds @Singleton CharSequence c(String s);",
152             "}");
153     Source component =
154         CompilerTests.javaSource(
155             "test.TestComponent",
156             "package test;",
157             "",
158             "import dagger.Component;",
159             "import javax.inject.Provider;",
160             "import javax.inject.Singleton;",
161             "",
162             "@Singleton",
163             "@Component(modules = TestModule.class)",
164             "interface TestComponent {",
165             "  Provider<Object> objectProvider();",
166             "  Provider<CharSequence> charSequenceProvider();",
167             "}");
168 
169     CompilerTests.daggerCompiler(module, component)
170         .withProcessingOptions(compilerMode.processorOptions())
171         .compile(
172             subject -> {
173               subject.hasErrorCount(0);
174               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
175             });
176   }
177 
178   @Test
emptyMultibindings_avoidSwitchProviders()179   public void emptyMultibindings_avoidSwitchProviders() throws Exception {
180     Source module =
181         CompilerTests.javaSource(
182             "test.TestModule",
183             "package test;",
184             "",
185             "import dagger.multibindings.Multibinds;",
186             "import dagger.Module;",
187             "import java.util.Map;",
188             "import java.util.Set;",
189             "",
190             "@Module",
191             "interface TestModule {",
192             "  @Multibinds Set<String> set();",
193             "  @Multibinds Map<String, String> map();",
194             "}");
195     Source component =
196         CompilerTests.javaSource(
197             "test.TestComponent",
198             "package test;",
199             "",
200             "import dagger.Component;",
201             "import java.util.Map;",
202             "import java.util.Set;",
203             "import javax.inject.Provider;",
204             "",
205             "@Component(modules = TestModule.class)",
206             "interface TestComponent {",
207             "  Provider<Set<String>> setProvider();",
208             "  Provider<Map<String, String>> mapProvider();",
209             "}");
210 
211     CompilerTests.daggerCompiler(module, component)
212         .withProcessingOptions(compilerMode.processorOptions())
213         .compile(
214             subject -> {
215               subject.hasErrorCount(0);
216               subject.hasWarningCount(0);
217               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
218             });
219   }
220 
221   @Test
memberInjectors()222   public void memberInjectors() throws Exception {
223     Source foo =
224         CompilerTests.javaSource(
225             "test.Foo",
226             "package test;",
227             "",
228             "class Foo {}");
229     Source component =
230         CompilerTests.javaSource(
231             "test.TestComponent",
232             "package test;",
233             "",
234             "import dagger.Component;",
235             "import dagger.MembersInjector;",
236             "import javax.inject.Provider;",
237             "",
238             "@Component",
239             "interface TestComponent {",
240             "  Provider<MembersInjector<Foo>> providerOfMembersInjector();",
241             "}");
242 
243     CompilerTests.daggerCompiler(foo, component)
244         .withProcessingOptions(compilerMode.processorOptions())
245         .compile(
246             subject -> {
247               subject.hasErrorCount(0);
248               subject.hasWarningCount(0);
249               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
250             });
251   }
252 
253   @Test
optionals()254   public void optionals() throws Exception {
255     Source present =
256         CompilerTests.javaSource(
257             "test.Present",
258             "package test;",
259             "",
260             "class Present {}");
261     Source absent =
262         CompilerTests.javaSource(
263             "test.Absent",
264             "package test;",
265             "",
266             "class Absent {}");
267     Source module =
268         CompilerTests.javaSource(
269             "test.TestModule",
270             "package test;",
271             "",
272             "import dagger.BindsOptionalOf;",
273             "import dagger.Module;",
274             "import dagger.Provides;",
275             "",
276             "@Module",
277             "interface TestModule {",
278             "  @BindsOptionalOf Present bindOptionalOfPresent();",
279             "  @BindsOptionalOf Absent bindOptionalOfAbsent();",
280             "",
281             "  @Provides static Present p() { return new Present(); }",
282             "}");
283     Source component =
284         CompilerTests.javaSource(
285             "test.TestComponent",
286             "package test;",
287             "",
288             "import dagger.Component;",
289             "import java.util.Optional;",
290             "import javax.inject.Provider;",
291             "",
292             "@Component(modules = TestModule.class)",
293             "interface TestComponent {",
294             "  Provider<Optional<Present>> providerOfOptionalOfPresent();",
295             "  Provider<Optional<Absent>> providerOfOptionalOfAbsent();",
296             "}");
297 
298     CompilerTests.daggerCompiler(present, absent, module, component)
299         .withProcessingOptions(compilerMode.processorOptions())
300         .compile(
301             subject -> {
302               subject.hasErrorCount(0);
303               subject.hasWarningCount(0);
304               subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent"));
305             });
306   }
307 }
308