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