1 /* 2 * Copyright (C) 2020 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.ImmutableCollection; 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 AssistedInjectErrorsTest { 29 @Parameters(name = "{0}") parameters()30 public static ImmutableCollection<Object[]> parameters() { 31 return CompilerMode.TEST_PARAMETERS; 32 } 33 34 private final CompilerMode compilerMode; 35 AssistedInjectErrorsTest(CompilerMode compilerMode)36 public AssistedInjectErrorsTest(CompilerMode compilerMode) { 37 this.compilerMode = compilerMode; 38 } 39 40 @Test testAssistedInjectWithDuplicateTypesFails()41 public void testAssistedInjectWithDuplicateTypesFails() { 42 Source foo = 43 CompilerTests.javaSource( 44 "test.Foo", 45 "package test;", 46 "", 47 "import dagger.assisted.Assisted;", 48 "import dagger.assisted.AssistedInject;", 49 "", 50 "class Foo {", 51 " @AssistedInject", 52 " Foo(@Assisted String str1, @Assisted String str2) {}", 53 "}"); 54 55 CompilerTests.daggerCompiler(foo) 56 .withProcessingOptions(compilerMode.processorOptions()) 57 .compile( 58 subject -> { 59 subject.hasErrorCount(1); 60 subject.hasErrorContaining( 61 "@AssistedInject constructor has duplicate @Assisted type: @Assisted " 62 + "java.lang.String") 63 .onSource(foo) 64 .onLine(8); 65 }); 66 } 67 68 @Test testAssistedInjectWithDuplicateTypesEmptyQualifierFails()69 public void testAssistedInjectWithDuplicateTypesEmptyQualifierFails() { 70 Source foo = 71 CompilerTests.javaSource( 72 "test.Foo", 73 "package test;", 74 "", 75 "import dagger.assisted.Assisted;", 76 "import dagger.assisted.AssistedInject;", 77 "", 78 "class Foo {", 79 " @AssistedInject", 80 " Foo(@Assisted(\"\") String str1, @Assisted String str2) {}", 81 "}"); 82 83 CompilerTests.daggerCompiler(foo) 84 .withProcessingOptions(compilerMode.processorOptions()) 85 .compile( 86 subject -> { 87 subject.hasErrorCount(1); 88 subject.hasErrorContaining( 89 "@AssistedInject constructor has duplicate @Assisted type: @Assisted " 90 + "java.lang.String") 91 .onSource(foo) 92 .onLine(8); 93 }); 94 } 95 96 @Test testAssistedInjectWithDuplicateQualifiedTypesFails()97 public void testAssistedInjectWithDuplicateQualifiedTypesFails() { 98 Source foo = 99 CompilerTests.javaSource( 100 "test.Foo", 101 "package test;", 102 "", 103 "import dagger.assisted.Assisted;", 104 "import dagger.assisted.AssistedInject;", 105 "", 106 "class Foo<T> {", 107 " @AssistedInject", 108 " Foo(@Assisted(\"MyQualfier\") String s1, @Assisted(\"MyQualfier\") String s2) {}", 109 "}"); 110 111 CompilerTests.daggerCompiler(foo) 112 .withProcessingOptions(compilerMode.processorOptions()) 113 .compile( 114 subject -> { 115 subject.hasErrorCount(1); 116 subject.hasErrorContaining( 117 "@AssistedInject constructor has duplicate @Assisted type: " 118 + "@Assisted(\"MyQualfier\") java.lang.String") 119 .onSource(foo) 120 .onLine(8); 121 }); 122 } 123 124 @Test testAssistedInjectWithDuplicateGenericTypesFails()125 public void testAssistedInjectWithDuplicateGenericTypesFails() { 126 Source foo = 127 CompilerTests.javaSource( 128 "test.Foo", 129 "package test;", 130 "", 131 "import dagger.assisted.Assisted;", 132 "import dagger.assisted.AssistedInject;", 133 "import java.util.List;", 134 "", 135 "class Foo {", 136 " @AssistedInject", 137 " Foo(@Assisted List<String> list1, @Assisted List<String> list2) {}", 138 "}"); 139 140 CompilerTests.daggerCompiler(foo) 141 .withProcessingOptions(compilerMode.processorOptions()) 142 .compile( 143 subject -> { 144 subject.hasErrorCount(1); 145 subject.hasErrorContaining( 146 "@AssistedInject constructor has duplicate @Assisted type: " 147 + "@Assisted java.util.List<java.lang.String>") 148 .onSource(foo) 149 .onLine(9); 150 }); 151 } 152 153 @Test testAssistedInjectWithDuplicateParameterizedTypesFails()154 public void testAssistedInjectWithDuplicateParameterizedTypesFails() { 155 Source foo = 156 CompilerTests.javaSource( 157 "test.Foo", 158 "package test;", 159 "", 160 "import dagger.assisted.Assisted;", 161 "import dagger.assisted.AssistedInject;", 162 "", 163 "class Foo<T> {", 164 " @AssistedInject", 165 " Foo(@Assisted T t1, @Assisted T t2) {}", 166 "}"); 167 168 CompilerTests.daggerCompiler(foo) 169 .withProcessingOptions(compilerMode.processorOptions()) 170 .compile( 171 subject -> { 172 subject.hasErrorCount(1); 173 subject.hasErrorContaining( 174 "@AssistedInject constructor has duplicate @Assisted type: @Assisted T") 175 .onSource(foo) 176 .onLine(8); 177 }); 178 } 179 180 @Test testAssistedInjectWithUniqueParameterizedTypesPasses()181 public void testAssistedInjectWithUniqueParameterizedTypesPasses() { 182 Source foo = 183 CompilerTests.javaSource( 184 "test.Foo", 185 "package test;", 186 "", 187 "import dagger.assisted.Assisted;", 188 "import dagger.assisted.AssistedInject;", 189 "import java.util.List;", 190 "", 191 "class Foo<T1, T2> {", 192 " @AssistedInject", 193 " Foo(@Assisted T1 t1, @Assisted T2 t2) {}", 194 "}"); 195 196 CompilerTests.daggerCompiler(foo) 197 .withProcessingOptions(compilerMode.processorOptions()) 198 .compile(subject -> subject.hasErrorCount(0)); 199 } 200 201 @Test testAssistedInjectWithUniqueGenericTypesPasses()202 public void testAssistedInjectWithUniqueGenericTypesPasses() { 203 Source foo = 204 CompilerTests.javaSource( 205 "test.Foo", 206 "package test;", 207 "", 208 "import dagger.assisted.Assisted;", 209 "import dagger.assisted.AssistedInject;", 210 "import java.util.List;", 211 "", 212 "class Foo {", 213 " @AssistedInject", 214 " Foo(@Assisted List<String> list1, @Assisted List<Integer> list2) {}", 215 "}"); 216 217 CompilerTests.daggerCompiler(foo) 218 .withProcessingOptions(compilerMode.processorOptions()) 219 .compile(subject -> subject.hasErrorCount(0)); 220 } 221 222 @Test testAssistedInjectWithUniqueQualifiedTypesPasses()223 public void testAssistedInjectWithUniqueQualifiedTypesPasses() { 224 Source foo = 225 CompilerTests.javaSource( 226 "test.Foo", 227 "package test;", 228 "", 229 "import dagger.assisted.Assisted;", 230 "import dagger.assisted.AssistedInject;", 231 "import java.util.List;", 232 "", 233 "class Foo {", 234 " @AssistedInject", 235 " Foo(", 236 " @Assisted(\"1\") Integer i1,", 237 " @Assisted(\"1\") String s1,", 238 " @Assisted(\"2\") String s2,", 239 " @Assisted String s3) {}", 240 "}"); 241 242 CompilerTests.daggerCompiler(foo) 243 .withProcessingOptions(compilerMode.processorOptions()) 244 .compile(subject -> subject.hasErrorCount(0)); 245 } 246 247 @Test testMultipleInjectedConstructors()248 public void testMultipleInjectedConstructors() { 249 Source foo = 250 CompilerTests.kotlinSource( 251 "test.Foo.kt", 252 "package test;", 253 "", 254 "import dagger.assisted.Assisted", 255 "import dagger.assisted.AssistedInject", 256 "import dagger.assisted.AssistedFactory", 257 "import javax.inject.Inject", 258 "", 259 "class Foo @AssistedInject constructor(@Assisted i: Int) {", 260 "", 261 " @Inject", 262 " constructor(s: String, @Assisted i: Int): this(i) {}", 263 "}"); 264 265 CompilerTests.daggerCompiler(foo) 266 .withProcessingOptions(compilerMode.processorOptions()) 267 .compile( 268 subject -> { 269 subject.hasErrorCount(2); 270 subject.hasErrorContaining( 271 "Type test.Foo may only contain one injected constructor." 272 + " Found: [@Inject test.Foo(String, int)," 273 + " @dagger.assisted.AssistedInject test.Foo(int)]"); 274 subject.hasErrorContaining( 275 "@Assisted parameters can only be used within an" 276 + " @AssistedInject-annotated constructor."); 277 }); 278 } 279 280 @Test testMultipleAssistedInjectedConstructors()281 public void testMultipleAssistedInjectedConstructors() { 282 Source foo = 283 CompilerTests.kotlinSource( 284 "test.Foo.kt", 285 "package test;", 286 "", 287 "import dagger.assisted.Assisted", 288 "import dagger.assisted.AssistedInject", 289 "import dagger.assisted.AssistedFactory", 290 "", 291 "class Foo @AssistedInject constructor(@Assisted i: Int) {", 292 "", 293 " @AssistedInject", 294 " constructor(s: String, @Assisted i: Int): this(i) {}", 295 "}"); 296 297 CompilerTests.daggerCompiler(foo) 298 .withProcessingOptions(compilerMode.processorOptions()) 299 .compile( 300 subject -> { 301 subject.hasErrorCount(1); 302 subject.hasErrorContaining( 303 "Type test.Foo may only contain one injected constructor." 304 + " Found: [@dagger.assisted.AssistedInject test.Foo(int)," 305 + " @dagger.assisted.AssistedInject test.Foo(String, int)]"); 306 }); 307 } 308 } 309