1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2017 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 dagger.testing.compile.CompilerTests; 21*f585d8a3SJacky Wang import dagger.testing.golden.GoldenFileRule; 22*f585d8a3SJacky Wang import java.util.Collection; 23*f585d8a3SJacky Wang import org.junit.Rule; 24*f585d8a3SJacky Wang import org.junit.Test; 25*f585d8a3SJacky Wang import org.junit.runner.RunWith; 26*f585d8a3SJacky Wang import org.junit.runners.Parameterized; 27*f585d8a3SJacky Wang import org.junit.runners.Parameterized.Parameters; 28*f585d8a3SJacky Wang 29*f585d8a3SJacky Wang @RunWith(Parameterized.class) 30*f585d8a3SJacky Wang public class ComponentRequirementFieldTest { 31*f585d8a3SJacky Wang @Parameters(name = "{0}") parameters()32*f585d8a3SJacky Wang public static Collection<Object[]> parameters() { 33*f585d8a3SJacky Wang return CompilerMode.TEST_PARAMETERS; 34*f585d8a3SJacky Wang } 35*f585d8a3SJacky Wang 36*f585d8a3SJacky Wang @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); 37*f585d8a3SJacky Wang 38*f585d8a3SJacky Wang private final CompilerMode compilerMode; 39*f585d8a3SJacky Wang ComponentRequirementFieldTest(CompilerMode compilerMode)40*f585d8a3SJacky Wang public ComponentRequirementFieldTest(CompilerMode compilerMode) { 41*f585d8a3SJacky Wang this.compilerMode = compilerMode; 42*f585d8a3SJacky Wang } 43*f585d8a3SJacky Wang 44*f585d8a3SJacky Wang @Test bindsInstance()45*f585d8a3SJacky Wang public void bindsInstance() throws Exception { 46*f585d8a3SJacky Wang Source component = 47*f585d8a3SJacky Wang CompilerTests.javaSource( 48*f585d8a3SJacky Wang "test.TestComponent", 49*f585d8a3SJacky Wang "package test;", 50*f585d8a3SJacky Wang "", 51*f585d8a3SJacky Wang "import dagger.BindsInstance;", 52*f585d8a3SJacky Wang "import dagger.Component;", 53*f585d8a3SJacky Wang "import java.util.List;", 54*f585d8a3SJacky Wang "", 55*f585d8a3SJacky Wang "@Component", 56*f585d8a3SJacky Wang "interface TestComponent {", 57*f585d8a3SJacky Wang " int i();", 58*f585d8a3SJacky Wang " List<String> list();", 59*f585d8a3SJacky Wang "", 60*f585d8a3SJacky Wang " @Component.Builder", 61*f585d8a3SJacky Wang " interface Builder {", 62*f585d8a3SJacky Wang " @BindsInstance Builder i(int i);", 63*f585d8a3SJacky Wang " @BindsInstance Builder list(List<String> list);", 64*f585d8a3SJacky Wang " TestComponent build();", 65*f585d8a3SJacky Wang " }", 66*f585d8a3SJacky Wang "}"); 67*f585d8a3SJacky Wang CompilerTests.daggerCompiler(component) 68*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 69*f585d8a3SJacky Wang .compile( 70*f585d8a3SJacky Wang subject -> { 71*f585d8a3SJacky Wang subject.hasErrorCount(0); 72*f585d8a3SJacky Wang subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 73*f585d8a3SJacky Wang }); 74*f585d8a3SJacky Wang } 75*f585d8a3SJacky Wang 76*f585d8a3SJacky Wang @Test instanceModuleMethod()77*f585d8a3SJacky Wang public void instanceModuleMethod() throws Exception { 78*f585d8a3SJacky Wang Source module = 79*f585d8a3SJacky Wang CompilerTests.javaSource( 80*f585d8a3SJacky Wang "test.ParentModule", 81*f585d8a3SJacky Wang "package test;", 82*f585d8a3SJacky Wang "", 83*f585d8a3SJacky Wang "import dagger.Module;", 84*f585d8a3SJacky Wang "import dagger.Provides;", 85*f585d8a3SJacky Wang "", 86*f585d8a3SJacky Wang "@Module", 87*f585d8a3SJacky Wang "class ParentModule {", 88*f585d8a3SJacky Wang " @Provides int i() { return 0; }", 89*f585d8a3SJacky Wang "}"); 90*f585d8a3SJacky Wang Source otherPackageModule = 91*f585d8a3SJacky Wang CompilerTests.javaSource( 92*f585d8a3SJacky Wang "other.OtherPackageModule", 93*f585d8a3SJacky Wang "package other;", 94*f585d8a3SJacky Wang "", 95*f585d8a3SJacky Wang "import dagger.Module;", 96*f585d8a3SJacky Wang "import dagger.Provides;", 97*f585d8a3SJacky Wang "", 98*f585d8a3SJacky Wang "@Module", 99*f585d8a3SJacky Wang "public class OtherPackageModule {", 100*f585d8a3SJacky Wang " @Provides long l() { return 0L; }", 101*f585d8a3SJacky Wang "}"); 102*f585d8a3SJacky Wang Source component = 103*f585d8a3SJacky Wang CompilerTests.javaSource( 104*f585d8a3SJacky Wang "test.TestComponent", 105*f585d8a3SJacky Wang "package test;", 106*f585d8a3SJacky Wang "", 107*f585d8a3SJacky Wang "import dagger.Component;", 108*f585d8a3SJacky Wang "import other.OtherPackageModule;", 109*f585d8a3SJacky Wang "", 110*f585d8a3SJacky Wang "@Component(modules = {ParentModule.class, OtherPackageModule.class})", 111*f585d8a3SJacky Wang "interface TestComponent {", 112*f585d8a3SJacky Wang " int i();", 113*f585d8a3SJacky Wang " long l();", 114*f585d8a3SJacky Wang "}"); 115*f585d8a3SJacky Wang CompilerTests.daggerCompiler(module, otherPackageModule, component) 116*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 117*f585d8a3SJacky Wang .compile( 118*f585d8a3SJacky Wang subject -> { 119*f585d8a3SJacky Wang subject.hasErrorCount(0); 120*f585d8a3SJacky Wang subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 121*f585d8a3SJacky Wang }); 122*f585d8a3SJacky Wang } 123*f585d8a3SJacky Wang 124*f585d8a3SJacky Wang @Test componentInstances()125*f585d8a3SJacky Wang public void componentInstances() throws Exception { 126*f585d8a3SJacky Wang Source dependency = 127*f585d8a3SJacky Wang CompilerTests.javaSource( 128*f585d8a3SJacky Wang "test.Dep", 129*f585d8a3SJacky Wang "package test;", 130*f585d8a3SJacky Wang "", 131*f585d8a3SJacky Wang "interface Dep {", 132*f585d8a3SJacky Wang " String string();", 133*f585d8a3SJacky Wang " Object object();", 134*f585d8a3SJacky Wang "}"); 135*f585d8a3SJacky Wang 136*f585d8a3SJacky Wang Source component = 137*f585d8a3SJacky Wang CompilerTests.javaSource( 138*f585d8a3SJacky Wang "test.TestComponent", 139*f585d8a3SJacky Wang "package test;", 140*f585d8a3SJacky Wang "", 141*f585d8a3SJacky Wang "import dagger.Component;", 142*f585d8a3SJacky Wang "", 143*f585d8a3SJacky Wang "@Component(dependencies = Dep.class)", 144*f585d8a3SJacky Wang "interface TestComponent {", 145*f585d8a3SJacky Wang " TestComponent self();", 146*f585d8a3SJacky Wang " TestSubcomponent subcomponent();", 147*f585d8a3SJacky Wang "", 148*f585d8a3SJacky Wang " Dep dep();", 149*f585d8a3SJacky Wang " String methodOnDep();", 150*f585d8a3SJacky Wang " Object otherMethodOnDep();", 151*f585d8a3SJacky Wang "}"); 152*f585d8a3SJacky Wang Source subcomponent = 153*f585d8a3SJacky Wang CompilerTests.javaSource( 154*f585d8a3SJacky Wang "test.TestSubcomponent", 155*f585d8a3SJacky Wang "package test;", 156*f585d8a3SJacky Wang "", 157*f585d8a3SJacky Wang "import dagger.Subcomponent;", 158*f585d8a3SJacky Wang "", 159*f585d8a3SJacky Wang "@Subcomponent", 160*f585d8a3SJacky Wang "interface TestSubcomponent {", 161*f585d8a3SJacky Wang " TestComponent parent();", 162*f585d8a3SJacky Wang " Dep depFromSubcomponent();", 163*f585d8a3SJacky Wang "}"); 164*f585d8a3SJacky Wang 165*f585d8a3SJacky Wang CompilerTests.daggerCompiler(dependency, component, subcomponent) 166*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 167*f585d8a3SJacky Wang .compile( 168*f585d8a3SJacky Wang subject -> { 169*f585d8a3SJacky Wang subject.hasErrorCount(0); 170*f585d8a3SJacky Wang subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 171*f585d8a3SJacky Wang }); 172*f585d8a3SJacky Wang } 173*f585d8a3SJacky Wang 174*f585d8a3SJacky Wang @Test componentRequirementNeededInFactoryCreationOfSubcomponent()175*f585d8a3SJacky Wang public void componentRequirementNeededInFactoryCreationOfSubcomponent() throws Exception { 176*f585d8a3SJacky Wang Source parentModule = 177*f585d8a3SJacky Wang CompilerTests.javaSource( 178*f585d8a3SJacky Wang "test.ParentModule", 179*f585d8a3SJacky Wang "package test;", 180*f585d8a3SJacky Wang "", 181*f585d8a3SJacky Wang "import dagger.Module;", 182*f585d8a3SJacky Wang "import dagger.multibindings.IntoSet;", 183*f585d8a3SJacky Wang "import dagger.Provides;", 184*f585d8a3SJacky Wang "import java.util.Set;", 185*f585d8a3SJacky Wang "", 186*f585d8a3SJacky Wang "@Module", 187*f585d8a3SJacky Wang "class ParentModule {", 188*f585d8a3SJacky Wang " @Provides", 189*f585d8a3SJacky Wang // intentionally non-static. this needs to require the module when the subcompnent 190*f585d8a3SJacky Wang // adds to the Set binding 191*f585d8a3SJacky Wang " Object reliesOnMultibinding(Set<Object> set) { return set; }", 192*f585d8a3SJacky Wang "", 193*f585d8a3SJacky Wang " @Provides @IntoSet static Object contribution() { return new Object(); }", 194*f585d8a3SJacky Wang "}"); 195*f585d8a3SJacky Wang 196*f585d8a3SJacky Wang Source childModule = 197*f585d8a3SJacky Wang CompilerTests.javaSource( 198*f585d8a3SJacky Wang "test.ChildModule", 199*f585d8a3SJacky Wang "package test;", 200*f585d8a3SJacky Wang "", 201*f585d8a3SJacky Wang "import dagger.Module;", 202*f585d8a3SJacky Wang "import dagger.multibindings.IntoSet;", 203*f585d8a3SJacky Wang "import dagger.Provides;", 204*f585d8a3SJacky Wang "", 205*f585d8a3SJacky Wang "@Module", 206*f585d8a3SJacky Wang "class ChildModule {", 207*f585d8a3SJacky Wang " @Provides @IntoSet static Object contribution() { return new Object(); }", 208*f585d8a3SJacky Wang "}"); 209*f585d8a3SJacky Wang 210*f585d8a3SJacky Wang Source component = 211*f585d8a3SJacky Wang CompilerTests.javaSource( 212*f585d8a3SJacky Wang "test.TestComponent", 213*f585d8a3SJacky Wang "package test;", 214*f585d8a3SJacky Wang "", 215*f585d8a3SJacky Wang "import dagger.Component;", 216*f585d8a3SJacky Wang "import javax.inject.Provider;", 217*f585d8a3SJacky Wang "", 218*f585d8a3SJacky Wang "@Component(modules = ParentModule.class)", 219*f585d8a3SJacky Wang "interface TestComponent {", 220*f585d8a3SJacky Wang " Provider<Object> dependsOnMultibinding();", 221*f585d8a3SJacky Wang " TestSubcomponent subcomponent();", 222*f585d8a3SJacky Wang "}"); 223*f585d8a3SJacky Wang 224*f585d8a3SJacky Wang Source subcomponent = 225*f585d8a3SJacky Wang CompilerTests.javaSource( 226*f585d8a3SJacky Wang "test.TestSubcomponent", 227*f585d8a3SJacky Wang "package test;", 228*f585d8a3SJacky Wang "", 229*f585d8a3SJacky Wang "import dagger.Subcomponent;", 230*f585d8a3SJacky Wang "import javax.inject.Provider;", 231*f585d8a3SJacky Wang "", 232*f585d8a3SJacky Wang "@Subcomponent(modules = ChildModule.class)", 233*f585d8a3SJacky Wang "interface TestSubcomponent {", 234*f585d8a3SJacky Wang " Provider<Object> dependsOnMultibinding();", 235*f585d8a3SJacky Wang "}"); 236*f585d8a3SJacky Wang 237*f585d8a3SJacky Wang CompilerTests.daggerCompiler(parentModule, childModule, component, subcomponent) 238*f585d8a3SJacky Wang .withProcessingOptions(compilerMode.processorOptions()) 239*f585d8a3SJacky Wang .compile( 240*f585d8a3SJacky Wang subject -> { 241*f585d8a3SJacky Wang subject.hasErrorCount(0); 242*f585d8a3SJacky Wang subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 243*f585d8a3SJacky Wang }); 244*f585d8a3SJacky Wang } 245*f585d8a3SJacky Wang } 246