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