xref: /aosp_15_r20/external/dagger2/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2014 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 androidx.room.compiler.processing.util.Source;
20*f585d8a3SJacky Wang import com.google.common.collect.ImmutableList;
21*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap;
22*f585d8a3SJacky Wang import dagger.testing.compile.CompilerTests;
23*f585d8a3SJacky Wang import org.junit.Test;
24*f585d8a3SJacky Wang import org.junit.runner.RunWith;
25*f585d8a3SJacky Wang import org.junit.runners.Parameterized;
26*f585d8a3SJacky Wang import org.junit.runners.Parameterized.Parameters;
27*f585d8a3SJacky Wang 
28*f585d8a3SJacky Wang @RunWith(Parameterized.class)
29*f585d8a3SJacky Wang public class MapMultibindingValidationTest {
30*f585d8a3SJacky Wang   @Parameters(name = "{0}")
parameters()31*f585d8a3SJacky Wang   public static ImmutableList<Object[]> parameters() {
32*f585d8a3SJacky Wang     return CompilerMode.TEST_PARAMETERS;
33*f585d8a3SJacky Wang   }
34*f585d8a3SJacky Wang 
35*f585d8a3SJacky Wang   private final CompilerMode compilerMode;
36*f585d8a3SJacky Wang 
MapMultibindingValidationTest(CompilerMode compilerMode)37*f585d8a3SJacky Wang   public MapMultibindingValidationTest(CompilerMode compilerMode) {
38*f585d8a3SJacky Wang     this.compilerMode = compilerMode;
39*f585d8a3SJacky Wang   }
40*f585d8a3SJacky Wang 
41*f585d8a3SJacky Wang   @Test
duplicateMapKeys_UnwrappedMapKey()42*f585d8a3SJacky Wang   public void duplicateMapKeys_UnwrappedMapKey() {
43*f585d8a3SJacky Wang     Source module =
44*f585d8a3SJacky Wang         CompilerTests.javaSource(
45*f585d8a3SJacky Wang             "test.MapModule",
46*f585d8a3SJacky Wang             "package test;",
47*f585d8a3SJacky Wang             "",
48*f585d8a3SJacky Wang             "import dagger.Module;",
49*f585d8a3SJacky Wang             "import dagger.Provides;",
50*f585d8a3SJacky Wang             "import dagger.multibindings.StringKey;",
51*f585d8a3SJacky Wang             "import dagger.multibindings.IntoMap;",
52*f585d8a3SJacky Wang             "",
53*f585d8a3SJacky Wang             "@Module",
54*f585d8a3SJacky Wang             "final class MapModule {",
55*f585d8a3SJacky Wang             "  @Provides @IntoMap @StringKey(\"AKey\") Object provideObjectForAKey() {",
56*f585d8a3SJacky Wang             "    return \"one\";",
57*f585d8a3SJacky Wang             "  }",
58*f585d8a3SJacky Wang             "",
59*f585d8a3SJacky Wang             "  @Provides @IntoMap @StringKey(\"AKey\") Object provideObjectForAKeyAgain() {",
60*f585d8a3SJacky Wang             "    return \"one again\";",
61*f585d8a3SJacky Wang             "  }",
62*f585d8a3SJacky Wang             "}");
63*f585d8a3SJacky Wang 
64*f585d8a3SJacky Wang     // If they're all there, report only Map<K, V>.
65*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
66*f585d8a3SJacky Wang             module,
67*f585d8a3SJacky Wang             component(
68*f585d8a3SJacky Wang                 "Map<String, Object> objects();",
69*f585d8a3SJacky Wang                 "Map<String, Provider<Object>> objectProviders();",
70*f585d8a3SJacky Wang                 "Producer<Map<String, Producer<Object>>> objectProducers();"))
71*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
72*f585d8a3SJacky Wang         .compile(
73*f585d8a3SJacky Wang             subject -> {
74*f585d8a3SJacky Wang               subject.hasErrorCount(1);
75*f585d8a3SJacky Wang               subject.hasErrorContaining(
76*f585d8a3SJacky Wang                   "The same map key is bound more than once for Map<String,Object>");
77*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForAKey()");
78*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForAKeyAgain()");
79*f585d8a3SJacky Wang             });
80*f585d8a3SJacky Wang 
81*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(module)
82*f585d8a3SJacky Wang         .withProcessingOptions(
83*f585d8a3SJacky Wang             ImmutableMap.<String, String>builder()
84*f585d8a3SJacky Wang                 .putAll(compilerMode.processorOptions())
85*f585d8a3SJacky Wang                 .put("dagger.fullBindingGraphValidation", "ERROR")
86*f585d8a3SJacky Wang                 .buildOrThrow())
87*f585d8a3SJacky Wang         .compile(
88*f585d8a3SJacky Wang             subject -> {
89*f585d8a3SJacky Wang               subject.hasErrorCount(1);
90*f585d8a3SJacky Wang               subject.hasErrorContaining(
91*f585d8a3SJacky Wang                       "The same map key is bound more than once for Map<String,Provider<Object>>")
92*f585d8a3SJacky Wang                   .onSource(module)
93*f585d8a3SJacky Wang                   .onLineContaining("class MapModule");
94*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForAKey()");
95*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForAKeyAgain()");
96*f585d8a3SJacky Wang             });
97*f585d8a3SJacky Wang 
98*f585d8a3SJacky Wang     // If there's Map<K, V> and Map<K, Provider<V>>, report only Map<K, V>.
99*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
100*f585d8a3SJacky Wang             module,
101*f585d8a3SJacky Wang             component(
102*f585d8a3SJacky Wang                 "Map<String, Object> objects();",
103*f585d8a3SJacky Wang                 "Map<String, Provider<Object>> objectProviders();"))
104*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
105*f585d8a3SJacky Wang         .compile(
106*f585d8a3SJacky Wang             subject -> {
107*f585d8a3SJacky Wang               subject.hasErrorCount(1);
108*f585d8a3SJacky Wang               subject.hasErrorContaining(
109*f585d8a3SJacky Wang                   "The same map key is bound more than once for Map<String,Object>");
110*f585d8a3SJacky Wang             });
111*f585d8a3SJacky Wang 
112*f585d8a3SJacky Wang     // If there's Map<K, V> and Map<K, Producer<V>>, report only Map<K, V>.
113*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
114*f585d8a3SJacky Wang             module,
115*f585d8a3SJacky Wang             component(
116*f585d8a3SJacky Wang                 "Map<String, Object> objects();",
117*f585d8a3SJacky Wang                 "Producer<Map<String, Producer<Object>>> objectProducers();"))
118*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
119*f585d8a3SJacky Wang         .compile(
120*f585d8a3SJacky Wang             subject -> {
121*f585d8a3SJacky Wang               subject.hasErrorCount(1);
122*f585d8a3SJacky Wang               subject.hasErrorContaining(
123*f585d8a3SJacky Wang                   "The same map key is bound more than once for Map<String,Object>");
124*f585d8a3SJacky Wang             });
125*f585d8a3SJacky Wang 
126*f585d8a3SJacky Wang     // If there's Map<K, Provider<V>> and Map<K, Producer<V>>, report only Map<K, Provider<V>>.
127*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
128*f585d8a3SJacky Wang             module,
129*f585d8a3SJacky Wang             component(
130*f585d8a3SJacky Wang                 "Map<String, Provider<Object>> objectProviders();",
131*f585d8a3SJacky Wang                 "Producer<Map<String, Producer<Object>>> objectProducers();"))
132*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
133*f585d8a3SJacky Wang         .compile(
134*f585d8a3SJacky Wang             subject -> {
135*f585d8a3SJacky Wang               subject.hasErrorCount(1);
136*f585d8a3SJacky Wang               subject.hasErrorContaining(
137*f585d8a3SJacky Wang                   "The same map key is bound more than once for Map<String,Provider<Object>>");
138*f585d8a3SJacky Wang             });
139*f585d8a3SJacky Wang 
140*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
141*f585d8a3SJacky Wang             module,
142*f585d8a3SJacky Wang             component("Map<String, Object> objects();"))
143*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
144*f585d8a3SJacky Wang         .compile(
145*f585d8a3SJacky Wang             subject -> {
146*f585d8a3SJacky Wang               subject.hasErrorCount(1);
147*f585d8a3SJacky Wang               subject.hasErrorContaining(
148*f585d8a3SJacky Wang                   "The same map key is bound more than once for Map<String,Object>");
149*f585d8a3SJacky Wang             });
150*f585d8a3SJacky Wang 
151*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
152*f585d8a3SJacky Wang             module,
153*f585d8a3SJacky Wang             component("Map<String, Provider<Object>> objectProviders();"))
154*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
155*f585d8a3SJacky Wang         .compile(
156*f585d8a3SJacky Wang             subject -> {
157*f585d8a3SJacky Wang               subject.hasErrorCount(1);
158*f585d8a3SJacky Wang               subject.hasErrorContaining(
159*f585d8a3SJacky Wang                   "The same map key is bound more than once for Map<String,Provider<Object>>");
160*f585d8a3SJacky Wang             });
161*f585d8a3SJacky Wang 
162*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
163*f585d8a3SJacky Wang             module,
164*f585d8a3SJacky Wang             component("Producer<Map<String, Producer<Object>>> objectProducers();"))
165*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
166*f585d8a3SJacky Wang         .compile(
167*f585d8a3SJacky Wang             subject -> {
168*f585d8a3SJacky Wang               subject.hasErrorCount(1);
169*f585d8a3SJacky Wang               subject.hasErrorContaining(
170*f585d8a3SJacky Wang                   "The same map key is bound more than once for Map<String,Producer<Object>>");
171*f585d8a3SJacky Wang             });
172*f585d8a3SJacky Wang   }
173*f585d8a3SJacky Wang 
174*f585d8a3SJacky Wang   @Test
duplicateMapKeys_WrappedMapKey()175*f585d8a3SJacky Wang   public void duplicateMapKeys_WrappedMapKey() {
176*f585d8a3SJacky Wang     Source module =
177*f585d8a3SJacky Wang         CompilerTests.javaSource(
178*f585d8a3SJacky Wang             "test.MapModule",
179*f585d8a3SJacky Wang             "package test;",
180*f585d8a3SJacky Wang             "",
181*f585d8a3SJacky Wang             "import dagger.Module;",
182*f585d8a3SJacky Wang             "import dagger.Provides;",
183*f585d8a3SJacky Wang             "import dagger.multibindings.IntoMap;",
184*f585d8a3SJacky Wang             "import dagger.MapKey;",
185*f585d8a3SJacky Wang             "",
186*f585d8a3SJacky Wang             "@Module",
187*f585d8a3SJacky Wang             "abstract class MapModule {",
188*f585d8a3SJacky Wang             "",
189*f585d8a3SJacky Wang             "  @MapKey(unwrapValue = false)",
190*f585d8a3SJacky Wang             "  @interface WrappedMapKey {",
191*f585d8a3SJacky Wang             "    String value();",
192*f585d8a3SJacky Wang             "  }",
193*f585d8a3SJacky Wang             "",
194*f585d8a3SJacky Wang             "  @Provides",
195*f585d8a3SJacky Wang             "  @IntoMap",
196*f585d8a3SJacky Wang             "  @WrappedMapKey(\"foo\")",
197*f585d8a3SJacky Wang             "  static String stringMapEntry1() { return \"\"; }",
198*f585d8a3SJacky Wang             "",
199*f585d8a3SJacky Wang             "  @Provides",
200*f585d8a3SJacky Wang             "  @IntoMap",
201*f585d8a3SJacky Wang             "  @WrappedMapKey(\"foo\")",
202*f585d8a3SJacky Wang             "  static String stringMapEntry2() { return \"\"; }",
203*f585d8a3SJacky Wang             "}");
204*f585d8a3SJacky Wang 
205*f585d8a3SJacky Wang     Source component = component("Map<test.MapModule.WrappedMapKey, String> objects();");
206*f585d8a3SJacky Wang 
207*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(module, component)
208*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
209*f585d8a3SJacky Wang         .compile(
210*f585d8a3SJacky Wang             subject -> {
211*f585d8a3SJacky Wang               subject.hasErrorCount(1);
212*f585d8a3SJacky Wang               subject.hasErrorContaining(
213*f585d8a3SJacky Wang                       String.join(
214*f585d8a3SJacky Wang                           "\n",
215*f585d8a3SJacky Wang                           "\033[1;31m[Dagger/MapKeys]\033[0m The same map key is bound more than "
216*f585d8a3SJacky Wang                               + "once for Map<MapModule.WrappedMapKey,String>",
217*f585d8a3SJacky Wang                           "    @Provides @IntoMap @MapModule.WrappedMapKey(\"foo\") String "
218*f585d8a3SJacky Wang                               + "MapModule.stringMapEntry1()",
219*f585d8a3SJacky Wang                           "    @Provides @IntoMap @MapModule.WrappedMapKey(\"foo\") String "
220*f585d8a3SJacky Wang                               + "MapModule.stringMapEntry2()"))
221*f585d8a3SJacky Wang                   .onSource(component)
222*f585d8a3SJacky Wang                   .onLineContaining("interface TestComponent");
223*f585d8a3SJacky Wang             });
224*f585d8a3SJacky Wang   }
225*f585d8a3SJacky Wang 
226*f585d8a3SJacky Wang   @Test
inconsistentMapKeyAnnotations()227*f585d8a3SJacky Wang   public void inconsistentMapKeyAnnotations() {
228*f585d8a3SJacky Wang     Source module =
229*f585d8a3SJacky Wang         CompilerTests.javaSource(
230*f585d8a3SJacky Wang             "test.MapModule",
231*f585d8a3SJacky Wang             "package test;",
232*f585d8a3SJacky Wang             "",
233*f585d8a3SJacky Wang             "import dagger.Module;",
234*f585d8a3SJacky Wang             "import dagger.Provides;",
235*f585d8a3SJacky Wang             "import dagger.multibindings.StringKey;",
236*f585d8a3SJacky Wang             "import dagger.multibindings.IntoMap;",
237*f585d8a3SJacky Wang             "",
238*f585d8a3SJacky Wang             "@Module",
239*f585d8a3SJacky Wang             "final class MapModule {",
240*f585d8a3SJacky Wang             "  @Provides @IntoMap @StringKey(\"AKey\") Object provideObjectForAKey() {",
241*f585d8a3SJacky Wang             "    return \"one\";",
242*f585d8a3SJacky Wang             "  }",
243*f585d8a3SJacky Wang             "",
244*f585d8a3SJacky Wang             "  @Provides @IntoMap @StringKeyTwo(\"BKey\") Object provideObjectForBKey() {",
245*f585d8a3SJacky Wang             "    return \"two\";",
246*f585d8a3SJacky Wang             "  }",
247*f585d8a3SJacky Wang             "}");
248*f585d8a3SJacky Wang     Source stringKeyTwoFile =
249*f585d8a3SJacky Wang         CompilerTests.javaSource(
250*f585d8a3SJacky Wang             "test.StringKeyTwo",
251*f585d8a3SJacky Wang             "package test;",
252*f585d8a3SJacky Wang             "",
253*f585d8a3SJacky Wang             "import dagger.MapKey;",
254*f585d8a3SJacky Wang             "",
255*f585d8a3SJacky Wang             "@MapKey(unwrapValue = true)",
256*f585d8a3SJacky Wang             "public @interface StringKeyTwo {",
257*f585d8a3SJacky Wang             "  String value();",
258*f585d8a3SJacky Wang             "}");
259*f585d8a3SJacky Wang 
260*f585d8a3SJacky Wang     // If they're all there, report only Map<K, V>.
261*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
262*f585d8a3SJacky Wang             module,
263*f585d8a3SJacky Wang             stringKeyTwoFile,
264*f585d8a3SJacky Wang             component(
265*f585d8a3SJacky Wang                 "Map<String, Object> objects();",
266*f585d8a3SJacky Wang                 "Map<String, Provider<Object>> objectProviders();",
267*f585d8a3SJacky Wang                 "Producer<Map<String, Producer<Object>>> objectProducers();"))
268*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
269*f585d8a3SJacky Wang         .compile(
270*f585d8a3SJacky Wang             subject -> {
271*f585d8a3SJacky Wang               subject.hasErrorCount(1);
272*f585d8a3SJacky Wang               subject.hasErrorContaining(
273*f585d8a3SJacky Wang                   "Map<String,Object> uses more than one @MapKey annotation type");
274*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForAKey()");
275*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForBKey()");
276*f585d8a3SJacky Wang             });
277*f585d8a3SJacky Wang 
278*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(module, stringKeyTwoFile)
279*f585d8a3SJacky Wang         .withProcessingOptions(
280*f585d8a3SJacky Wang             ImmutableMap.<String, String>builder()
281*f585d8a3SJacky Wang                 .putAll(compilerMode.processorOptions())
282*f585d8a3SJacky Wang                 .put("dagger.fullBindingGraphValidation", "ERROR")
283*f585d8a3SJacky Wang                 .buildOrThrow())
284*f585d8a3SJacky Wang         .compile(
285*f585d8a3SJacky Wang             subject -> {
286*f585d8a3SJacky Wang               subject.hasErrorCount(1);
287*f585d8a3SJacky Wang               subject.hasErrorContaining(
288*f585d8a3SJacky Wang                       "Map<String,Provider<Object>> uses more than one @MapKey annotation type")
289*f585d8a3SJacky Wang                   .onSource(module)
290*f585d8a3SJacky Wang                   .onLineContaining("class MapModule");
291*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForAKey()");
292*f585d8a3SJacky Wang               subject.hasErrorContaining("provideObjectForBKey()");
293*f585d8a3SJacky Wang             });
294*f585d8a3SJacky Wang 
295*f585d8a3SJacky Wang     // If there's Map<K, V> and Map<K, Provider<V>>, report only Map<K, V>.
296*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
297*f585d8a3SJacky Wang             module,
298*f585d8a3SJacky Wang             stringKeyTwoFile,
299*f585d8a3SJacky Wang             component(
300*f585d8a3SJacky Wang                 "Map<String, Object> objects();",
301*f585d8a3SJacky Wang                 "Map<String, Provider<Object>> objectProviders();"))
302*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
303*f585d8a3SJacky Wang         .compile(
304*f585d8a3SJacky Wang             subject -> {
305*f585d8a3SJacky Wang               subject.hasErrorCount(1);
306*f585d8a3SJacky Wang               subject.hasErrorContaining(
307*f585d8a3SJacky Wang                   "Map<String,Object> uses more than one @MapKey annotation type");
308*f585d8a3SJacky Wang             });
309*f585d8a3SJacky Wang 
310*f585d8a3SJacky Wang     // If there's Map<K, V> and Map<K, Producer<V>>, report only Map<K, V>.
311*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
312*f585d8a3SJacky Wang             module,
313*f585d8a3SJacky Wang             stringKeyTwoFile,
314*f585d8a3SJacky Wang             component(
315*f585d8a3SJacky Wang                 "Map<String, Object> objects();",
316*f585d8a3SJacky Wang                 "Producer<Map<String, Producer<Object>>> objectProducers();"))
317*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
318*f585d8a3SJacky Wang         .compile(
319*f585d8a3SJacky Wang             subject -> {
320*f585d8a3SJacky Wang               subject.hasErrorCount(1);
321*f585d8a3SJacky Wang               subject.hasErrorContaining(
322*f585d8a3SJacky Wang                   "Map<String,Object> uses more than one @MapKey annotation type");
323*f585d8a3SJacky Wang             });
324*f585d8a3SJacky Wang 
325*f585d8a3SJacky Wang     // If there's Map<K, Provider<V>> and Map<K, Producer<V>>, report only Map<K, Provider<V>>.
326*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
327*f585d8a3SJacky Wang             module,
328*f585d8a3SJacky Wang             stringKeyTwoFile,
329*f585d8a3SJacky Wang             component(
330*f585d8a3SJacky Wang                 "Map<String, Provider<Object>> objectProviders();",
331*f585d8a3SJacky Wang                 "Producer<Map<String, Producer<Object>>> objectProducers();"))
332*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
333*f585d8a3SJacky Wang         .compile(
334*f585d8a3SJacky Wang             subject -> {
335*f585d8a3SJacky Wang               subject.hasErrorCount(1);
336*f585d8a3SJacky Wang               subject.hasErrorContaining(
337*f585d8a3SJacky Wang                   "Map<String,Provider<Object>> uses more than one @MapKey annotation type");
338*f585d8a3SJacky Wang             });
339*f585d8a3SJacky Wang 
340*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
341*f585d8a3SJacky Wang             module,
342*f585d8a3SJacky Wang             stringKeyTwoFile,
343*f585d8a3SJacky Wang             component("Map<String, Object> objects();"))
344*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
345*f585d8a3SJacky Wang         .compile(
346*f585d8a3SJacky Wang             subject -> {
347*f585d8a3SJacky Wang               subject.hasErrorCount(1);
348*f585d8a3SJacky Wang               subject.hasErrorContaining(
349*f585d8a3SJacky Wang                   "Map<String,Object> uses more than one @MapKey annotation type");
350*f585d8a3SJacky Wang             });
351*f585d8a3SJacky Wang 
352*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
353*f585d8a3SJacky Wang             module,
354*f585d8a3SJacky Wang             stringKeyTwoFile,
355*f585d8a3SJacky Wang             component("Map<String, Provider<Object>> objectProviders();"))
356*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
357*f585d8a3SJacky Wang         .compile(
358*f585d8a3SJacky Wang             subject -> {
359*f585d8a3SJacky Wang               subject.hasErrorCount(1);
360*f585d8a3SJacky Wang               subject.hasErrorContaining(
361*f585d8a3SJacky Wang                   "Map<String,Provider<Object>> uses more than one @MapKey annotation type");
362*f585d8a3SJacky Wang             });
363*f585d8a3SJacky Wang 
364*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
365*f585d8a3SJacky Wang             module,
366*f585d8a3SJacky Wang             stringKeyTwoFile,
367*f585d8a3SJacky Wang             component("Producer<Map<String, Producer<Object>>> objectProducers();"))
368*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
369*f585d8a3SJacky Wang         .compile(
370*f585d8a3SJacky Wang             subject -> {
371*f585d8a3SJacky Wang               subject.hasErrorCount(1);
372*f585d8a3SJacky Wang               subject.hasErrorContaining(
373*f585d8a3SJacky Wang                   "Map<String,Producer<Object>> uses more than one @MapKey annotation type");
374*f585d8a3SJacky Wang             });
375*f585d8a3SJacky Wang   }
376*f585d8a3SJacky Wang 
component(String... entryPoints)377*f585d8a3SJacky Wang   private static Source component(String... entryPoints) {
378*f585d8a3SJacky Wang     return CompilerTests.javaSource(
379*f585d8a3SJacky Wang         "test.TestComponent",
380*f585d8a3SJacky Wang         ImmutableList.<String>builder()
381*f585d8a3SJacky Wang             .add(
382*f585d8a3SJacky Wang                 "package test;",
383*f585d8a3SJacky Wang                 "",
384*f585d8a3SJacky Wang                 "import dagger.Component;",
385*f585d8a3SJacky Wang                 "import dagger.producers.Producer;",
386*f585d8a3SJacky Wang                 "import java.util.Map;",
387*f585d8a3SJacky Wang                 "import javax.inject.Provider;",
388*f585d8a3SJacky Wang                 "",
389*f585d8a3SJacky Wang                 "@Component(modules = {MapModule.class})",
390*f585d8a3SJacky Wang                 "interface TestComponent {")
391*f585d8a3SJacky Wang             .add(entryPoints)
392*f585d8a3SJacky Wang             .add("}")
393*f585d8a3SJacky Wang             .build());
394*f585d8a3SJacky Wang   }
395*f585d8a3SJacky Wang }
396