1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2018 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 dagger.internal.codegen.TestUtils.endsWithMessage; 20*f585d8a3SJacky Wang 21*f585d8a3SJacky Wang import androidx.room.compiler.processing.util.Source; 22*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap; 23*f585d8a3SJacky Wang import dagger.testing.compile.CompilerTests; 24*f585d8a3SJacky Wang import java.util.regex.Pattern; 25*f585d8a3SJacky Wang import org.junit.Test; 26*f585d8a3SJacky Wang import org.junit.runner.RunWith; 27*f585d8a3SJacky Wang import org.junit.runners.JUnit4; 28*f585d8a3SJacky Wang 29*f585d8a3SJacky Wang @RunWith(JUnit4.class) 30*f585d8a3SJacky Wang public final class FullBindingGraphValidationTest { 31*f585d8a3SJacky Wang private static final Source MODULE_WITH_ERRORS = 32*f585d8a3SJacky Wang CompilerTests.javaSource( 33*f585d8a3SJacky Wang "test.ModuleWithErrors", 34*f585d8a3SJacky Wang "package test;", 35*f585d8a3SJacky Wang "", 36*f585d8a3SJacky Wang "import dagger.Binds;", 37*f585d8a3SJacky Wang "import dagger.Module;", 38*f585d8a3SJacky Wang "", 39*f585d8a3SJacky Wang "@Module", 40*f585d8a3SJacky Wang "interface ModuleWithErrors {", 41*f585d8a3SJacky Wang " @Binds Object object1(String string);", 42*f585d8a3SJacky Wang " @Binds Object object2(Long l);", 43*f585d8a3SJacky Wang " @Binds Number missingDependency(Integer i);", 44*f585d8a3SJacky Wang "}"); 45*f585d8a3SJacky Wang 46*f585d8a3SJacky Wang // Make sure the error doesn't show other bindings or a dependency trace afterwards. 47*f585d8a3SJacky Wang private static final Pattern MODULE_WITH_ERRORS_MESSAGE = 48*f585d8a3SJacky Wang endsWithMessage( 49*f585d8a3SJacky Wang "\033[1;31m[Dagger/DuplicateBindings]\033[0m Object is bound multiple times:", 50*f585d8a3SJacky Wang " @Binds Object ModuleWithErrors.object1(String)", 51*f585d8a3SJacky Wang " @Binds Object ModuleWithErrors.object2(Long)", 52*f585d8a3SJacky Wang " in component: [ModuleWithErrors]", 53*f585d8a3SJacky Wang "", 54*f585d8a3SJacky Wang "======================", 55*f585d8a3SJacky Wang "Full classname legend:", 56*f585d8a3SJacky Wang "======================", 57*f585d8a3SJacky Wang "ModuleWithErrors: test.ModuleWithErrors", 58*f585d8a3SJacky Wang "========================", 59*f585d8a3SJacky Wang "End of classname legend:", 60*f585d8a3SJacky Wang "========================"); 61*f585d8a3SJacky Wang 62*f585d8a3SJacky Wang private static final Pattern INCLUDES_MODULE_WITH_ERRORS_MESSAGE = 63*f585d8a3SJacky Wang endsWithMessage( 64*f585d8a3SJacky Wang "\033[1;31m[Dagger/DuplicateBindings]\033[0m Object is bound multiple times:", 65*f585d8a3SJacky Wang " @Binds Object ModuleWithErrors.object1(String)", 66*f585d8a3SJacky Wang " @Binds Object ModuleWithErrors.object2(Long)", 67*f585d8a3SJacky Wang " in component: [IncludesModuleWithErrors]", 68*f585d8a3SJacky Wang "", 69*f585d8a3SJacky Wang "======================", 70*f585d8a3SJacky Wang "Full classname legend:", 71*f585d8a3SJacky Wang "======================", 72*f585d8a3SJacky Wang "IncludesModuleWithErrors: test.IncludesModuleWithErrors", 73*f585d8a3SJacky Wang "ModuleWithErrors: test.ModuleWithErrors", 74*f585d8a3SJacky Wang "========================", 75*f585d8a3SJacky Wang "End of classname legend:", 76*f585d8a3SJacky Wang "========================"); 77*f585d8a3SJacky Wang 78*f585d8a3SJacky Wang @Test moduleWithErrors_validationTypeNone()79*f585d8a3SJacky Wang public void moduleWithErrors_validationTypeNone() { 80*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS) 81*f585d8a3SJacky Wang .compile( 82*f585d8a3SJacky Wang subject -> { 83*f585d8a3SJacky Wang subject.hasErrorCount(0); 84*f585d8a3SJacky Wang subject.hasWarningCount(0); 85*f585d8a3SJacky Wang }); 86*f585d8a3SJacky Wang } 87*f585d8a3SJacky Wang 88*f585d8a3SJacky Wang @Test moduleWithErrors_validationTypeError()89*f585d8a3SJacky Wang public void moduleWithErrors_validationTypeError() { 90*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS) 91*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "ERROR")) 92*f585d8a3SJacky Wang .compile( 93*f585d8a3SJacky Wang subject -> { 94*f585d8a3SJacky Wang subject.hasErrorCount(1); 95*f585d8a3SJacky Wang subject.hasErrorContainingMatch(MODULE_WITH_ERRORS_MESSAGE.pattern()) 96*f585d8a3SJacky Wang .onSource(MODULE_WITH_ERRORS) 97*f585d8a3SJacky Wang .onLineContaining("interface ModuleWithErrors"); 98*f585d8a3SJacky Wang }); 99*f585d8a3SJacky Wang } 100*f585d8a3SJacky Wang 101*f585d8a3SJacky Wang @Test moduleWithErrors_validationTypeWarning()102*f585d8a3SJacky Wang public void moduleWithErrors_validationTypeWarning() { 103*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS) 104*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "WARNING")) 105*f585d8a3SJacky Wang .compile( 106*f585d8a3SJacky Wang subject -> { 107*f585d8a3SJacky Wang subject.hasErrorCount(0); 108*f585d8a3SJacky Wang subject.hasWarningCount(1); 109*f585d8a3SJacky Wang subject.hasWarningContainingMatch(MODULE_WITH_ERRORS_MESSAGE.pattern()) 110*f585d8a3SJacky Wang .onSource(MODULE_WITH_ERRORS) 111*f585d8a3SJacky Wang .onLineContaining("interface ModuleWithErrors"); 112*f585d8a3SJacky Wang }); 113*f585d8a3SJacky Wang } 114*f585d8a3SJacky Wang 115*f585d8a3SJacky Wang private static final Source INCLUDES_MODULE_WITH_ERRORS = 116*f585d8a3SJacky Wang CompilerTests.javaSource( 117*f585d8a3SJacky Wang "test.IncludesModuleWithErrors", 118*f585d8a3SJacky Wang "package test;", 119*f585d8a3SJacky Wang "", 120*f585d8a3SJacky Wang "import dagger.Binds;", 121*f585d8a3SJacky Wang "import dagger.Module;", 122*f585d8a3SJacky Wang "", 123*f585d8a3SJacky Wang "@Module(includes = ModuleWithErrors.class)", 124*f585d8a3SJacky Wang "interface IncludesModuleWithErrors {}"); 125*f585d8a3SJacky Wang 126*f585d8a3SJacky Wang @Test includesModuleWithErrors_validationTypeNone()127*f585d8a3SJacky Wang public void includesModuleWithErrors_validationTypeNone() { 128*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS, INCLUDES_MODULE_WITH_ERRORS) 129*f585d8a3SJacky Wang .compile( 130*f585d8a3SJacky Wang subject -> { 131*f585d8a3SJacky Wang subject.hasErrorCount(0); 132*f585d8a3SJacky Wang subject.hasWarningCount(0); 133*f585d8a3SJacky Wang }); 134*f585d8a3SJacky Wang } 135*f585d8a3SJacky Wang 136*f585d8a3SJacky Wang @Test includesModuleWithErrors_validationTypeError()137*f585d8a3SJacky Wang public void includesModuleWithErrors_validationTypeError() { 138*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS, INCLUDES_MODULE_WITH_ERRORS) 139*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "ERROR")) 140*f585d8a3SJacky Wang .compile( 141*f585d8a3SJacky Wang subject -> { 142*f585d8a3SJacky Wang subject.hasErrorCount(2); 143*f585d8a3SJacky Wang subject.hasErrorContainingMatch(MODULE_WITH_ERRORS_MESSAGE.pattern()) 144*f585d8a3SJacky Wang .onSource(MODULE_WITH_ERRORS) 145*f585d8a3SJacky Wang .onLineContaining("interface ModuleWithErrors"); 146*f585d8a3SJacky Wang subject.hasErrorContaining("ModuleWithErrors has errors") 147*f585d8a3SJacky Wang .onSource(INCLUDES_MODULE_WITH_ERRORS) 148*f585d8a3SJacky Wang .onLineContaining("ModuleWithErrors.class"); 149*f585d8a3SJacky Wang }); 150*f585d8a3SJacky Wang } 151*f585d8a3SJacky Wang 152*f585d8a3SJacky Wang @Test includesModuleWithErrors_validationTypeWarning()153*f585d8a3SJacky Wang public void includesModuleWithErrors_validationTypeWarning() { 154*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS, INCLUDES_MODULE_WITH_ERRORS) 155*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "WARNING")) 156*f585d8a3SJacky Wang .compile( 157*f585d8a3SJacky Wang subject -> { 158*f585d8a3SJacky Wang subject.hasErrorCount(0); 159*f585d8a3SJacky Wang subject.hasWarningCount(2); 160*f585d8a3SJacky Wang 161*f585d8a3SJacky Wang subject.hasWarningContainingMatch(MODULE_WITH_ERRORS_MESSAGE.pattern()) 162*f585d8a3SJacky Wang .onSource(MODULE_WITH_ERRORS) 163*f585d8a3SJacky Wang .onLineContaining("interface ModuleWithErrors"); 164*f585d8a3SJacky Wang 165*f585d8a3SJacky Wang subject.hasWarningContainingMatch(INCLUDES_MODULE_WITH_ERRORS_MESSAGE.pattern()) 166*f585d8a3SJacky Wang .onSource(INCLUDES_MODULE_WITH_ERRORS) 167*f585d8a3SJacky Wang .onLineContaining("interface IncludesModuleWithErrors"); 168*f585d8a3SJacky Wang }); 169*f585d8a3SJacky Wang } 170*f585d8a3SJacky Wang 171*f585d8a3SJacky Wang private static final Source A_MODULE = 172*f585d8a3SJacky Wang CompilerTests.javaSource( 173*f585d8a3SJacky Wang "test.AModule", 174*f585d8a3SJacky Wang "package test;", 175*f585d8a3SJacky Wang "", 176*f585d8a3SJacky Wang "import dagger.Binds;", 177*f585d8a3SJacky Wang "import dagger.Module;", 178*f585d8a3SJacky Wang "", 179*f585d8a3SJacky Wang "@Module", 180*f585d8a3SJacky Wang "interface AModule {", 181*f585d8a3SJacky Wang " @Binds Object object(String string);", 182*f585d8a3SJacky Wang "}"); 183*f585d8a3SJacky Wang 184*f585d8a3SJacky Wang private static final Source COMBINED_WITH_A_MODULE_HAS_ERRORS = 185*f585d8a3SJacky Wang CompilerTests.javaSource( 186*f585d8a3SJacky Wang "test.CombinedWithAModuleHasErrors", 187*f585d8a3SJacky Wang "package test;", 188*f585d8a3SJacky Wang "", 189*f585d8a3SJacky Wang "import dagger.Binds;", 190*f585d8a3SJacky Wang "import dagger.Module;", 191*f585d8a3SJacky Wang "", 192*f585d8a3SJacky Wang "@Module(includes = AModule.class)", 193*f585d8a3SJacky Wang "interface CombinedWithAModuleHasErrors {", 194*f585d8a3SJacky Wang " @Binds Object object(Long l);", 195*f585d8a3SJacky Wang "}"); 196*f585d8a3SJacky Wang 197*f585d8a3SJacky Wang // Make sure the error doesn't show other bindings or a dependency trace afterwards. 198*f585d8a3SJacky Wang private static final Pattern COMBINED_WITH_A_MODULE_HAS_ERRORS_MESSAGE = 199*f585d8a3SJacky Wang endsWithMessage( 200*f585d8a3SJacky Wang "\033[1;31m[Dagger/DuplicateBindings]\033[0m Object is bound multiple times:", 201*f585d8a3SJacky Wang " @Binds Object AModule.object(String)", 202*f585d8a3SJacky Wang " @Binds Object CombinedWithAModuleHasErrors.object(Long)", 203*f585d8a3SJacky Wang " in component: [CombinedWithAModuleHasErrors]", 204*f585d8a3SJacky Wang "", 205*f585d8a3SJacky Wang "======================", 206*f585d8a3SJacky Wang "Full classname legend:", 207*f585d8a3SJacky Wang "======================", 208*f585d8a3SJacky Wang "AModule: test.AModule", 209*f585d8a3SJacky Wang "CombinedWithAModuleHasErrors: test.CombinedWithAModuleHasErrors", 210*f585d8a3SJacky Wang "========================", 211*f585d8a3SJacky Wang "End of classname legend:", 212*f585d8a3SJacky Wang "========================"); 213*f585d8a3SJacky Wang 214*f585d8a3SJacky Wang @Test moduleIncludingModuleWithCombinedErrors_validationTypeNone()215*f585d8a3SJacky Wang public void moduleIncludingModuleWithCombinedErrors_validationTypeNone() { 216*f585d8a3SJacky Wang CompilerTests.daggerCompiler(A_MODULE, COMBINED_WITH_A_MODULE_HAS_ERRORS) 217*f585d8a3SJacky Wang .compile( 218*f585d8a3SJacky Wang subject -> { 219*f585d8a3SJacky Wang subject.hasErrorCount(0); 220*f585d8a3SJacky Wang subject.hasWarningCount(0); 221*f585d8a3SJacky Wang }); 222*f585d8a3SJacky Wang } 223*f585d8a3SJacky Wang 224*f585d8a3SJacky Wang @Test moduleIncludingModuleWithCombinedErrors_validationTypeError()225*f585d8a3SJacky Wang public void moduleIncludingModuleWithCombinedErrors_validationTypeError() { 226*f585d8a3SJacky Wang CompilerTests.daggerCompiler(A_MODULE, COMBINED_WITH_A_MODULE_HAS_ERRORS) 227*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "ERROR")) 228*f585d8a3SJacky Wang .compile( 229*f585d8a3SJacky Wang subject -> { 230*f585d8a3SJacky Wang subject.hasErrorCount(1); 231*f585d8a3SJacky Wang subject.hasErrorContainingMatch(COMBINED_WITH_A_MODULE_HAS_ERRORS_MESSAGE.pattern()) 232*f585d8a3SJacky Wang .onSource(COMBINED_WITH_A_MODULE_HAS_ERRORS) 233*f585d8a3SJacky Wang .onLineContaining("interface CombinedWithAModuleHasErrors"); 234*f585d8a3SJacky Wang }); 235*f585d8a3SJacky Wang } 236*f585d8a3SJacky Wang 237*f585d8a3SJacky Wang @Test moduleIncludingModuleWithCombinedErrors_validationTypeWarning()238*f585d8a3SJacky Wang public void moduleIncludingModuleWithCombinedErrors_validationTypeWarning() { 239*f585d8a3SJacky Wang CompilerTests.daggerCompiler(A_MODULE, COMBINED_WITH_A_MODULE_HAS_ERRORS) 240*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "WARNING")) 241*f585d8a3SJacky Wang .compile( 242*f585d8a3SJacky Wang subject -> { 243*f585d8a3SJacky Wang subject.hasErrorCount(0); 244*f585d8a3SJacky Wang subject.hasWarningCount(1); 245*f585d8a3SJacky Wang subject.hasWarningContainingMatch(COMBINED_WITH_A_MODULE_HAS_ERRORS_MESSAGE.pattern()) 246*f585d8a3SJacky Wang .onSource(COMBINED_WITH_A_MODULE_HAS_ERRORS) 247*f585d8a3SJacky Wang .onLineContaining("interface CombinedWithAModuleHasErrors"); 248*f585d8a3SJacky Wang }); 249*f585d8a3SJacky Wang } 250*f585d8a3SJacky Wang 251*f585d8a3SJacky Wang private static final Source SUBCOMPONENT_WITH_ERRORS = 252*f585d8a3SJacky Wang CompilerTests.javaSource( 253*f585d8a3SJacky Wang "test.SubcomponentWithErrors", 254*f585d8a3SJacky Wang "package test;", 255*f585d8a3SJacky Wang "", 256*f585d8a3SJacky Wang "import dagger.BindsInstance;", 257*f585d8a3SJacky Wang "import dagger.Subcomponent;", 258*f585d8a3SJacky Wang "", 259*f585d8a3SJacky Wang "@Subcomponent(modules = AModule.class)", 260*f585d8a3SJacky Wang "interface SubcomponentWithErrors {", 261*f585d8a3SJacky Wang " @Subcomponent.Builder", 262*f585d8a3SJacky Wang " interface Builder {", 263*f585d8a3SJacky Wang " @BindsInstance Builder object(Object object);", 264*f585d8a3SJacky Wang " SubcomponentWithErrors build();", 265*f585d8a3SJacky Wang " }", 266*f585d8a3SJacky Wang "}"); 267*f585d8a3SJacky Wang 268*f585d8a3SJacky Wang // Make sure the error doesn't show other bindings or a dependency trace afterwards. 269*f585d8a3SJacky Wang private static final Pattern SUBCOMPONENT_WITH_ERRORS_MESSAGE = 270*f585d8a3SJacky Wang endsWithMessage( 271*f585d8a3SJacky Wang "\033[1;31m[Dagger/DuplicateBindings]\033[0m Object is bound multiple times:", 272*f585d8a3SJacky Wang " @Binds Object AModule.object(String)", 273*f585d8a3SJacky Wang " @BindsInstance SubcomponentWithErrors.Builder" 274*f585d8a3SJacky Wang + " SubcomponentWithErrors.Builder.object(Object)", 275*f585d8a3SJacky Wang " in component: [SubcomponentWithErrors]", 276*f585d8a3SJacky Wang "", 277*f585d8a3SJacky Wang "======================", 278*f585d8a3SJacky Wang "Full classname legend:", 279*f585d8a3SJacky Wang "======================", 280*f585d8a3SJacky Wang "AModule: test.AModule", 281*f585d8a3SJacky Wang "SubcomponentWithErrors: test.SubcomponentWithErrors", 282*f585d8a3SJacky Wang "========================", 283*f585d8a3SJacky Wang "End of classname legend:", 284*f585d8a3SJacky Wang "========================"); 285*f585d8a3SJacky Wang 286*f585d8a3SJacky Wang private static final Pattern MODULE_WITH_SUBCOMPONENT_WITH_ERRORS_MESSAGE = 287*f585d8a3SJacky Wang endsWithMessage( 288*f585d8a3SJacky Wang "\033[1;31m[Dagger/DuplicateBindings]\033[0m Object is bound multiple times:", 289*f585d8a3SJacky Wang " @Binds Object AModule.object(String)", 290*f585d8a3SJacky Wang " @BindsInstance SubcomponentWithErrors.Builder" 291*f585d8a3SJacky Wang + " SubcomponentWithErrors.Builder.object(Object)", 292*f585d8a3SJacky Wang " in component: [ModuleWithSubcomponentWithErrors → SubcomponentWithErrors]", 293*f585d8a3SJacky Wang "", 294*f585d8a3SJacky Wang "======================", 295*f585d8a3SJacky Wang "Full classname legend:", 296*f585d8a3SJacky Wang "======================", 297*f585d8a3SJacky Wang "AModule: test.AModule", 298*f585d8a3SJacky Wang "ModuleWithSubcomponentWithErrors: test.ModuleWithSubcomponentWithErrors", 299*f585d8a3SJacky Wang "SubcomponentWithErrors: test.SubcomponentWithErrors", 300*f585d8a3SJacky Wang "========================", 301*f585d8a3SJacky Wang "End of classname legend:", 302*f585d8a3SJacky Wang "========================"); 303*f585d8a3SJacky Wang 304*f585d8a3SJacky Wang @Test subcomponentWithErrors_validationTypeNone()305*f585d8a3SJacky Wang public void subcomponentWithErrors_validationTypeNone() { 306*f585d8a3SJacky Wang CompilerTests.daggerCompiler(SUBCOMPONENT_WITH_ERRORS, A_MODULE) 307*f585d8a3SJacky Wang .compile( 308*f585d8a3SJacky Wang subject -> { 309*f585d8a3SJacky Wang subject.hasErrorCount(0); 310*f585d8a3SJacky Wang subject.hasWarningCount(0); 311*f585d8a3SJacky Wang }); 312*f585d8a3SJacky Wang } 313*f585d8a3SJacky Wang 314*f585d8a3SJacky Wang @Test subcomponentWithErrors_validationTypeError()315*f585d8a3SJacky Wang public void subcomponentWithErrors_validationTypeError() { 316*f585d8a3SJacky Wang CompilerTests.daggerCompiler(SUBCOMPONENT_WITH_ERRORS, A_MODULE) 317*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "ERROR")) 318*f585d8a3SJacky Wang .compile( 319*f585d8a3SJacky Wang subject -> { 320*f585d8a3SJacky Wang subject.hasErrorCount(1); 321*f585d8a3SJacky Wang subject.hasErrorContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE.pattern()) 322*f585d8a3SJacky Wang .onSource(SUBCOMPONENT_WITH_ERRORS) 323*f585d8a3SJacky Wang .onLineContaining("interface SubcomponentWithErrors"); 324*f585d8a3SJacky Wang }); 325*f585d8a3SJacky Wang } 326*f585d8a3SJacky Wang 327*f585d8a3SJacky Wang @Test subcomponentWithErrors_validationTypeWarning()328*f585d8a3SJacky Wang public void subcomponentWithErrors_validationTypeWarning() { 329*f585d8a3SJacky Wang CompilerTests.daggerCompiler(SUBCOMPONENT_WITH_ERRORS, A_MODULE) 330*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "WARNING")) 331*f585d8a3SJacky Wang .compile( 332*f585d8a3SJacky Wang subject -> { 333*f585d8a3SJacky Wang subject.hasErrorCount(0); 334*f585d8a3SJacky Wang subject.hasWarningCount(1); 335*f585d8a3SJacky Wang subject.hasWarningContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE.pattern()) 336*f585d8a3SJacky Wang .onSource(SUBCOMPONENT_WITH_ERRORS) 337*f585d8a3SJacky Wang .onLineContaining("interface SubcomponentWithErrors"); 338*f585d8a3SJacky Wang }); 339*f585d8a3SJacky Wang } 340*f585d8a3SJacky Wang 341*f585d8a3SJacky Wang private static final Source MODULE_WITH_SUBCOMPONENT_WITH_ERRORS = 342*f585d8a3SJacky Wang CompilerTests.javaSource( 343*f585d8a3SJacky Wang "test.ModuleWithSubcomponentWithErrors", 344*f585d8a3SJacky Wang "package test;", 345*f585d8a3SJacky Wang "", 346*f585d8a3SJacky Wang "import dagger.Binds;", 347*f585d8a3SJacky Wang "import dagger.Module;", 348*f585d8a3SJacky Wang "", 349*f585d8a3SJacky Wang "@Module(subcomponents = SubcomponentWithErrors.class)", 350*f585d8a3SJacky Wang "interface ModuleWithSubcomponentWithErrors {}"); 351*f585d8a3SJacky Wang 352*f585d8a3SJacky Wang @Test moduleWithSubcomponentWithErrors_validationTypeNone()353*f585d8a3SJacky Wang public void moduleWithSubcomponentWithErrors_validationTypeNone() { 354*f585d8a3SJacky Wang CompilerTests.daggerCompiler( 355*f585d8a3SJacky Wang MODULE_WITH_SUBCOMPONENT_WITH_ERRORS, SUBCOMPONENT_WITH_ERRORS, A_MODULE) 356*f585d8a3SJacky Wang .compile( 357*f585d8a3SJacky Wang subject -> { 358*f585d8a3SJacky Wang subject.hasErrorCount(0); 359*f585d8a3SJacky Wang subject.hasWarningCount(0); 360*f585d8a3SJacky Wang }); 361*f585d8a3SJacky Wang } 362*f585d8a3SJacky Wang 363*f585d8a3SJacky Wang @Test moduleWithSubcomponentWithErrors_validationTypeError()364*f585d8a3SJacky Wang public void moduleWithSubcomponentWithErrors_validationTypeError() { 365*f585d8a3SJacky Wang CompilerTests.daggerCompiler( 366*f585d8a3SJacky Wang MODULE_WITH_SUBCOMPONENT_WITH_ERRORS, SUBCOMPONENT_WITH_ERRORS, A_MODULE) 367*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "ERROR")) 368*f585d8a3SJacky Wang .compile( 369*f585d8a3SJacky Wang subject -> { 370*f585d8a3SJacky Wang subject.hasErrorCount(2); 371*f585d8a3SJacky Wang subject.hasErrorContainingMatch( 372*f585d8a3SJacky Wang MODULE_WITH_SUBCOMPONENT_WITH_ERRORS_MESSAGE.pattern()) 373*f585d8a3SJacky Wang .onSource(MODULE_WITH_SUBCOMPONENT_WITH_ERRORS) 374*f585d8a3SJacky Wang .onLineContaining("interface ModuleWithSubcomponentWithErrors"); 375*f585d8a3SJacky Wang // TODO(b/130283677) 376*f585d8a3SJacky Wang subject.hasErrorContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE.pattern()) 377*f585d8a3SJacky Wang .onSource(SUBCOMPONENT_WITH_ERRORS) 378*f585d8a3SJacky Wang .onLineContaining("interface SubcomponentWithErrors"); 379*f585d8a3SJacky Wang }); 380*f585d8a3SJacky Wang } 381*f585d8a3SJacky Wang 382*f585d8a3SJacky Wang @Test moduleWithSubcomponentWithErrors_validationTypeWarning()383*f585d8a3SJacky Wang public void moduleWithSubcomponentWithErrors_validationTypeWarning() { 384*f585d8a3SJacky Wang CompilerTests.daggerCompiler( 385*f585d8a3SJacky Wang MODULE_WITH_SUBCOMPONENT_WITH_ERRORS, SUBCOMPONENT_WITH_ERRORS, A_MODULE) 386*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "WARNING")) 387*f585d8a3SJacky Wang .compile( 388*f585d8a3SJacky Wang subject -> { 389*f585d8a3SJacky Wang subject.hasErrorCount(0); 390*f585d8a3SJacky Wang subject.hasWarningCount(2); 391*f585d8a3SJacky Wang 392*f585d8a3SJacky Wang subject.hasWarningContainingMatch( 393*f585d8a3SJacky Wang MODULE_WITH_SUBCOMPONENT_WITH_ERRORS_MESSAGE.pattern()) 394*f585d8a3SJacky Wang .onSource(MODULE_WITH_SUBCOMPONENT_WITH_ERRORS) 395*f585d8a3SJacky Wang .onLineContaining("interface ModuleWithSubcomponentWithErrors"); 396*f585d8a3SJacky Wang 397*f585d8a3SJacky Wang // TODO(b/130283677): Don't repeat error. 398*f585d8a3SJacky Wang subject.hasWarningContainingMatch(SUBCOMPONENT_WITH_ERRORS_MESSAGE.pattern()) 399*f585d8a3SJacky Wang .onSource(SUBCOMPONENT_WITH_ERRORS) 400*f585d8a3SJacky Wang .onLineContaining("interface SubcomponentWithErrors"); 401*f585d8a3SJacky Wang }); 402*f585d8a3SJacky Wang } 403*f585d8a3SJacky Wang 404*f585d8a3SJacky Wang private static final Source A_SUBCOMPONENT = 405*f585d8a3SJacky Wang CompilerTests.javaSource( 406*f585d8a3SJacky Wang "test.ASubcomponent", 407*f585d8a3SJacky Wang "package test;", 408*f585d8a3SJacky Wang "", 409*f585d8a3SJacky Wang "import dagger.BindsInstance;", 410*f585d8a3SJacky Wang "import dagger.Subcomponent;", 411*f585d8a3SJacky Wang "", 412*f585d8a3SJacky Wang "@Subcomponent(modules = AModule.class)", 413*f585d8a3SJacky Wang "interface ASubcomponent {", 414*f585d8a3SJacky Wang " @Subcomponent.Builder", 415*f585d8a3SJacky Wang " interface Builder {", 416*f585d8a3SJacky Wang " ASubcomponent build();", 417*f585d8a3SJacky Wang " }", 418*f585d8a3SJacky Wang "}"); 419*f585d8a3SJacky Wang 420*f585d8a3SJacky Wang private static final Source COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS = 421*f585d8a3SJacky Wang CompilerTests.javaSource( 422*f585d8a3SJacky Wang "test.CombinedWithASubcomponentHasErrors", 423*f585d8a3SJacky Wang "package test;", 424*f585d8a3SJacky Wang "", 425*f585d8a3SJacky Wang "import dagger.Binds;", 426*f585d8a3SJacky Wang "import dagger.Module;", 427*f585d8a3SJacky Wang "", 428*f585d8a3SJacky Wang "@Module(subcomponents = ASubcomponent.class)", 429*f585d8a3SJacky Wang "interface CombinedWithASubcomponentHasErrors {", 430*f585d8a3SJacky Wang " @Binds Object object(Number number);", 431*f585d8a3SJacky Wang "}"); 432*f585d8a3SJacky Wang 433*f585d8a3SJacky Wang // Make sure the error doesn't show other bindings or a dependency trace afterwards. 434*f585d8a3SJacky Wang private static final Pattern COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS_MESSAGE = 435*f585d8a3SJacky Wang endsWithMessage( 436*f585d8a3SJacky Wang "\033[1;31m[Dagger/DuplicateBindings]\033[0m Object is bound multiple times:", 437*f585d8a3SJacky Wang " @Binds Object AModule.object(String)", 438*f585d8a3SJacky Wang " @Binds Object CombinedWithASubcomponentHasErrors.object(Number)", 439*f585d8a3SJacky Wang " in component: [CombinedWithASubcomponentHasErrors → ASubcomponent]", 440*f585d8a3SJacky Wang "", 441*f585d8a3SJacky Wang "======================", 442*f585d8a3SJacky Wang "Full classname legend:", 443*f585d8a3SJacky Wang "======================", 444*f585d8a3SJacky Wang "AModule: test.AModule", 445*f585d8a3SJacky Wang "ASubcomponent: test.ASubcomponent", 446*f585d8a3SJacky Wang "CombinedWithASubcomponentHasErrors: test.CombinedWithASubcomponentHasErrors", 447*f585d8a3SJacky Wang "========================", 448*f585d8a3SJacky Wang "End of classname legend:", 449*f585d8a3SJacky Wang "========================"); 450*f585d8a3SJacky Wang 451*f585d8a3SJacky Wang @Test moduleWithSubcomponentWithCombinedErrors_validationTypeNone()452*f585d8a3SJacky Wang public void moduleWithSubcomponentWithCombinedErrors_validationTypeNone() { 453*f585d8a3SJacky Wang CompilerTests.daggerCompiler(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS, A_SUBCOMPONENT, A_MODULE) 454*f585d8a3SJacky Wang .compile( 455*f585d8a3SJacky Wang subject -> { 456*f585d8a3SJacky Wang subject.hasErrorCount(0); 457*f585d8a3SJacky Wang subject.hasWarningCount(0); 458*f585d8a3SJacky Wang }); 459*f585d8a3SJacky Wang } 460*f585d8a3SJacky Wang 461*f585d8a3SJacky Wang @Test moduleWithSubcomponentWithCombinedErrors_validationTypeError()462*f585d8a3SJacky Wang public void moduleWithSubcomponentWithCombinedErrors_validationTypeError() { 463*f585d8a3SJacky Wang CompilerTests.daggerCompiler(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS, A_SUBCOMPONENT, A_MODULE) 464*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "ERROR")) 465*f585d8a3SJacky Wang .compile( 466*f585d8a3SJacky Wang subject -> { 467*f585d8a3SJacky Wang subject.hasErrorCount(1); 468*f585d8a3SJacky Wang subject.hasErrorContainingMatch( 469*f585d8a3SJacky Wang COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS_MESSAGE.pattern()) 470*f585d8a3SJacky Wang .onSource(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS) 471*f585d8a3SJacky Wang .onLineContaining("interface CombinedWithASubcomponentHasErrors"); 472*f585d8a3SJacky Wang }); 473*f585d8a3SJacky Wang } 474*f585d8a3SJacky Wang 475*f585d8a3SJacky Wang @Test moduleWithSubcomponentWithCombinedErrors_validationTypeWarning()476*f585d8a3SJacky Wang public void moduleWithSubcomponentWithCombinedErrors_validationTypeWarning() { 477*f585d8a3SJacky Wang CompilerTests.daggerCompiler(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS, A_SUBCOMPONENT, A_MODULE) 478*f585d8a3SJacky Wang .withProcessingOptions(ImmutableMap.of("dagger.fullBindingGraphValidation", "WARNING")) 479*f585d8a3SJacky Wang .compile( 480*f585d8a3SJacky Wang subject -> { 481*f585d8a3SJacky Wang subject.hasErrorCount(0); 482*f585d8a3SJacky Wang subject.hasWarningCount(1); 483*f585d8a3SJacky Wang subject.hasWarningContainingMatch( 484*f585d8a3SJacky Wang COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS_MESSAGE.pattern()) 485*f585d8a3SJacky Wang .onSource(COMBINED_WITH_A_SUBCOMPONENT_HAS_ERRORS) 486*f585d8a3SJacky Wang .onLineContaining("interface CombinedWithASubcomponentHasErrors"); 487*f585d8a3SJacky Wang }); 488*f585d8a3SJacky Wang } 489*f585d8a3SJacky Wang 490*f585d8a3SJacky Wang @Test bothAliasesDifferentValues()491*f585d8a3SJacky Wang public void bothAliasesDifferentValues() { 492*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS) 493*f585d8a3SJacky Wang .withProcessingOptions( 494*f585d8a3SJacky Wang ImmutableMap.of( 495*f585d8a3SJacky Wang "dagger.moduleBindingValidation", "NONE", 496*f585d8a3SJacky Wang "dagger.fullBindingGraphValidation", "ERROR")) 497*f585d8a3SJacky Wang .compile( 498*f585d8a3SJacky Wang subject -> { 499*f585d8a3SJacky Wang subject.hasErrorCount(1); 500*f585d8a3SJacky Wang subject.hasErrorContaining( 501*f585d8a3SJacky Wang "Only one of the equivalent options " 502*f585d8a3SJacky Wang + "(-Adagger.fullBindingGraphValidation, -Adagger.moduleBindingValidation)" 503*f585d8a3SJacky Wang + " should be used; prefer -Adagger.fullBindingGraphValidation"); 504*f585d8a3SJacky Wang }); 505*f585d8a3SJacky Wang } 506*f585d8a3SJacky Wang 507*f585d8a3SJacky Wang @Test bothAliasesSameValue()508*f585d8a3SJacky Wang public void bothAliasesSameValue() { 509*f585d8a3SJacky Wang CompilerTests.daggerCompiler(MODULE_WITH_ERRORS) 510*f585d8a3SJacky Wang .withProcessingOptions( 511*f585d8a3SJacky Wang ImmutableMap.of( 512*f585d8a3SJacky Wang "dagger.moduleBindingValidation", "NONE", 513*f585d8a3SJacky Wang "dagger.fullBindingGraphValidation", "NONE")) 514*f585d8a3SJacky Wang .compile( 515*f585d8a3SJacky Wang subject -> { 516*f585d8a3SJacky Wang subject.hasErrorCount(0); 517*f585d8a3SJacky Wang subject.hasWarningCount(1); 518*f585d8a3SJacky Wang subject.hasWarningContaining( 519*f585d8a3SJacky Wang "Only one of the equivalent options " 520*f585d8a3SJacky Wang + "(-Adagger.fullBindingGraphValidation, -Adagger.moduleBindingValidation)" 521*f585d8a3SJacky Wang + " should be used; prefer -Adagger.fullBindingGraphValidation"); 522*f585d8a3SJacky Wang }); 523*f585d8a3SJacky Wang } 524*f585d8a3SJacky Wang } 525