xref: /aosp_15_r20/external/dagger2/javatests/dagger/internal/codegen/ComponentShardTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
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 java.util.stream.Collectors.joining;
20 
21 import androidx.room.compiler.processing.util.Source;
22 import com.google.common.collect.ImmutableList;
23 import com.google.common.collect.ImmutableMap;
24 import dagger.testing.compile.CompilerTests;
25 import dagger.testing.golden.GoldenFileRule;
26 import java.util.Arrays;
27 import org.junit.Rule;
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 ComponentShardTest {
35   private static final int BINDINGS_PER_SHARD = 2;
36 
37   @Parameters(name = "{0}")
parameters()38   public static ImmutableList<Object[]> parameters() {
39     return CompilerMode.TEST_PARAMETERS;
40   }
41 
42   @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule();
43 
44   private final CompilerMode compilerMode;
45 
ComponentShardTest(CompilerMode compilerMode)46   public ComponentShardTest(CompilerMode compilerMode) {
47     this.compilerMode = compilerMode;
48   }
49 
50   @Test
testNewShardCreated()51   public void testNewShardCreated() throws Exception {
52     // Add all bindings.
53     //
54     //     1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7
55     //          ^--------/
56     //
57     ImmutableList.Builder<Source> sources = ImmutableList.builder();
58     sources
59         // Shard 2: Bindings (1)
60         .add(createBinding("Binding1", "Binding2 binding2"))
61         // Shard 1: Bindings (2, 3, 4, 5). Contains more than 2 bindings due to cycle.
62         .add(createBinding("Binding2", "Binding3 binding3"))
63         .add(createBinding("Binding3", "Binding4 binding4"))
64         .add(createBinding("Binding4", "Binding5 binding5, Provider<Binding2> binding2Provider"))
65         .add(createBinding("Binding5", "Binding6 binding6"))
66         // Component shard: Bindings (6, 7)
67         .add(createBinding("Binding6", "Binding7 binding7"))
68         .add(createBinding("Binding7"));
69 
70     // Add the component with entry points for each binding and its provider.
71     sources.add(
72         CompilerTests.javaSource(
73             "dagger.internal.codegen.TestComponent",
74             "package dagger.internal.codegen;",
75             "",
76             "import dagger.Component;",
77             "import javax.inject.Provider;",
78             "import javax.inject.Singleton;",
79             "",
80             "@Singleton",
81             "@Component",
82             "interface TestComponent {",
83             "  Binding1 binding1();",
84             "  Binding2 binding2();",
85             "  Binding3 binding3();",
86             "  Binding4 binding4();",
87             "  Binding5 binding5();",
88             "  Binding6 binding6();",
89             "  Binding7 binding7();",
90             "  Provider<Binding1> providerBinding1();",
91             "  Provider<Binding2> providerBinding2();",
92             "  Provider<Binding3> providerBinding3();",
93             "  Provider<Binding4> providerBinding4();",
94             "  Provider<Binding5> providerBinding5();",
95             "  Provider<Binding6> providerBinding6();",
96             "  Provider<Binding7> providerBinding7();",
97             "}"));
98 
99     CompilerTests.daggerCompiler(sources.build())
100         .withProcessingOptions(compilerOptions())
101         .compile(
102             subject -> {
103               subject.hasErrorCount(0);
104               subject.generatedSource(
105                   goldenFileRule.goldenSource("dagger/internal/codegen/DaggerTestComponent"));
106             });
107   }
108 
109   @Test
testNewShardCreatedWithDependencies()110   public void testNewShardCreatedWithDependencies() throws Exception {
111     ImmutableList.Builder<Source> sources = ImmutableList.builder();
112     sources.add(
113         createBinding("Binding1"),
114         createBinding("Binding2"),
115         CompilerTests.javaSource(
116             "dagger.internal.codegen.Binding3",
117             "package dagger.internal.codegen;",
118             "",
119             "class Binding3 {}"),
120         CompilerTests.javaSource(
121             "dagger.internal.codegen.Dependency",
122             "package dagger.internal.codegen;",
123             "",
124             "interface Dependency {",
125             "  Binding3 binding3();",
126             "}"),
127         CompilerTests.javaSource(
128             "dagger.internal.codegen.TestComponent",
129             "package dagger.internal.codegen;",
130             "",
131             "import dagger.Component;",
132             "import javax.inject.Provider;",
133             "import javax.inject.Singleton;",
134             "",
135             "@Singleton",
136             "@Component(dependencies = Dependency.class)",
137             "interface TestComponent {",
138             "  Binding1 binding1();",
139             "  Binding2 binding2();",
140             "  Binding3 binding3();",
141             "  Provider<Binding1> providerBinding1();",
142             "  Provider<Binding2> providerBinding2();",
143             "  Provider<Binding3> providerBinding3();",
144             "}"));
145 
146     CompilerTests.daggerCompiler(sources.build())
147         .withProcessingOptions(compilerOptions())
148         .compile(
149             subject -> {
150               subject.hasErrorCount(0);
151               subject.generatedSource(
152                   goldenFileRule.goldenSource("dagger/internal/codegen/DaggerTestComponent"));
153             });
154   }
155 
156   @Test
testNewShardSubcomponentCreated()157   public void testNewShardSubcomponentCreated() throws Exception {
158     ImmutableList.Builder<Source> sources = ImmutableList.builder();
159     sources.add(
160         CompilerTests.javaSource(
161             "dagger.internal.codegen.SubcomponentScope",
162             "package dagger.internal.codegen;",
163             "",
164             "import javax.inject.Scope;",
165             "",
166             "@Scope",
167             "public @interface SubcomponentScope {}"),
168         CompilerTests.javaSource(
169             "dagger.internal.codegen.Binding1",
170             "package dagger.internal.codegen;",
171             "",
172             "@SubcomponentScope",
173             "final class Binding1 {",
174             "  @javax.inject.Inject Binding1() {}",
175             "}"),
176         CompilerTests.javaSource(
177             "dagger.internal.codegen.Binding2",
178             "package dagger.internal.codegen;",
179             "",
180             "@SubcomponentScope",
181             "final class Binding2 {",
182             "  @javax.inject.Inject Binding2() {}",
183             "}"),
184         CompilerTests.javaSource(
185             "dagger.internal.codegen.Binding3",
186             "package dagger.internal.codegen;",
187             "",
188             "@SubcomponentScope",
189             "final class Binding3 {",
190             "  @javax.inject.Inject Binding3() {}",
191             "}"),
192         CompilerTests.javaSource(
193             "dagger.internal.codegen.TestComponent",
194             "package dagger.internal.codegen;",
195             "",
196             "import dagger.Component;",
197             "",
198             "@Component",
199             "interface TestComponent {",
200             "  TestSubcomponent subcomponent();",
201             "}"),
202         CompilerTests.javaSource(
203             "dagger.internal.codegen.TestSubcomponent",
204             "package dagger.internal.codegen;",
205             "",
206             "import dagger.Subcomponent;",
207             "import javax.inject.Provider;",
208             "",
209             "@SubcomponentScope",
210             "@Subcomponent",
211             "interface TestSubcomponent {",
212             "  Binding1 binding1();",
213             "  Binding2 binding2();",
214             "  Binding3 binding3();",
215             "  Provider<Binding1> providerBinding1();",
216             "  Provider<Binding2> providerBinding2();",
217             "  Provider<Binding3> providerBinding3();",
218             "}"));
219 
220     CompilerTests.daggerCompiler(sources.build())
221         .withProcessingOptions(compilerOptions())
222         .compile(
223             subject -> {
224               subject.hasErrorCount(0);
225               subject.generatedSource(
226                   goldenFileRule.goldenSource("dagger/internal/codegen/DaggerTestComponent"));
227             });
228   }
229 
createBinding(String bindingName, String... deps)230   private static Source createBinding(String bindingName, String... deps) {
231     return CompilerTests.javaSource(
232         "dagger.internal.codegen." + bindingName,
233         "package dagger.internal.codegen;",
234         "",
235         "import javax.inject.Inject;",
236         "import javax.inject.Provider;",
237         "import javax.inject.Singleton;",
238         "",
239         "@Singleton",
240         "final class " + bindingName + " {",
241         "  @Inject",
242         "  " + bindingName + "(" + Arrays.stream(deps).collect(joining(", ")) + ") {}",
243         "}");
244   }
245 
compilerOptions()246   private ImmutableMap<String, String> compilerOptions() {
247     return ImmutableMap.<String, String>builder()
248         .putAll(compilerMode.processorOptions())
249         .put("dagger.generatedClassExtendsComponent", "DISABLED")
250         .put("dagger.keysPerComponentShard", Integer.toString(BINDINGS_PER_SHARD))
251         .buildOrThrow();
252   }
253 }
254