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.SUBCOMPONENT_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 com.google.common.collect.ImmutableList; 24*f585d8a3SJacky Wang import dagger.internal.codegen.binding.ErrorMessages; 25*f585d8a3SJacky Wang import dagger.testing.compile.CompilerTests; 26*f585d8a3SJacky Wang import dagger.testing.golden.GoldenFileRule; 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.Subcomponent.Builder} validation. */ 34*f585d8a3SJacky Wang @RunWith(Parameterized.class) 35*f585d8a3SJacky Wang public class SubcomponentBuilderValidationTest { 36*f585d8a3SJacky Wang @Parameters(name = "{0}") parameters()37*f585d8a3SJacky Wang public static ImmutableList<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 SubcomponentBuilderValidationTest(CompilerMode compilerMode)45*f585d8a3SJacky Wang public SubcomponentBuilderValidationTest(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(SUBCOMPONENT_BUILDER); 51*f585d8a3SJacky Wang 52*f585d8a3SJacky Wang @Test testMoreThanOneArgFails()53*f585d8a3SJacky Wang public void testMoreThanOneArgFails() { 54*f585d8a3SJacky Wang Source childComponentFile = CompilerTests.javaSource("test.ChildComponent", 55*f585d8a3SJacky Wang "package test;", 56*f585d8a3SJacky Wang "", 57*f585d8a3SJacky Wang "import dagger.Subcomponent;", 58*f585d8a3SJacky Wang "", 59*f585d8a3SJacky Wang "@Subcomponent", 60*f585d8a3SJacky Wang "abstract class ChildComponent {", 61*f585d8a3SJacky Wang " @Subcomponent.Builder", 62*f585d8a3SJacky Wang " interface Builder {", 63*f585d8a3SJacky Wang " ChildComponent build();", 64*f585d8a3SJacky Wang " Builder set(String s, Integer i);", 65*f585d8a3SJacky Wang " Builder set(Number n, Double d);", 66*f585d8a3SJacky Wang " }", 67*f585d8a3SJacky Wang "}"); 68*f585d8a3SJacky Wang 69*f585d8a3SJacky Wang CompilerTests.daggerCompiler(childComponentFile) 70*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 71*f585d8a3SJacky Wang .compile( 72*f585d8a3SJacky Wang subject -> { 73*f585d8a3SJacky Wang subject.hasErrorCount(2); 74*f585d8a3SJacky Wang subject 75*f585d8a3SJacky Wang .hasErrorContaining(MSGS.setterMethodsMustTakeOneArg()) 76*f585d8a3SJacky Wang .onSource(childComponentFile) 77*f585d8a3SJacky Wang .onLine(10); 78*f585d8a3SJacky Wang subject 79*f585d8a3SJacky Wang .hasErrorContaining(MSGS.setterMethodsMustTakeOneArg()) 80*f585d8a3SJacky Wang .onSource(childComponentFile) 81*f585d8a3SJacky Wang .onLine(11); 82*f585d8a3SJacky Wang }); 83*f585d8a3SJacky Wang } 84*f585d8a3SJacky Wang 85*f585d8a3SJacky Wang @Test testInheritedMoreThanOneArgFails()86*f585d8a3SJacky Wang public void testInheritedMoreThanOneArgFails() { 87*f585d8a3SJacky Wang Source childComponentFile = CompilerTests.javaSource("test.ChildComponent", 88*f585d8a3SJacky Wang "package test;", 89*f585d8a3SJacky Wang "", 90*f585d8a3SJacky Wang "import dagger.Subcomponent;", 91*f585d8a3SJacky Wang "", 92*f585d8a3SJacky Wang "@Subcomponent", 93*f585d8a3SJacky Wang "abstract class ChildComponent {", 94*f585d8a3SJacky Wang " interface Parent {", 95*f585d8a3SJacky Wang " ChildComponent build();", 96*f585d8a3SJacky Wang " Builder set1(String s, Integer i);", 97*f585d8a3SJacky Wang " }", 98*f585d8a3SJacky Wang "", 99*f585d8a3SJacky Wang " @Subcomponent.Builder", 100*f585d8a3SJacky Wang " interface Builder extends Parent {}", 101*f585d8a3SJacky Wang "}"); 102*f585d8a3SJacky Wang 103*f585d8a3SJacky Wang String expectedErrorMsg = 104*f585d8a3SJacky Wang String.format( 105*f585d8a3SJacky Wang MSGS.inheritedSetterMethodsMustTakeOneArg(), 106*f585d8a3SJacky Wang "test.ChildComponent.Builder test.ChildComponent.Parent.set1(String, Integer)"); 107*f585d8a3SJacky Wang CompilerTests.daggerCompiler(childComponentFile) 108*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 109*f585d8a3SJacky Wang .compile( 110*f585d8a3SJacky Wang subject -> { 111*f585d8a3SJacky Wang subject.hasErrorCount(1); 112*f585d8a3SJacky Wang subject 113*f585d8a3SJacky Wang .hasErrorContaining(expectedErrorMsg) 114*f585d8a3SJacky Wang .onSource(childComponentFile) 115*f585d8a3SJacky Wang .onLine(13); 116*f585d8a3SJacky Wang }); 117*f585d8a3SJacky Wang } 118*f585d8a3SJacky Wang 119*f585d8a3SJacky Wang @Test testSetterReturningNonVoidOrBuilderFails()120*f585d8a3SJacky Wang public void testSetterReturningNonVoidOrBuilderFails() { 121*f585d8a3SJacky Wang Source childComponentFile = CompilerTests.javaSource("test.ChildComponent", 122*f585d8a3SJacky Wang "package test;", 123*f585d8a3SJacky Wang "", 124*f585d8a3SJacky Wang "import dagger.Subcomponent;", 125*f585d8a3SJacky Wang "", 126*f585d8a3SJacky Wang "@Subcomponent", 127*f585d8a3SJacky Wang "abstract class ChildComponent {", 128*f585d8a3SJacky Wang " @Subcomponent.Builder", 129*f585d8a3SJacky Wang " interface Builder {", 130*f585d8a3SJacky Wang " ChildComponent build();", 131*f585d8a3SJacky Wang " String set(Integer i);", 132*f585d8a3SJacky Wang " }", 133*f585d8a3SJacky Wang "}"); 134*f585d8a3SJacky Wang 135*f585d8a3SJacky Wang CompilerTests.daggerCompiler(childComponentFile) 136*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 137*f585d8a3SJacky Wang .compile( 138*f585d8a3SJacky Wang subject -> { 139*f585d8a3SJacky Wang subject.hasErrorCount(1); 140*f585d8a3SJacky Wang subject 141*f585d8a3SJacky Wang .hasErrorContaining(MSGS.setterMethodsMustReturnVoidOrBuilder()) 142*f585d8a3SJacky Wang .onSource(childComponentFile) 143*f585d8a3SJacky Wang .onLine(10); 144*f585d8a3SJacky Wang }); 145*f585d8a3SJacky Wang } 146*f585d8a3SJacky Wang 147*f585d8a3SJacky Wang @Test testInheritedSetterReturningNonVoidOrBuilderFails()148*f585d8a3SJacky Wang public void testInheritedSetterReturningNonVoidOrBuilderFails() { 149*f585d8a3SJacky Wang Source childComponentFile = CompilerTests.javaSource("test.ChildComponent", 150*f585d8a3SJacky Wang "package test;", 151*f585d8a3SJacky Wang "", 152*f585d8a3SJacky Wang "import dagger.Subcomponent;", 153*f585d8a3SJacky Wang "", 154*f585d8a3SJacky Wang "@Subcomponent", 155*f585d8a3SJacky Wang "abstract class ChildComponent {", 156*f585d8a3SJacky Wang " interface Parent {", 157*f585d8a3SJacky Wang " ChildComponent build();", 158*f585d8a3SJacky Wang " String set(Integer i);", 159*f585d8a3SJacky Wang " }", 160*f585d8a3SJacky Wang "", 161*f585d8a3SJacky Wang " @Subcomponent.Builder", 162*f585d8a3SJacky Wang " interface Builder extends Parent {}", 163*f585d8a3SJacky Wang "}"); 164*f585d8a3SJacky Wang 165*f585d8a3SJacky Wang CompilerTests.daggerCompiler(childComponentFile) 166*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 167*f585d8a3SJacky Wang .compile( 168*f585d8a3SJacky Wang subject -> { 169*f585d8a3SJacky Wang subject.hasErrorCount(1); 170*f585d8a3SJacky Wang subject 171*f585d8a3SJacky Wang .hasErrorContaining( 172*f585d8a3SJacky Wang String.format( 173*f585d8a3SJacky Wang MSGS.inheritedSetterMethodsMustReturnVoidOrBuilder(), 174*f585d8a3SJacky Wang "String test.ChildComponent.Parent.set(Integer)")) 175*f585d8a3SJacky Wang .onSource(childComponentFile) 176*f585d8a3SJacky Wang .onLine(13); 177*f585d8a3SJacky Wang }); 178*f585d8a3SJacky Wang } 179*f585d8a3SJacky Wang 180*f585d8a3SJacky Wang @Test testGenericsOnSetterMethodFails()181*f585d8a3SJacky Wang public void testGenericsOnSetterMethodFails() { 182*f585d8a3SJacky Wang Source childComponentFile = CompilerTests.javaSource("test.ChildComponent", 183*f585d8a3SJacky Wang "package test;", 184*f585d8a3SJacky Wang "", 185*f585d8a3SJacky Wang "import dagger.Subcomponent;", 186*f585d8a3SJacky Wang "", 187*f585d8a3SJacky Wang "@Subcomponent", 188*f585d8a3SJacky Wang "abstract class ChildComponent {", 189*f585d8a3SJacky Wang " @Subcomponent.Builder", 190*f585d8a3SJacky Wang " interface Builder {", 191*f585d8a3SJacky Wang " ChildComponent build();", 192*f585d8a3SJacky Wang " <T> Builder set(T t);", 193*f585d8a3SJacky Wang " }", 194*f585d8a3SJacky Wang "}"); 195*f585d8a3SJacky Wang 196*f585d8a3SJacky Wang CompilerTests.daggerCompiler(childComponentFile) 197*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 198*f585d8a3SJacky Wang .compile( 199*f585d8a3SJacky Wang subject -> { 200*f585d8a3SJacky Wang subject.hasErrorCount(1); 201*f585d8a3SJacky Wang subject 202*f585d8a3SJacky Wang .hasErrorContaining(MSGS.methodsMayNotHaveTypeParameters()) 203*f585d8a3SJacky Wang .onSource(childComponentFile) 204*f585d8a3SJacky Wang .onLine(10); 205*f585d8a3SJacky Wang }); 206*f585d8a3SJacky Wang } 207*f585d8a3SJacky Wang 208*f585d8a3SJacky Wang @Test testGenericsOnInheritedSetterMethodFails()209*f585d8a3SJacky Wang public void testGenericsOnInheritedSetterMethodFails() { 210*f585d8a3SJacky Wang Source childComponentFile = CompilerTests.javaSource("test.ChildComponent", 211*f585d8a3SJacky Wang "package test;", 212*f585d8a3SJacky Wang "", 213*f585d8a3SJacky Wang "import dagger.Subcomponent;", 214*f585d8a3SJacky Wang "", 215*f585d8a3SJacky Wang "@Subcomponent", 216*f585d8a3SJacky Wang "abstract class ChildComponent {", 217*f585d8a3SJacky Wang " interface Parent {", 218*f585d8a3SJacky Wang " ChildComponent build();", 219*f585d8a3SJacky Wang " <T> Builder set(T t);", 220*f585d8a3SJacky Wang " }", 221*f585d8a3SJacky Wang "", 222*f585d8a3SJacky Wang " @Subcomponent.Builder", 223*f585d8a3SJacky Wang " interface Builder extends Parent {}", 224*f585d8a3SJacky Wang "}"); 225*f585d8a3SJacky Wang 226*f585d8a3SJacky Wang CompilerTests.daggerCompiler(childComponentFile) 227*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 228*f585d8a3SJacky Wang .compile( 229*f585d8a3SJacky Wang subject -> { 230*f585d8a3SJacky Wang subject.hasErrorCount(1); 231*f585d8a3SJacky Wang subject 232*f585d8a3SJacky Wang .hasErrorContaining( 233*f585d8a3SJacky Wang String.format( 234*f585d8a3SJacky Wang MSGS.inheritedMethodsMayNotHaveTypeParameters(), 235*f585d8a3SJacky Wang "test.ChildComponent.Builder test.ChildComponent.Parent.set(T)")) 236*f585d8a3SJacky Wang .onSource(childComponentFile) 237*f585d8a3SJacky Wang .onLine(13); 238*f585d8a3SJacky Wang }); 239*f585d8a3SJacky Wang } 240*f585d8a3SJacky Wang } 241