1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2015 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.base.ComponentCreatorAnnotation.COMPONENT_BUILDER; 20*f585d8a3SJacky Wang import static dagger.internal.codegen.binding.ErrorMessages.creatorMessagesFor; 21*f585d8a3SJacky Wang 22*f585d8a3SJacky Wang import androidx.room.compiler.processing.util.Source; 23*f585d8a3SJacky Wang import dagger.internal.codegen.binding.ErrorMessages; 24*f585d8a3SJacky Wang import dagger.testing.compile.CompilerTests; 25*f585d8a3SJacky Wang import dagger.testing.golden.GoldenFileRule; 26*f585d8a3SJacky Wang import java.util.Collection; 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 /** Tests for {@link dagger.Component.Builder} */ 34*f585d8a3SJacky Wang @RunWith(Parameterized.class) 35*f585d8a3SJacky Wang public class ComponentBuilderTest { 36*f585d8a3SJacky Wang @Parameters(name = "{0}") parameters()37*f585d8a3SJacky Wang public static Collection<Object[]> parameters() { 38*f585d8a3SJacky Wang return CompilerMode.TEST_PARAMETERS; 39*f585d8a3SJacky Wang } 40*f585d8a3SJacky Wang 41*f585d8a3SJacky Wang @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); 42*f585d8a3SJacky Wang 43*f585d8a3SJacky Wang private final CompilerMode compilerMode; 44*f585d8a3SJacky Wang ComponentBuilderTest(CompilerMode compilerMode)45*f585d8a3SJacky Wang public ComponentBuilderTest(CompilerMode compilerMode) { 46*f585d8a3SJacky Wang this.compilerMode = compilerMode; 47*f585d8a3SJacky Wang } 48*f585d8a3SJacky Wang 49*f585d8a3SJacky Wang private static final ErrorMessages.ComponentCreatorMessages MSGS = 50*f585d8a3SJacky Wang creatorMessagesFor(COMPONENT_BUILDER); 51*f585d8a3SJacky Wang 52*f585d8a3SJacky Wang @Test testUsesBuildAndSetterNames()53*f585d8a3SJacky Wang public void testUsesBuildAndSetterNames() throws Exception { 54*f585d8a3SJacky Wang Source moduleFile = 55*f585d8a3SJacky Wang CompilerTests.javaSource( 56*f585d8a3SJacky Wang "test.TestModule", 57*f585d8a3SJacky Wang "package test;", 58*f585d8a3SJacky Wang "", 59*f585d8a3SJacky Wang "import dagger.Module;", 60*f585d8a3SJacky Wang "import dagger.Provides;", 61*f585d8a3SJacky Wang "", 62*f585d8a3SJacky Wang "@Module", 63*f585d8a3SJacky Wang "final class TestModule {", 64*f585d8a3SJacky Wang " @Provides String string() { return null; }", 65*f585d8a3SJacky Wang "}"); 66*f585d8a3SJacky Wang 67*f585d8a3SJacky Wang Source componentFile = 68*f585d8a3SJacky Wang CompilerTests.javaSource( 69*f585d8a3SJacky Wang "test.TestComponent", 70*f585d8a3SJacky Wang "package test;", 71*f585d8a3SJacky Wang "", 72*f585d8a3SJacky Wang "import dagger.Component;", 73*f585d8a3SJacky Wang "", 74*f585d8a3SJacky Wang "@Component(modules = TestModule.class)", 75*f585d8a3SJacky Wang "interface TestComponent {", 76*f585d8a3SJacky Wang " String string();", 77*f585d8a3SJacky Wang "", 78*f585d8a3SJacky Wang " @Component.Builder", 79*f585d8a3SJacky Wang " interface Builder {", 80*f585d8a3SJacky Wang " Builder setTestModule(TestModule testModule);", 81*f585d8a3SJacky Wang " TestComponent create();", 82*f585d8a3SJacky Wang " }", 83*f585d8a3SJacky Wang "}"); 84*f585d8a3SJacky Wang 85*f585d8a3SJacky Wang CompilerTests.daggerCompiler(moduleFile, componentFile) 86*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 87*f585d8a3SJacky Wang .compile( 88*f585d8a3SJacky Wang subject -> { 89*f585d8a3SJacky Wang subject.hasErrorCount(0); 90*f585d8a3SJacky Wang subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 91*f585d8a3SJacky Wang }); 92*f585d8a3SJacky Wang } 93*f585d8a3SJacky Wang 94*f585d8a3SJacky Wang @Test testSetterMethodWithMoreThanOneArgFails()95*f585d8a3SJacky Wang public void testSetterMethodWithMoreThanOneArgFails() { 96*f585d8a3SJacky Wang Source componentFile = 97*f585d8a3SJacky Wang CompilerTests.javaSource( 98*f585d8a3SJacky Wang "test.SimpleComponent", 99*f585d8a3SJacky Wang "package test;", 100*f585d8a3SJacky Wang "", 101*f585d8a3SJacky Wang "import dagger.Component;", 102*f585d8a3SJacky Wang "import javax.inject.Provider;", 103*f585d8a3SJacky Wang "", 104*f585d8a3SJacky Wang "@Component", 105*f585d8a3SJacky Wang "abstract class SimpleComponent {", 106*f585d8a3SJacky Wang " @Component.Builder", 107*f585d8a3SJacky Wang " interface Builder {", 108*f585d8a3SJacky Wang " SimpleComponent build();", 109*f585d8a3SJacky Wang " Builder set(String s, Integer i);", 110*f585d8a3SJacky Wang " Builder set(Number n, Double d);", 111*f585d8a3SJacky Wang " }", 112*f585d8a3SJacky Wang "}"); 113*f585d8a3SJacky Wang 114*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 115*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 116*f585d8a3SJacky Wang .compile( 117*f585d8a3SJacky Wang subject -> { 118*f585d8a3SJacky Wang subject.hasErrorCount(2); 119*f585d8a3SJacky Wang subject 120*f585d8a3SJacky Wang .hasErrorContaining(MSGS.setterMethodsMustTakeOneArg()) 121*f585d8a3SJacky Wang .onSource(componentFile) 122*f585d8a3SJacky Wang .onLineContaining("Builder set(String s, Integer i);"); 123*f585d8a3SJacky Wang subject 124*f585d8a3SJacky Wang .hasErrorContaining(MSGS.setterMethodsMustTakeOneArg()) 125*f585d8a3SJacky Wang .onSource(componentFile) 126*f585d8a3SJacky Wang .onLineContaining("Builder set(Number n, Double d);"); 127*f585d8a3SJacky Wang }); 128*f585d8a3SJacky Wang } 129*f585d8a3SJacky Wang 130*f585d8a3SJacky Wang @Test testInheritedSetterMethodWithMoreThanOneArgFails()131*f585d8a3SJacky Wang public void testInheritedSetterMethodWithMoreThanOneArgFails() { 132*f585d8a3SJacky Wang Source componentFile = 133*f585d8a3SJacky Wang CompilerTests.javaSource( 134*f585d8a3SJacky Wang "test.SimpleComponent", 135*f585d8a3SJacky Wang "package test;", 136*f585d8a3SJacky Wang "", 137*f585d8a3SJacky Wang "import dagger.Component;", 138*f585d8a3SJacky Wang "import javax.inject.Provider;", 139*f585d8a3SJacky Wang "", 140*f585d8a3SJacky Wang "@Component", 141*f585d8a3SJacky Wang "abstract class SimpleComponent {", 142*f585d8a3SJacky Wang " interface Parent {", 143*f585d8a3SJacky Wang " SimpleComponent build();", 144*f585d8a3SJacky Wang " Builder set1(String s, Integer i);", 145*f585d8a3SJacky Wang " }", 146*f585d8a3SJacky Wang "", 147*f585d8a3SJacky Wang " @Component.Builder", 148*f585d8a3SJacky Wang " interface Builder extends Parent {}", 149*f585d8a3SJacky Wang "}"); 150*f585d8a3SJacky Wang 151*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 152*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 153*f585d8a3SJacky Wang .compile( 154*f585d8a3SJacky Wang subject -> { 155*f585d8a3SJacky Wang subject.hasErrorCount(1); 156*f585d8a3SJacky Wang subject 157*f585d8a3SJacky Wang .hasErrorContaining( 158*f585d8a3SJacky Wang String.format( 159*f585d8a3SJacky Wang MSGS.inheritedSetterMethodsMustTakeOneArg(), 160*f585d8a3SJacky Wang "test.SimpleComponent.Builder test.SimpleComponent.Parent.set1(" 161*f585d8a3SJacky Wang + "String, Integer)")) 162*f585d8a3SJacky Wang .onSource(componentFile) 163*f585d8a3SJacky Wang .onLineContaining("interface Builder"); 164*f585d8a3SJacky Wang }); 165*f585d8a3SJacky Wang } 166*f585d8a3SJacky Wang 167*f585d8a3SJacky Wang @Test testSetterReturningNonVoidOrBuilderFails()168*f585d8a3SJacky Wang public void testSetterReturningNonVoidOrBuilderFails() { 169*f585d8a3SJacky Wang Source componentFile = 170*f585d8a3SJacky Wang CompilerTests.javaSource( 171*f585d8a3SJacky Wang "test.SimpleComponent", 172*f585d8a3SJacky Wang "package test;", 173*f585d8a3SJacky Wang "", 174*f585d8a3SJacky Wang "import dagger.Component;", 175*f585d8a3SJacky Wang "import javax.inject.Provider;", 176*f585d8a3SJacky Wang "", 177*f585d8a3SJacky Wang "@Component", 178*f585d8a3SJacky Wang "abstract class SimpleComponent {", 179*f585d8a3SJacky Wang " @Component.Builder", 180*f585d8a3SJacky Wang " interface Builder {", 181*f585d8a3SJacky Wang " SimpleComponent build();", 182*f585d8a3SJacky Wang " String set(Integer i);", 183*f585d8a3SJacky Wang " }", 184*f585d8a3SJacky Wang "}"); 185*f585d8a3SJacky Wang 186*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 187*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 188*f585d8a3SJacky Wang .compile( 189*f585d8a3SJacky Wang subject -> { 190*f585d8a3SJacky Wang subject.hasErrorCount(1); 191*f585d8a3SJacky Wang subject 192*f585d8a3SJacky Wang .hasErrorContaining(MSGS.setterMethodsMustReturnVoidOrBuilder()) 193*f585d8a3SJacky Wang .onSource(componentFile) 194*f585d8a3SJacky Wang .onLineContaining("String set(Integer i);"); 195*f585d8a3SJacky Wang }); 196*f585d8a3SJacky Wang } 197*f585d8a3SJacky Wang 198*f585d8a3SJacky Wang @Test testInheritedSetterReturningNonVoidOrBuilderFails()199*f585d8a3SJacky Wang public void testInheritedSetterReturningNonVoidOrBuilderFails() { 200*f585d8a3SJacky Wang Source componentFile = 201*f585d8a3SJacky Wang CompilerTests.javaSource( 202*f585d8a3SJacky Wang "test.SimpleComponent", 203*f585d8a3SJacky Wang "package test;", 204*f585d8a3SJacky Wang "", 205*f585d8a3SJacky Wang "import dagger.Component;", 206*f585d8a3SJacky Wang "import javax.inject.Provider;", 207*f585d8a3SJacky Wang "", 208*f585d8a3SJacky Wang "@Component", 209*f585d8a3SJacky Wang "abstract class SimpleComponent {", 210*f585d8a3SJacky Wang " interface Parent {", 211*f585d8a3SJacky Wang " SimpleComponent build();", 212*f585d8a3SJacky Wang " String set(Integer i);", 213*f585d8a3SJacky Wang " }", 214*f585d8a3SJacky Wang "", 215*f585d8a3SJacky Wang " @Component.Builder", 216*f585d8a3SJacky Wang " interface Builder extends Parent {}", 217*f585d8a3SJacky Wang "}"); 218*f585d8a3SJacky Wang 219*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 220*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 221*f585d8a3SJacky Wang .compile( 222*f585d8a3SJacky Wang subject -> { 223*f585d8a3SJacky Wang subject.hasErrorCount(1); 224*f585d8a3SJacky Wang subject 225*f585d8a3SJacky Wang .hasErrorContaining( 226*f585d8a3SJacky Wang String.format( 227*f585d8a3SJacky Wang MSGS.inheritedSetterMethodsMustReturnVoidOrBuilder(), 228*f585d8a3SJacky Wang "String test.SimpleComponent.Parent.set(Integer)")) 229*f585d8a3SJacky Wang .onSource(componentFile) 230*f585d8a3SJacky Wang .onLineContaining("interface Builder"); 231*f585d8a3SJacky Wang }); 232*f585d8a3SJacky Wang } 233*f585d8a3SJacky Wang 234*f585d8a3SJacky Wang @Test testGenericsOnSetterMethodFails()235*f585d8a3SJacky Wang public void testGenericsOnSetterMethodFails() { 236*f585d8a3SJacky Wang Source componentFile = 237*f585d8a3SJacky Wang CompilerTests.javaSource( 238*f585d8a3SJacky Wang "test.SimpleComponent", 239*f585d8a3SJacky Wang "package test;", 240*f585d8a3SJacky Wang "", 241*f585d8a3SJacky Wang "import dagger.Component;", 242*f585d8a3SJacky Wang "import javax.inject.Provider;", 243*f585d8a3SJacky Wang "", 244*f585d8a3SJacky Wang "@Component", 245*f585d8a3SJacky Wang "abstract class SimpleComponent {", 246*f585d8a3SJacky Wang " @Component.Builder", 247*f585d8a3SJacky Wang " interface Builder {", 248*f585d8a3SJacky Wang " SimpleComponent build();", 249*f585d8a3SJacky Wang " <T> Builder set(T t);", 250*f585d8a3SJacky Wang " }", 251*f585d8a3SJacky Wang "}"); 252*f585d8a3SJacky Wang 253*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 254*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 255*f585d8a3SJacky Wang .compile( 256*f585d8a3SJacky Wang subject -> { 257*f585d8a3SJacky Wang subject.hasErrorCount(1); 258*f585d8a3SJacky Wang subject 259*f585d8a3SJacky Wang .hasErrorContaining(MSGS.methodsMayNotHaveTypeParameters()) 260*f585d8a3SJacky Wang .onSource(componentFile) 261*f585d8a3SJacky Wang .onLineContaining("<T> Builder set(T t);"); 262*f585d8a3SJacky Wang }); 263*f585d8a3SJacky Wang } 264*f585d8a3SJacky Wang 265*f585d8a3SJacky Wang @Test testGenericsOnInheritedSetterMethodFails()266*f585d8a3SJacky Wang public void testGenericsOnInheritedSetterMethodFails() { 267*f585d8a3SJacky Wang Source componentFile = 268*f585d8a3SJacky Wang CompilerTests.javaSource( 269*f585d8a3SJacky Wang "test.SimpleComponent", 270*f585d8a3SJacky Wang "package test;", 271*f585d8a3SJacky Wang "", 272*f585d8a3SJacky Wang "import dagger.Component;", 273*f585d8a3SJacky Wang "import javax.inject.Provider;", 274*f585d8a3SJacky Wang "", 275*f585d8a3SJacky Wang "@Component", 276*f585d8a3SJacky Wang "abstract class SimpleComponent {", 277*f585d8a3SJacky Wang " interface Parent {", 278*f585d8a3SJacky Wang " SimpleComponent build();", 279*f585d8a3SJacky Wang " <T> Builder set(T t);", 280*f585d8a3SJacky Wang " }", 281*f585d8a3SJacky Wang "", 282*f585d8a3SJacky Wang " @Component.Builder", 283*f585d8a3SJacky Wang " interface Builder extends Parent {}", 284*f585d8a3SJacky Wang "}"); 285*f585d8a3SJacky Wang 286*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 287*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 288*f585d8a3SJacky Wang .compile( 289*f585d8a3SJacky Wang subject -> { 290*f585d8a3SJacky Wang subject.hasErrorCount(1); 291*f585d8a3SJacky Wang subject 292*f585d8a3SJacky Wang .hasErrorContaining( 293*f585d8a3SJacky Wang String.format( 294*f585d8a3SJacky Wang MSGS.inheritedMethodsMayNotHaveTypeParameters(), 295*f585d8a3SJacky Wang "test.SimpleComponent.Builder test.SimpleComponent.Parent.set(T)")) 296*f585d8a3SJacky Wang .onSource(componentFile) 297*f585d8a3SJacky Wang .onLineContaining("interface Builder"); 298*f585d8a3SJacky Wang }); 299*f585d8a3SJacky Wang } 300*f585d8a3SJacky Wang 301*f585d8a3SJacky Wang @Test testBindsInstanceNotAllowedOnBothSetterAndParameter()302*f585d8a3SJacky Wang public void testBindsInstanceNotAllowedOnBothSetterAndParameter() { 303*f585d8a3SJacky Wang Source componentFile = 304*f585d8a3SJacky Wang CompilerTests.javaSource( 305*f585d8a3SJacky Wang "test.SimpleComponent", 306*f585d8a3SJacky Wang "package test;", 307*f585d8a3SJacky Wang "", 308*f585d8a3SJacky Wang "import dagger.BindsInstance;", 309*f585d8a3SJacky Wang "import dagger.Component;", 310*f585d8a3SJacky Wang "", 311*f585d8a3SJacky Wang "@Component", 312*f585d8a3SJacky Wang "abstract class SimpleComponent {", 313*f585d8a3SJacky Wang " abstract String s();", 314*f585d8a3SJacky Wang "", 315*f585d8a3SJacky Wang " @Component.Builder", 316*f585d8a3SJacky Wang " interface Builder {", 317*f585d8a3SJacky Wang " @BindsInstance", 318*f585d8a3SJacky Wang " Builder s(@BindsInstance String s);", 319*f585d8a3SJacky Wang "", 320*f585d8a3SJacky Wang " SimpleComponent build();", 321*f585d8a3SJacky Wang " }", 322*f585d8a3SJacky Wang "}"); 323*f585d8a3SJacky Wang 324*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 325*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 326*f585d8a3SJacky Wang .compile( 327*f585d8a3SJacky Wang subject -> { 328*f585d8a3SJacky Wang subject.hasErrorCount(1); 329*f585d8a3SJacky Wang subject 330*f585d8a3SJacky Wang .hasErrorContaining(MSGS.bindsInstanceNotAllowedOnBothSetterMethodAndParameter()) 331*f585d8a3SJacky Wang .onSource(componentFile) 332*f585d8a3SJacky Wang .onLineContaining("Builder s("); 333*f585d8a3SJacky Wang }); 334*f585d8a3SJacky Wang } 335*f585d8a3SJacky Wang 336*f585d8a3SJacky Wang @Test testBindsInstanceNotAllowedOnBothSetterAndParameter_inherited()337*f585d8a3SJacky Wang public void testBindsInstanceNotAllowedOnBothSetterAndParameter_inherited() { 338*f585d8a3SJacky Wang Source componentFile = 339*f585d8a3SJacky Wang CompilerTests.javaSource( 340*f585d8a3SJacky Wang "test.SimpleComponent", 341*f585d8a3SJacky Wang "package test;", 342*f585d8a3SJacky Wang "", 343*f585d8a3SJacky Wang "import dagger.BindsInstance;", 344*f585d8a3SJacky Wang "import dagger.Component;", 345*f585d8a3SJacky Wang "", 346*f585d8a3SJacky Wang "@Component", 347*f585d8a3SJacky Wang "abstract class SimpleComponent {", 348*f585d8a3SJacky Wang " abstract String s();", 349*f585d8a3SJacky Wang "", 350*f585d8a3SJacky Wang " interface BuilderParent<B extends BuilderParent> {", 351*f585d8a3SJacky Wang " @BindsInstance", 352*f585d8a3SJacky Wang " B s(@BindsInstance String s);", 353*f585d8a3SJacky Wang " }", 354*f585d8a3SJacky Wang "", 355*f585d8a3SJacky Wang " @Component.Builder", 356*f585d8a3SJacky Wang " interface Builder extends BuilderParent<Builder> {", 357*f585d8a3SJacky Wang " SimpleComponent build();", 358*f585d8a3SJacky Wang " }", 359*f585d8a3SJacky Wang "}"); 360*f585d8a3SJacky Wang 361*f585d8a3SJacky Wang CompilerTests.daggerCompiler(componentFile) 362*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 363*f585d8a3SJacky Wang .compile( 364*f585d8a3SJacky Wang subject -> { 365*f585d8a3SJacky Wang subject.hasErrorCount(1); 366*f585d8a3SJacky Wang subject 367*f585d8a3SJacky Wang .hasErrorContaining( 368*f585d8a3SJacky Wang String.format( 369*f585d8a3SJacky Wang MSGS.inheritedBindsInstanceNotAllowedOnBothSetterMethodAndParameter(), 370*f585d8a3SJacky Wang "@BindsInstance B test.SimpleComponent.BuilderParent.s(String)")) 371*f585d8a3SJacky Wang .onSource(componentFile) 372*f585d8a3SJacky Wang .onLineContaining("Builder extends BuilderParent<Builder>"); 373*f585d8a3SJacky Wang }); 374*f585d8a3SJacky Wang } 375*f585d8a3SJacky Wang } 376