1 /* 2 * Copyright (C) 2014 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen; 18 19 import androidx.room.compiler.processing.util.Source; 20 import com.google.common.collect.ImmutableList; 21 import dagger.testing.compile.CompilerTests; 22 import org.junit.Test; 23 import org.junit.runner.RunWith; 24 import org.junit.runners.Parameterized; 25 import org.junit.runners.Parameterized.Parameters; 26 27 @RunWith(Parameterized.class) 28 public class BindsInstanceValidationTest { 29 @Parameters(name = "{0}") parameters()30 public static ImmutableList<Object[]> parameters() { 31 return CompilerMode.TEST_PARAMETERS; 32 } 33 34 private final CompilerMode compilerMode; 35 BindsInstanceValidationTest(CompilerMode compilerMode)36 public BindsInstanceValidationTest(CompilerMode compilerMode) { 37 this.compilerMode = compilerMode; 38 } 39 40 @Test bindsInstanceInModule()41 public void bindsInstanceInModule() { 42 Source testModule = 43 CompilerTests.javaSource( 44 "test.TestModule", 45 "package test;", 46 "", 47 "import dagger.BindsInstance;", 48 "import dagger.Module;", 49 "", 50 "@Module", 51 "abstract class TestModule {", 52 " @BindsInstance abstract void str(String string);", 53 "}"); 54 CompilerTests.daggerCompiler(testModule) 55 .withProcessingOptions(compilerMode.processorOptions()) 56 .compile( 57 subject -> { 58 subject.hasErrorCount(1); 59 subject.hasErrorContaining( 60 "@BindsInstance methods should not be included in @Modules. Did you mean @Binds"); 61 }); 62 } 63 64 @Test bindsInstanceInComponent()65 public void bindsInstanceInComponent() { 66 Source testComponent = 67 CompilerTests.javaSource( 68 "test.TestComponent", 69 "package test;", 70 "", 71 "import dagger.BindsInstance;", 72 "import dagger.Component;", 73 "", 74 "@Component", 75 "interface TestComponent {", 76 " @BindsInstance String s(String s);", 77 "}"); 78 CompilerTests.daggerCompiler(testComponent) 79 .withProcessingOptions(compilerMode.processorOptions()) 80 .compile( 81 subject -> { 82 subject.hasErrorCount(1); 83 subject.hasErrorContaining( 84 "@BindsInstance methods should not be included in @Components. " 85 + "Did you mean to put it in a @Component.Builder?"); 86 }); 87 } 88 89 @Test bindsInstanceNotAbstract()90 public void bindsInstanceNotAbstract() { 91 Source notAbstract = 92 CompilerTests.javaSource( 93 "test.BindsInstanceNotAbstract", 94 "package test;", 95 "", 96 "import dagger.BindsInstance;", 97 "import dagger.Component;", 98 "", 99 "class BindsInstanceNotAbstract {", 100 " @BindsInstance BindsInstanceNotAbstract bind(int unused) { return this; }", 101 "}"); 102 CompilerTests.daggerCompiler(notAbstract) 103 .withProcessingOptions(compilerMode.processorOptions()) 104 .compile( 105 subject -> { 106 subject.hasErrorCount(1); 107 subject.hasErrorContaining("@BindsInstance methods must be abstract") 108 .onSource(notAbstract) 109 .onLine(7); 110 }); 111 } 112 113 @Test bindsInstanceNoParameters()114 public void bindsInstanceNoParameters() { 115 Source notAbstract = 116 CompilerTests.javaSource( 117 "test.BindsInstanceNoParameters", 118 "package test;", 119 "", 120 "import dagger.BindsInstance;", 121 "", 122 "interface BindsInstanceNoParameters {", 123 " @BindsInstance void noParams();", 124 "}"); 125 CompilerTests.daggerCompiler(notAbstract) 126 .withProcessingOptions(compilerMode.processorOptions()) 127 .compile( 128 subject -> { 129 subject.hasErrorCount(1); 130 subject.hasErrorContaining( 131 "@BindsInstance methods should have exactly one parameter for the bound type") 132 .onSource(notAbstract) 133 .onLine(6); 134 }); 135 } 136 137 @Test bindsInstanceManyParameters()138 public void bindsInstanceManyParameters() { 139 Source notAbstract = 140 CompilerTests.javaSource( 141 "test.BindsInstanceNoParameter", 142 "package test;", 143 "", 144 "import dagger.BindsInstance;", 145 "", 146 "interface BindsInstanceManyParameters {", 147 " @BindsInstance void manyParams(int i, long l);", 148 "}"); 149 CompilerTests.daggerCompiler(notAbstract) 150 .withProcessingOptions(compilerMode.processorOptions()) 151 .compile( 152 subject -> { 153 subject.hasErrorCount(1); 154 subject.hasErrorContaining( 155 "@BindsInstance methods should have exactly one parameter for the bound type") 156 .onSource(notAbstract) 157 .onLine(6); 158 }); 159 } 160 161 @Test bindsInstanceFrameworkType()162 public void bindsInstanceFrameworkType() { 163 Source bindsFrameworkType = 164 CompilerTests.javaSource( 165 "test.BindsInstanceFrameworkType", 166 "package test;", 167 "", 168 "import dagger.BindsInstance;", 169 "import dagger.producers.Producer;", 170 "import javax.inject.Provider;", 171 "", 172 "interface BindsInstanceFrameworkType {", 173 " @BindsInstance void bindsProvider(Provider<Object> objectProvider);", 174 " @BindsInstance void bindsProducer(Producer<Object> objectProducer);", 175 "}"); 176 CompilerTests.daggerCompiler(bindsFrameworkType) 177 .withProcessingOptions(compilerMode.processorOptions()) 178 .compile( 179 subject -> { 180 subject.hasErrorCount(2); 181 subject.hasErrorContaining("@BindsInstance parameters must not be framework types") 182 .onSource(bindsFrameworkType) 183 .onLine(8); 184 subject.hasErrorContaining("@BindsInstance parameters must not be framework types") 185 .onSource(bindsFrameworkType) 186 .onLine(9); 187 }); 188 } 189 190 } 191