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 static com.google.common.truth.Truth.assertAbout; 20 import static com.google.testing.compile.CompilationSubject.assertThat; 21 import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; 22 import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; 23 import static dagger.internal.codegen.Compilers.compilerWithOptions; 24 import static dagger.internal.codegen.Compilers.daggerCompiler; 25 26 import com.google.common.collect.ImmutableList; 27 import com.google.testing.compile.Compilation; 28 import com.google.testing.compile.JavaFileObjects; 29 import javax.tools.JavaFileObject; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.junit.runners.JUnit4; 33 34 @RunWith(JUnit4.class) 35 // TODO(gak): add tests for generation in the default package. 36 public final class InjectConstructorFactoryGeneratorTest { 37 private static final JavaFileObject QUALIFIER_A = 38 JavaFileObjects.forSourceLines("test.QualifierA", 39 "package test;", 40 "", 41 "import javax.inject.Qualifier;", 42 "", 43 "@Qualifier @interface QualifierA {}"); 44 private static final JavaFileObject QUALIFIER_B = 45 JavaFileObjects.forSourceLines("test.QualifierB", 46 "package test;", 47 "", 48 "import javax.inject.Qualifier;", 49 "", 50 "@Qualifier @interface QualifierB {}"); 51 private static final JavaFileObject SCOPE_A = 52 JavaFileObjects.forSourceLines("test.ScopeA", 53 "package test;", 54 "", 55 "import javax.inject.Scope;", 56 "", 57 "@Scope @interface ScopeA {}"); 58 private static final JavaFileObject SCOPE_B = 59 JavaFileObjects.forSourceLines("test.ScopeB", 60 "package test;", 61 "", 62 "import javax.inject.Scope;", 63 "", 64 "@Scope @interface ScopeB {}"); 65 injectOnPrivateConstructor()66 @Test public void injectOnPrivateConstructor() { 67 JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateConstructor", 68 "package test;", 69 "", 70 "import javax.inject.Inject;", 71 "", 72 "class PrivateConstructor {", 73 " @Inject private PrivateConstructor() {}", 74 "}"); 75 Compilation compilation = daggerCompiler().compile(file); 76 assertThat(compilation).failed(); 77 assertThat(compilation) 78 .hadErrorContaining("Dagger does not support injection into private constructors") 79 .inFile(file) 80 .onLine(6); 81 } 82 injectConstructorOnInnerClass()83 @Test public void injectConstructorOnInnerClass() { 84 JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass", 85 "package test;", 86 "", 87 "import javax.inject.Inject;", 88 "", 89 "class OuterClass {", 90 " class InnerClass {", 91 " @Inject InnerClass() {}", 92 " }", 93 "}"); 94 Compilation compilation = daggerCompiler().compile(file); 95 assertThat(compilation).failed(); 96 assertThat(compilation) 97 .hadErrorContaining( 98 "@Inject constructors are invalid on inner classes. " 99 + "Did you mean to make the class static?") 100 .inFile(file) 101 .onLine(7); 102 } 103 injectConstructorOnAbstractClass()104 @Test public void injectConstructorOnAbstractClass() { 105 JavaFileObject file = JavaFileObjects.forSourceLines("test.AbstractClass", 106 "package test;", 107 "", 108 "import javax.inject.Inject;", 109 "", 110 "abstract class AbstractClass {", 111 " @Inject AbstractClass() {}", 112 "}"); 113 Compilation compilation = daggerCompiler().compile(file); 114 assertThat(compilation).failed(); 115 assertThat(compilation) 116 .hadErrorContaining("@Inject is nonsense on the constructor of an abstract class") 117 .inFile(file) 118 .onLine(6); 119 } 120 injectConstructorOnGenericClass()121 @Test public void injectConstructorOnGenericClass() { 122 JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass", 123 "package test;", 124 "", 125 "import javax.inject.Inject;", 126 "", 127 "class GenericClass<T> {", 128 " @Inject GenericClass(T t) {}", 129 "}"); 130 JavaFileObject expected = 131 JavaFileObjects.forSourceLines( 132 "test.GenericClass_Factory", 133 "package test;", 134 "", 135 GeneratedLines.generatedImports( 136 "import dagger.internal.Factory;", 137 "import dagger.internal.QualifierMetadata;", 138 "import dagger.internal.ScopeMetadata;", 139 "import javax.inject.Provider;"), 140 "", 141 "@ScopeMetadata", 142 "@QualifierMetadata", 143 GeneratedLines.generatedAnnotations(), 144 "public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> {", 145 " private final Provider<T> tProvider;", 146 "", 147 " public GenericClass_Factory(Provider<T> tProvider) {", 148 " this.tProvider = tProvider;", 149 " }", 150 "", 151 " @Override", 152 " public GenericClass<T> get() {", 153 " return newInstance(tProvider.get());", 154 " }", 155 "", 156 " public static <T> GenericClass_Factory<T> create(Provider<T> tProvider) {", 157 " return new GenericClass_Factory<T>(tProvider);", 158 " }", 159 "", 160 " public static <T> GenericClass<T> newInstance(T t) {", 161 " return new GenericClass<T>(t);", 162 " }", 163 "}"); 164 assertAbout(javaSource()).that(file) 165 .processedWith(new ComponentProcessor()) 166 .compilesWithoutError() 167 .and().generatesSources(expected); 168 } 169 fieldAndMethodGenerics()170 @Test public void fieldAndMethodGenerics() { 171 JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass", 172 "package test;", 173 "", 174 "import javax.inject.Inject;", 175 "", 176 "class GenericClass<A, B> {", 177 " @Inject A a;", 178 "", 179 " @Inject GenericClass() {}", 180 "", 181 " @Inject void register(B b) {}", 182 "}"); 183 JavaFileObject expected = 184 JavaFileObjects.forSourceLines( 185 "test.GenericClass_Factory", 186 "package test;", 187 "", 188 GeneratedLines.generatedImports( 189 "import dagger.internal.Factory;", 190 "import dagger.internal.QualifierMetadata;", 191 "import dagger.internal.ScopeMetadata;", 192 "import javax.inject.Provider;"), 193 "", 194 "@ScopeMetadata", 195 "@QualifierMetadata", 196 GeneratedLines.generatedAnnotations(), 197 "public final class GenericClass_Factory<A, B> implements", 198 " Factory<GenericClass<A, B>> {", 199 " private final Provider<A> aProvider;", 200 " private final Provider<B> bProvider;", 201 "", 202 " public GenericClass_Factory(", 203 " Provider<A> aProvider, Provider<B> bProvider) {", 204 " this.aProvider = aProvider;", 205 " this.bProvider = bProvider;", 206 " }", 207 "", 208 " @Override", 209 " public GenericClass<A, B> get() {", 210 " GenericClass<A, B> instance = newInstance();", 211 " GenericClass_MembersInjector.injectA(instance, aProvider.get());", 212 " GenericClass_MembersInjector.injectRegister(instance, bProvider.get());", 213 " return instance;", 214 " }", 215 "", 216 " public static <A, B> GenericClass_Factory<A, B> create(", 217 " Provider<A> aProvider, Provider<B> bProvider) {", 218 " return new GenericClass_Factory<A, B>(aProvider, bProvider);", 219 " }", 220 "", 221 " public static <A, B> GenericClass<A, B> newInstance() {", 222 " return new GenericClass<A, B>();", 223 " }", 224 "}"); 225 assertAbout(javaSource()).that(file) 226 .processedWith(new ComponentProcessor()) 227 .compilesWithoutError() 228 .and().generatesSources(expected); 229 } 230 genericClassWithNoDependencies()231 @Test public void genericClassWithNoDependencies() { 232 JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass", 233 "package test;", 234 "", 235 "import javax.inject.Inject;", 236 "", 237 "class GenericClass<T> {", 238 " @Inject GenericClass() {}", 239 "}"); 240 JavaFileObject expected = 241 JavaFileObjects.forSourceLines( 242 "test.GenericClass_Factory", 243 "package test;", 244 "", 245 GeneratedLines.generatedImports( 246 "import dagger.internal.Factory;", 247 "import dagger.internal.QualifierMetadata;", 248 "import dagger.internal.ScopeMetadata;"), 249 "", 250 "@ScopeMetadata", 251 "@QualifierMetadata", 252 GeneratedLines.generatedAnnotations(), 253 "public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> {", 254 " @Override", 255 " public GenericClass<T> get() {", 256 " return newInstance();", 257 " }", 258 "", 259 " @SuppressWarnings(\"unchecked\")", 260 " public static <T> GenericClass_Factory<T> create() {", 261 " return InstanceHolder.INSTANCE;", 262 " }", 263 "", 264 " public static <T> GenericClass<T> newInstance() {", 265 " return new GenericClass<T>();", 266 " }", 267 "", 268 " private static final class InstanceHolder {", 269 " @SuppressWarnings(\"rawtypes\")", 270 " private static final GenericClass_Factory INSTANCE = new GenericClass_Factory();", 271 " }", 272 "}"); 273 assertAbout(javaSource()).that(file) 274 .processedWith(new ComponentProcessor()) 275 .compilesWithoutError() 276 .and().generatesSources(expected); 277 } 278 twoGenericTypes()279 @Test public void twoGenericTypes() { 280 JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass", 281 "package test;", 282 "", 283 "import javax.inject.Inject;", 284 "", 285 "class GenericClass<A, B> {", 286 " @Inject GenericClass(A a, B b) {}", 287 "}"); 288 JavaFileObject expected = 289 JavaFileObjects.forSourceLines( 290 "test.GenericClass_Factory", 291 "package test;", 292 "", 293 GeneratedLines.generatedImports( 294 "import dagger.internal.Factory;", 295 "import dagger.internal.QualifierMetadata;", 296 "import dagger.internal.ScopeMetadata;", 297 "import javax.inject.Provider;"), 298 "", 299 "@ScopeMetadata", 300 "@QualifierMetadata", 301 GeneratedLines.generatedAnnotations(), 302 "public final class GenericClass_Factory<A, B>", 303 " implements Factory<GenericClass<A, B>> {", 304 " private final Provider<A> aProvider;", 305 " private final Provider<B> bProvider;", 306 "", 307 " public GenericClass_Factory(Provider<A> aProvider, Provider<B> bProvider) {", 308 " this.aProvider = aProvider;", 309 " this.bProvider = bProvider;", 310 " }", 311 "", 312 " @Override", 313 " public GenericClass<A, B> get() {", 314 " return newInstance(aProvider.get(), bProvider.get());", 315 " }", 316 "", 317 " public static <A, B> GenericClass_Factory<A, B> create(", 318 " Provider<A> aProvider, Provider<B> bProvider) {", 319 " return new GenericClass_Factory<A, B>(aProvider, bProvider);", 320 " }", 321 "", 322 " public static <A, B> GenericClass<A, B> newInstance(A a, B b) {", 323 " return new GenericClass<A, B>(a, b);", 324 " }", 325 "}"); 326 assertAbout(javaSource()).that(file) 327 .processedWith(new ComponentProcessor()) 328 .compilesWithoutError() 329 .and().generatesSources(expected); 330 } 331 boundedGenerics()332 @Test public void boundedGenerics() { 333 JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass", 334 "package test;", 335 "", 336 "import javax.inject.Inject;", 337 "import java.util.List;", 338 "", 339 "class GenericClass<A extends Number & Comparable<A>,", 340 " B extends List<? extends String>,", 341 " C extends List<? super String>> {", 342 " @Inject GenericClass(A a, B b, C c) {}", 343 "}"); 344 JavaFileObject expected = 345 JavaFileObjects.forSourceLines( 346 "test.GenericClass_Factory", 347 "package test;", 348 "", 349 GeneratedLines.generatedImports( 350 "import dagger.internal.Factory;", 351 "import dagger.internal.QualifierMetadata;", 352 "import dagger.internal.ScopeMetadata;", 353 "import java.util.List;", 354 "import javax.inject.Provider;"), 355 "", 356 "@ScopeMetadata", 357 "@QualifierMetadata", 358 GeneratedLines.generatedAnnotations(), 359 "public final class GenericClass_Factory<A extends Number & Comparable<A>,", 360 " B extends List<? extends String>,", 361 " C extends List<? super String>>", 362 " implements Factory<GenericClass<A, B, C>> {", 363 " private final Provider<A> aProvider;", 364 " private final Provider<B> bProvider;", 365 " private final Provider<C> cProvider;", 366 "", 367 " public GenericClass_Factory(Provider<A> aProvider,", 368 " Provider<B> bProvider,", 369 " Provider<C> cProvider) {", 370 " this.aProvider = aProvider;", 371 " this.bProvider = bProvider;", 372 " this.cProvider = cProvider;", 373 " }", 374 "", 375 " @Override", 376 " public GenericClass<A, B, C> get() {", 377 " return newInstance(aProvider.get(), bProvider.get(), cProvider.get());", 378 " }", 379 "", 380 " public static <A extends Number & Comparable<A>,", 381 " B extends List<? extends String>,", 382 " C extends List<? super String>> GenericClass_Factory<A, B, C> create(", 383 " Provider<A> aProvider, Provider<B> bProvider, Provider<C> cProvider) {", 384 " return new GenericClass_Factory<A, B, C>(aProvider, bProvider, cProvider);", 385 " }", 386 "", 387 " public static <", 388 " A extends Number & Comparable<A>,", 389 " B extends List<? extends String>,", 390 " C extends List<? super String>>", 391 " GenericClass<A, B, C> newInstance(A a, B b, C c) {", 392 " return new GenericClass<A, B, C>(a, b, c);", 393 " }", 394 "}"); 395 assertAbout(javaSource()).that(file) 396 .processedWith(new ComponentProcessor()) 397 .compilesWithoutError() 398 .and().generatesSources(expected); 399 } 400 multipleSameTypesWithGenericsAndQualifiersAndLazies()401 @Test public void multipleSameTypesWithGenericsAndQualifiersAndLazies() { 402 JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericClass", 403 "package test;", 404 "", 405 "import javax.inject.Inject;", 406 "import javax.inject.Provider;", 407 "import dagger.Lazy;", 408 "", 409 "class GenericClass<A, B> {", 410 " @Inject GenericClass(A a, A a2, Provider<A> pa, @QualifierA A qa, Lazy<A> la, ", 411 " String s, String s2, Provider<String> ps, ", 412 " @QualifierA String qs, Lazy<String> ls,", 413 " B b, B b2, Provider<B> pb, @QualifierA B qb, Lazy<B> lb) {}", 414 "}"); 415 JavaFileObject expected = 416 JavaFileObjects.forSourceLines( 417 "test.GenericClass_Factory", 418 "package test;", 419 "", 420 GeneratedLines.generatedImports( 421 "import dagger.Lazy;", 422 "import dagger.internal.DoubleCheck;", 423 "import dagger.internal.Factory;", 424 "import dagger.internal.QualifierMetadata;", 425 "import dagger.internal.ScopeMetadata;", 426 "import javax.inject.Provider;"), 427 "", 428 "@ScopeMetadata", 429 "@QualifierMetadata(\"test.QualifierA\")", 430 GeneratedLines.generatedAnnotations(), 431 "public final class GenericClass_Factory<A, B>", 432 " implements Factory<GenericClass<A, B>> {", 433 " private final Provider<A> aProvider;", 434 " private final Provider<A> a2Provider;", 435 " private final Provider<A> paProvider;", 436 " private final Provider<A> qaProvider;", 437 " private final Provider<A> laProvider;", 438 " private final Provider<String> sProvider;", 439 " private final Provider<String> s2Provider;", 440 " private final Provider<String> psProvider;", 441 " private final Provider<String> qsProvider;", 442 " private final Provider<String> lsProvider;", 443 " private final Provider<B> bProvider;", 444 " private final Provider<B> b2Provider;", 445 " private final Provider<B> pbProvider;", 446 " private final Provider<B> qbProvider;", 447 " private final Provider<B> lbProvider;", 448 "", 449 " public GenericClass_Factory(", 450 " Provider<A> aProvider,", 451 " Provider<A> a2Provider,", 452 " Provider<A> paProvider,", 453 " Provider<A> qaProvider,", 454 " Provider<A> laProvider,", 455 " Provider<String> sProvider,", 456 " Provider<String> s2Provider,", 457 " Provider<String> psProvider,", 458 " Provider<String> qsProvider,", 459 " Provider<String> lsProvider,", 460 " Provider<B> bProvider,", 461 " Provider<B> b2Provider,", 462 " Provider<B> pbProvider,", 463 " Provider<B> qbProvider,", 464 " Provider<B> lbProvider) {", 465 " this.aProvider = aProvider;", 466 " this.a2Provider = a2Provider;", 467 " this.paProvider = paProvider;", 468 " this.qaProvider = qaProvider;", 469 " this.laProvider = laProvider;", 470 " this.sProvider = sProvider;", 471 " this.s2Provider = s2Provider;", 472 " this.psProvider = psProvider;", 473 " this.qsProvider = qsProvider;", 474 " this.lsProvider = lsProvider;", 475 " this.bProvider = bProvider;", 476 " this.b2Provider = b2Provider;", 477 " this.pbProvider = pbProvider;", 478 " this.qbProvider = qbProvider;", 479 " this.lbProvider = lbProvider;", 480 " }", 481 "", 482 " @Override", 483 " public GenericClass<A, B> get() {", 484 " return newInstance(", 485 " aProvider.get(),", 486 " a2Provider.get(),", 487 " paProvider,", 488 " qaProvider.get(),", 489 " DoubleCheck.lazy(laProvider),", 490 " sProvider.get(),", 491 " s2Provider.get(),", 492 " psProvider,", 493 " qsProvider.get(),", 494 " DoubleCheck.lazy(lsProvider),", 495 " bProvider.get(),", 496 " b2Provider.get(),", 497 " pbProvider,", 498 " qbProvider.get(),", 499 " DoubleCheck.lazy(lbProvider));", 500 " }", 501 "", 502 " public static <A, B> GenericClass_Factory<A, B> create(", 503 " Provider<A> aProvider,", 504 " Provider<A> a2Provider,", 505 " Provider<A> paProvider,", 506 " Provider<A> qaProvider,", 507 " Provider<A> laProvider,", 508 " Provider<String> sProvider,", 509 " Provider<String> s2Provider,", 510 " Provider<String> psProvider,", 511 " Provider<String> qsProvider,", 512 " Provider<String> lsProvider,", 513 " Provider<B> bProvider,", 514 " Provider<B> b2Provider,", 515 " Provider<B> pbProvider,", 516 " Provider<B> qbProvider,", 517 " Provider<B> lbProvider) {", 518 " return new GenericClass_Factory<A, B>(", 519 " aProvider,", 520 " a2Provider,", 521 " paProvider,", 522 " qaProvider,", 523 " laProvider,", 524 " sProvider,", 525 " s2Provider,", 526 " psProvider,", 527 " qsProvider,", 528 " lsProvider,", 529 " bProvider,", 530 " b2Provider,", 531 " pbProvider,", 532 " qbProvider,", 533 " lbProvider);", 534 " }", 535 "", 536 " public static <A, B> GenericClass<A, B> newInstance(", 537 " A a,", 538 " A a2,", 539 " Provider<A> pa,", 540 " A qa,", 541 " Lazy<A> la,", 542 " String s,", 543 " String s2,", 544 " Provider<String> ps,", 545 " String qs,", 546 " Lazy<String> ls,", 547 " B b,", 548 " B b2,", 549 " Provider<B> pb,", 550 " B qb,", 551 " Lazy<B> lb) {", 552 " return new GenericClass<A, B>(", 553 " a, a2, pa, qa, la, s, s2, ps, qs, ls, b, b2, pb, qb, lb);", 554 " }", 555 "}"); 556 assertAbout(javaSources()).that(ImmutableList.of(file, QUALIFIER_A)) 557 .processedWith(new ComponentProcessor()) 558 .compilesWithoutError() 559 .and().generatesSources(expected); 560 } 561 multipleInjectConstructors()562 @Test public void multipleInjectConstructors() { 563 JavaFileObject file = JavaFileObjects.forSourceLines("test.TooManyInjectConstructors", 564 "package test;", 565 "", 566 "import javax.inject.Inject;", 567 "", 568 "class TooManyInjectConstructors {", 569 " @Inject TooManyInjectConstructors() {}", 570 " TooManyInjectConstructors(int i) {}", 571 " @Inject TooManyInjectConstructors(String s) {}", 572 "}"); 573 Compilation compilation = daggerCompiler().compile(file); 574 assertThat(compilation).failed(); 575 assertThat(compilation).hadErrorCount(1); 576 assertThat(compilation) 577 .hadErrorContaining( 578 "Type test.TooManyInjectConstructors may only contain one injected constructor. " 579 + "Found: [" 580 + "TooManyInjectConstructors(), " 581 + "TooManyInjectConstructors(java.lang.String)" 582 + "]") 583 .inFile(file) 584 .onLine(5); 585 } 586 multipleQualifiersOnInjectConstructorParameter()587 @Test public void multipleQualifiersOnInjectConstructorParameter() { 588 JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierConstructorParam", 589 "package test;", 590 "", 591 "import javax.inject.Inject;", 592 "", 593 "class MultipleQualifierConstructorParam {", 594 " @Inject MultipleQualifierConstructorParam(@QualifierA @QualifierB String s) {}", 595 "}"); 596 Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B); 597 assertThat(compilation).failed(); 598 // for whatever reason, javac only reports the error once on the constructor 599 assertThat(compilation) 600 .hadErrorContaining("A single dependency request may not use more than one @Qualifier") 601 .inFile(file) 602 .onLine(6); 603 } 604 injectConstructorOnClassWithMultipleScopes()605 @Test public void injectConstructorOnClassWithMultipleScopes() { 606 JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleScopeClass", 607 "package test;", 608 "", 609 "import javax.inject.Inject;", 610 "", 611 "@ScopeA @ScopeB class MultipleScopeClass {", 612 " @Inject MultipleScopeClass() {}", 613 "}"); 614 Compilation compilation = daggerCompiler().compile(file, SCOPE_A, SCOPE_B); 615 assertThat(compilation).failed(); 616 assertThat(compilation) 617 .hadErrorContaining("A single binding may not declare more than one @Scope") 618 .inFile(file) 619 .onLine(5) 620 .atColumn(1); 621 assertThat(compilation) 622 .hadErrorContaining("A single binding may not declare more than one @Scope") 623 .inFile(file) 624 .onLine(5) 625 .atColumn(9); 626 } 627 injectConstructorWithQualifier()628 @Test public void injectConstructorWithQualifier() { 629 JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleScopeClass", 630 "package test;", 631 "", 632 "import javax.inject.Inject;", 633 "", 634 "class MultipleScopeClass {", 635 " @Inject", 636 " @QualifierA", 637 " @QualifierB", 638 " MultipleScopeClass() {}", 639 "}"); 640 Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B); 641 assertThat(compilation).failed(); 642 assertThat(compilation) 643 .hadErrorContaining("@Qualifier annotations are not allowed on @Inject constructors") 644 .inFile(file) 645 .onLine(7); 646 assertThat(compilation) 647 .hadErrorContaining("@Qualifier annotations are not allowed on @Inject constructors") 648 .inFile(file) 649 .onLine(8); 650 } 651 injectConstructorWithCheckedExceptionsError()652 @Test public void injectConstructorWithCheckedExceptionsError() { 653 JavaFileObject file = JavaFileObjects.forSourceLines("test.CheckedExceptionClass", 654 "package test;", 655 "", 656 "import javax.inject.Inject;", 657 "", 658 "class CheckedExceptionClass {", 659 " @Inject CheckedExceptionClass() throws Exception {}", 660 "}"); 661 Compilation compilation = daggerCompiler().compile(file); 662 assertThat(compilation).failed(); 663 assertThat(compilation) 664 .hadErrorContaining("Dagger does not support checked exceptions on @Inject constructors") 665 .inFile(file) 666 .onLine(6); 667 } 668 injectConstructorWithCheckedExceptionsWarning()669 @Test public void injectConstructorWithCheckedExceptionsWarning() { 670 JavaFileObject file = JavaFileObjects.forSourceLines("test.CheckedExceptionClass", 671 "package test;", 672 "", 673 "import javax.inject.Inject;", 674 "", 675 "class CheckedExceptionClass {", 676 " @Inject CheckedExceptionClass() throws Exception {}", 677 "}"); 678 Compilation compilation = 679 compilerWithOptions("-Adagger.privateMemberValidation=WARNING").compile(file); 680 assertThat(compilation).succeeded(); 681 assertThat(compilation) 682 .hadWarningContaining("Dagger does not support checked exceptions on @Inject constructors") 683 .inFile(file) 684 .onLine(6); 685 } 686 privateInjectClassError()687 @Test public void privateInjectClassError() { 688 JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass", 689 "package test;", 690 "", 691 "import javax.inject.Inject;", 692 "", 693 "final class OuterClass {", 694 " private static final class InnerClass {", 695 " @Inject InnerClass() {}", 696 " }", 697 "}"); 698 Compilation compilation = daggerCompiler().compile(file); 699 assertThat(compilation).failed(); 700 assertThat(compilation) 701 .hadErrorContaining("Dagger does not support injection into private classes") 702 .inFile(file) 703 .onLine(7); 704 } 705 privateInjectClassWarning()706 @Test public void privateInjectClassWarning() { 707 JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass", 708 "package test;", 709 "", 710 "import javax.inject.Inject;", 711 "", 712 "final class OuterClass {", 713 " private static final class InnerClass {", 714 " @Inject InnerClass() {}", 715 " }", 716 "}"); 717 Compilation compilation = 718 compilerWithOptions("-Adagger.privateMemberValidation=WARNING").compile(file); 719 assertThat(compilation).succeeded(); 720 assertThat(compilation) 721 .hadWarningContaining("Dagger does not support injection into private classes") 722 .inFile(file) 723 .onLine(7); 724 } 725 nestedInPrivateInjectClassError()726 @Test public void nestedInPrivateInjectClassError() { 727 JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass", 728 "package test;", 729 "", 730 "import javax.inject.Inject;", 731 "", 732 "final class OuterClass {", 733 " private static final class MiddleClass {", 734 " static final class InnerClass {", 735 " @Inject InnerClass() {}", 736 " }", 737 " }", 738 "}"); 739 Compilation compilation = daggerCompiler().compile(file); 740 assertThat(compilation).failed(); 741 assertThat(compilation) 742 .hadErrorContaining("Dagger does not support injection into private classes") 743 .inFile(file) 744 .onLine(8); 745 } 746 nestedInPrivateInjectClassWarning()747 @Test public void nestedInPrivateInjectClassWarning() { 748 JavaFileObject file = JavaFileObjects.forSourceLines("test.OuterClass", 749 "package test;", 750 "", 751 "import javax.inject.Inject;", 752 "", 753 "final class OuterClass {", 754 " private static final class MiddleClass {", 755 " static final class InnerClass {", 756 " @Inject InnerClass() {}", 757 " }", 758 " }", 759 "}"); 760 Compilation compilation = 761 compilerWithOptions("-Adagger.privateMemberValidation=WARNING").compile(file); 762 assertThat(compilation).succeeded(); 763 assertThat(compilation) 764 .hadWarningContaining("Dagger does not support injection into private classes") 765 .inFile(file) 766 .onLine(8); 767 } 768 finalInjectField()769 @Test public void finalInjectField() { 770 JavaFileObject file = JavaFileObjects.forSourceLines("test.FinalInjectField", 771 "package test;", 772 "", 773 "import javax.inject.Inject;", 774 "", 775 "class FinalInjectField {", 776 " @Inject final String s;", 777 "}"); 778 Compilation compilation = daggerCompiler().compile(file); 779 assertThat(compilation).failed(); 780 assertThat(compilation) 781 .hadErrorContaining("@Inject fields may not be final") 782 .inFile(file) 783 .onLine(6); 784 } 785 privateInjectFieldError()786 @Test public void privateInjectFieldError() { 787 JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectField", 788 "package test;", 789 "", 790 "import javax.inject.Inject;", 791 "", 792 "class PrivateInjectField {", 793 " @Inject private String s;", 794 "}"); 795 Compilation compilation = daggerCompiler().compile(file); 796 assertThat(compilation).failed(); 797 assertThat(compilation) 798 .hadErrorContaining("Dagger does not support injection into private fields") 799 .inFile(file) 800 .onLine(6); 801 } 802 privateInjectFieldWarning()803 @Test public void privateInjectFieldWarning() { 804 JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectField", 805 "package test;", 806 "", 807 "import javax.inject.Inject;", 808 "", 809 "class PrivateInjectField {", 810 " @Inject private String s;", 811 "}"); 812 Compilation compilation = 813 compilerWithOptions("-Adagger.privateMemberValidation=WARNING").compile(file); 814 assertThat(compilation).succeeded(); // TODO: Verify warning message when supported 815 } 816 staticInjectFieldError()817 @Test public void staticInjectFieldError() { 818 JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectField", 819 "package test;", 820 "", 821 "import javax.inject.Inject;", 822 "", 823 "class StaticInjectField {", 824 " @Inject static String s;", 825 "}"); 826 Compilation compilation = daggerCompiler().compile(file); 827 assertThat(compilation).failed(); 828 assertThat(compilation) 829 .hadErrorContaining("Dagger does not support injection into static fields") 830 .inFile(file) 831 .onLine(6); 832 } 833 staticInjectFieldWarning()834 @Test public void staticInjectFieldWarning() { 835 JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectField", 836 "package test;", 837 "", 838 "import javax.inject.Inject;", 839 "", 840 "class StaticInjectField {", 841 " @Inject static String s;", 842 "}"); 843 Compilation compilation = 844 compilerWithOptions("-Adagger.staticMemberValidation=WARNING").compile(file); 845 assertThat(compilation).succeeded(); // TODO: Verify warning message when supported 846 } 847 multipleQualifiersOnField()848 @Test public void multipleQualifiersOnField() { 849 JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierInjectField", 850 "package test;", 851 "", 852 "import javax.inject.Inject;", 853 "", 854 "class MultipleQualifierInjectField {", 855 " @Inject @QualifierA @QualifierB String s;", 856 "}"); 857 Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B); 858 assertThat(compilation).failed(); 859 assertThat(compilation) 860 .hadErrorContaining("A single dependency request may not use more than one @Qualifier") 861 .inFile(file) 862 .onLine(6) 863 .atColumn(11); 864 assertThat(compilation) 865 .hadErrorContaining("A single dependency request may not use more than one @Qualifier") 866 .inFile(file) 867 .onLine(6) 868 .atColumn(23); 869 } 870 abstractInjectMethod()871 @Test public void abstractInjectMethod() { 872 JavaFileObject file = JavaFileObjects.forSourceLines("test.AbstractInjectMethod", 873 "package test;", 874 "", 875 "import javax.inject.Inject;", 876 "", 877 "abstract class AbstractInjectMethod {", 878 " @Inject abstract void method();", 879 "}"); 880 Compilation compilation = daggerCompiler().compile(file); 881 assertThat(compilation).failed(); 882 assertThat(compilation) 883 .hadErrorContaining("Methods with @Inject may not be abstract") 884 .inFile(file) 885 .onLine(6); 886 } 887 privateInjectMethodError()888 @Test public void privateInjectMethodError() { 889 JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectMethod", 890 "package test;", 891 "", 892 "import javax.inject.Inject;", 893 "", 894 "class PrivateInjectMethod {", 895 " @Inject private void method(){}", 896 "}"); 897 Compilation compilation = daggerCompiler().compile(file); 898 assertThat(compilation).failed(); 899 assertThat(compilation) 900 .hadErrorContaining("Dagger does not support injection into private methods") 901 .inFile(file) 902 .onLine(6); 903 } 904 privateInjectMethodWarning()905 @Test public void privateInjectMethodWarning() { 906 JavaFileObject file = JavaFileObjects.forSourceLines("test.PrivateInjectMethod", 907 "package test;", 908 "", 909 "import javax.inject.Inject;", 910 "", 911 "class PrivateInjectMethod {", 912 " @Inject private void method(){}", 913 "}"); 914 Compilation compilation = 915 compilerWithOptions("-Adagger.privateMemberValidation=WARNING").compile(file); 916 assertThat(compilation).succeeded(); // TODO: Verify warning message when supported 917 } 918 staticInjectMethodError()919 @Test public void staticInjectMethodError() { 920 JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectMethod", 921 "package test;", 922 "", 923 "import javax.inject.Inject;", 924 "", 925 "class StaticInjectMethod {", 926 " @Inject static void method(){}", 927 "}"); 928 Compilation compilation = daggerCompiler().compile(file); 929 assertThat(compilation).failed(); 930 assertThat(compilation) 931 .hadErrorContaining("Dagger does not support injection into static methods") 932 .inFile(file) 933 .onLine(6); 934 } 935 staticInjectMethodWarning()936 @Test public void staticInjectMethodWarning() { 937 JavaFileObject file = JavaFileObjects.forSourceLines("test.StaticInjectMethod", 938 "package test;", 939 "", 940 "import javax.inject.Inject;", 941 "", 942 "class StaticInjectMethod {", 943 " @Inject static void method(){}", 944 "}"); 945 Compilation compilation = 946 compilerWithOptions("-Adagger.staticMemberValidation=WARNING").compile(file); 947 assertThat(compilation).succeeded(); // TODO: Verify warning message when supported 948 } 949 genericInjectMethod()950 @Test public void genericInjectMethod() { 951 JavaFileObject file = JavaFileObjects.forSourceLines("test.GenericInjectMethod", 952 "package test;", 953 "", 954 "import javax.inject.Inject;", 955 "", 956 "class AbstractInjectMethod {", 957 " @Inject <T> void method();", 958 "}"); 959 Compilation compilation = daggerCompiler().compile(file); 960 assertThat(compilation).failed(); 961 assertThat(compilation) 962 .hadErrorContaining("Methods with @Inject may not declare type parameters") 963 .inFile(file) 964 .onLine(6); 965 } 966 multipleQualifiersOnInjectMethodParameter()967 @Test public void multipleQualifiersOnInjectMethodParameter() { 968 JavaFileObject file = JavaFileObjects.forSourceLines("test.MultipleQualifierMethodParam", 969 "package test;", 970 "", 971 "import javax.inject.Inject;", 972 "", 973 "class MultipleQualifierMethodParam {", 974 " @Inject void method(@QualifierA @QualifierB String s) {}", 975 "}"); 976 Compilation compilation = daggerCompiler().compile(file, QUALIFIER_A, QUALIFIER_B); 977 assertThat(compilation).failed(); 978 assertThat(compilation) 979 .hadErrorContaining("A single dependency request may not use more than one @Qualifier") 980 .inFile(file) 981 .onLine(6); 982 } 983 injectConstructorDependsOnProduced()984 @Test public void injectConstructorDependsOnProduced() { 985 JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A", 986 "package test;", 987 "", 988 "import dagger.producers.Produced;", 989 "import javax.inject.Inject;", 990 "", 991 "final class A {", 992 " @Inject A(Produced<String> str) {}", 993 "}"); 994 Compilation compilation = daggerCompiler().compile(aFile); 995 assertThat(compilation).failed(); 996 assertThat(compilation) 997 .hadErrorContaining("Produced may only be injected in @Produces methods"); 998 } 999 injectConstructorDependsOnProducer()1000 @Test public void injectConstructorDependsOnProducer() { 1001 JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A", 1002 "package test;", 1003 "", 1004 "import dagger.producers.Producer;", 1005 "import javax.inject.Inject;", 1006 "", 1007 "final class A {", 1008 " @Inject A(Producer<String> str) {}", 1009 "}"); 1010 Compilation compilation = daggerCompiler().compile(aFile); 1011 assertThat(compilation).failed(); 1012 assertThat(compilation) 1013 .hadErrorContaining("Producer may only be injected in @Produces methods"); 1014 } 1015 injectFieldDependsOnProduced()1016 @Test public void injectFieldDependsOnProduced() { 1017 JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A", 1018 "package test;", 1019 "", 1020 "import dagger.producers.Produced;", 1021 "import javax.inject.Inject;", 1022 "", 1023 "final class A {", 1024 " @Inject Produced<String> str;", 1025 "}"); 1026 Compilation compilation = daggerCompiler().compile(aFile); 1027 assertThat(compilation).failed(); 1028 assertThat(compilation) 1029 .hadErrorContaining("Produced may only be injected in @Produces methods"); 1030 } 1031 injectFieldDependsOnProducer()1032 @Test public void injectFieldDependsOnProducer() { 1033 JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A", 1034 "package test;", 1035 "", 1036 "import dagger.producers.Producer;", 1037 "import javax.inject.Inject;", 1038 "", 1039 "final class A {", 1040 " @Inject Producer<String> str;", 1041 "}"); 1042 Compilation compilation = daggerCompiler().compile(aFile); 1043 assertThat(compilation).failed(); 1044 assertThat(compilation) 1045 .hadErrorContaining("Producer may only be injected in @Produces methods"); 1046 } 1047 injectMethodDependsOnProduced()1048 @Test public void injectMethodDependsOnProduced() { 1049 JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A", 1050 "package test;", 1051 "", 1052 "import dagger.producers.Produced;", 1053 "import javax.inject.Inject;", 1054 "", 1055 "final class A {", 1056 " @Inject void inject(Produced<String> str) {}", 1057 "}"); 1058 Compilation compilation = daggerCompiler().compile(aFile); 1059 assertThat(compilation).failed(); 1060 assertThat(compilation) 1061 .hadErrorContaining("Produced may only be injected in @Produces methods"); 1062 } 1063 injectMethodDependsOnProducer()1064 @Test public void injectMethodDependsOnProducer() { 1065 JavaFileObject aFile = JavaFileObjects.forSourceLines("test.A", 1066 "package test;", 1067 "", 1068 "import dagger.producers.Producer;", 1069 "import javax.inject.Inject;", 1070 "", 1071 "final class A {", 1072 " @Inject void inject(Producer<String> str) {}", 1073 "}"); 1074 Compilation compilation = daggerCompiler().compile(aFile); 1075 assertThat(compilation).failed(); 1076 assertThat(compilation) 1077 .hadErrorContaining("Producer may only be injected in @Produces methods"); 1078 } 1079 1080 injectConstructor()1081 @Test public void injectConstructor() { 1082 JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor", 1083 "package test;", 1084 "", 1085 "import javax.inject.Inject;", 1086 "", 1087 "class InjectConstructor {", 1088 " @Inject InjectConstructor(String s) {}", 1089 "}"); 1090 JavaFileObject expected = 1091 JavaFileObjects.forSourceLines( 1092 "test.InjectConstructor_Factory", 1093 "package test;", 1094 "", 1095 GeneratedLines.generatedImports( 1096 "import dagger.internal.Factory;", 1097 "import dagger.internal.QualifierMetadata;", 1098 "import dagger.internal.ScopeMetadata;", 1099 "import javax.inject.Provider;"), 1100 "", 1101 "@ScopeMetadata", 1102 "@QualifierMetadata", 1103 GeneratedLines.generatedAnnotations(), 1104 "public final class InjectConstructor_Factory ", 1105 " implements Factory<InjectConstructor> {", 1106 "", 1107 " private final Provider<String> sProvider;", 1108 "", 1109 " public InjectConstructor_Factory(Provider<String> sProvider) {", 1110 " this.sProvider = sProvider;", 1111 " }", 1112 "", 1113 " @Override public InjectConstructor get() {", 1114 " return newInstance(sProvider.get());", 1115 " }", 1116 "", 1117 " public static InjectConstructor_Factory create(Provider<String> sProvider) {", 1118 " return new InjectConstructor_Factory(sProvider);", 1119 " }", 1120 "", 1121 " public static InjectConstructor newInstance(String s) {", 1122 " return new InjectConstructor(s);", 1123 " }", 1124 "}"); 1125 assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor()) 1126 .compilesWithoutError() 1127 .and().generatesSources(expected); 1128 } 1129 injectConstructorAndMembersInjection()1130 @Test public void injectConstructorAndMembersInjection() { 1131 JavaFileObject file = JavaFileObjects.forSourceLines("test.AllInjections", 1132 "package test;", 1133 "", 1134 "import javax.inject.Inject;", 1135 "", 1136 "class AllInjections {", 1137 " @Inject String s;", 1138 " @Inject AllInjections(String s) {}", 1139 " @Inject void s(String s) {}", 1140 "}"); 1141 JavaFileObject expectedFactory = 1142 JavaFileObjects.forSourceLines( 1143 "test.AllInjections_Factory", 1144 "package test;", 1145 "", 1146 GeneratedLines.generatedImports( 1147 "import dagger.internal.Factory;", 1148 "import dagger.internal.QualifierMetadata;", 1149 "import dagger.internal.ScopeMetadata;", 1150 "import javax.inject.Provider;"), 1151 "", 1152 "@ScopeMetadata", 1153 "@QualifierMetadata", 1154 GeneratedLines.generatedAnnotations(), 1155 "public final class AllInjections_Factory implements Factory<AllInjections> {", 1156 " private final Provider<String> sProvider;", 1157 " private final Provider<String> sProvider2;", 1158 " private final Provider<String> sProvider3;", 1159 "", 1160 " public AllInjections_Factory(", 1161 " Provider<String> sProvider,", 1162 " Provider<String> sProvider2,", 1163 " Provider<String> sProvider3) {", 1164 " this.sProvider = sProvider;", 1165 " this.sProvider2 = sProvider2;", 1166 " this.sProvider3 = sProvider3;", 1167 " }", 1168 "", 1169 " @Override", 1170 " public AllInjections get() {", 1171 " AllInjections instance = newInstance(sProvider.get());", 1172 " AllInjections_MembersInjector.injectS(instance, sProvider2.get());", 1173 " AllInjections_MembersInjector.injectS2(instance, sProvider3.get());", 1174 " return instance;", 1175 " }", 1176 "", 1177 " public static AllInjections_Factory create(", 1178 " Provider<String> sProvider,", 1179 " Provider<String> sProvider2,", 1180 " Provider<String> sProvider3) {", 1181 " return new AllInjections_Factory(sProvider, sProvider2, sProvider3);", 1182 " }", 1183 "", 1184 " public static AllInjections newInstance(String s) {", 1185 " return new AllInjections(s);", 1186 " }", 1187 "}"); 1188 assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor()) 1189 .compilesWithoutError() 1190 .and() 1191 .generatesSources(expectedFactory); 1192 } 1193 1194 @Test wildcardDependency()1195 public void wildcardDependency() { 1196 JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor", 1197 "package test;", 1198 "", 1199 "import java.util.List;", 1200 "import javax.inject.Inject;", 1201 "", 1202 "class InjectConstructor {", 1203 " @Inject InjectConstructor(List<?> objects) {}", 1204 "}"); 1205 JavaFileObject expected = 1206 JavaFileObjects.forSourceLines( 1207 "test.InjectConstructor_Factory", 1208 "package test;", 1209 "", 1210 GeneratedLines.generatedImports( 1211 "import dagger.internal.Factory;", 1212 "import dagger.internal.QualifierMetadata;", 1213 "import dagger.internal.ScopeMetadata;", 1214 "import java.util.List;", 1215 "import javax.inject.Provider;"), 1216 "", 1217 "@ScopeMetadata", 1218 "@QualifierMetadata", 1219 GeneratedLines.generatedAnnotations(), 1220 "public final class InjectConstructor_Factory ", 1221 " implements Factory<InjectConstructor> {", 1222 "", 1223 " private final Provider<List<?>> objectsProvider;", 1224 "", 1225 " public InjectConstructor_Factory(Provider<List<?>> objectsProvider) {", 1226 " this.objectsProvider = objectsProvider;", 1227 " }", 1228 "", 1229 " @Override public InjectConstructor get() {", 1230 " return newInstance(objectsProvider.get());", 1231 " }", 1232 "", 1233 " public static InjectConstructor_Factory create(", 1234 " Provider<List<?>> objectsProvider) {", 1235 " return new InjectConstructor_Factory(objectsProvider);", 1236 " }", 1237 "", 1238 " public static InjectConstructor newInstance(List<?> objects) {", 1239 " return new InjectConstructor(objects);", 1240 " }", 1241 "}"); 1242 assertAbout(javaSource()).that(file).processedWith(new ComponentProcessor()) 1243 .compilesWithoutError() 1244 .and().generatesSources(expected); 1245 } 1246 1247 @Test basicNameCollision()1248 public void basicNameCollision() { 1249 JavaFileObject factoryFile = JavaFileObjects.forSourceLines("other.pkg.Factory", 1250 "package other.pkg;", 1251 "", 1252 "public class Factory {}"); 1253 JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor", 1254 "package test;", 1255 "", 1256 "import javax.inject.Inject;", 1257 "import other.pkg.Factory;", 1258 "", 1259 "class InjectConstructor {", 1260 " @Inject InjectConstructor(Factory factory) {}", 1261 "}"); 1262 JavaFileObject expected = 1263 JavaFileObjects.forSourceLines( 1264 "test.InjectConstructor_Factory", 1265 "package test;", 1266 "", 1267 GeneratedLines.generatedImports( 1268 "import dagger.internal.Factory;", 1269 "import dagger.internal.QualifierMetadata;", 1270 "import dagger.internal.ScopeMetadata;", 1271 "import javax.inject.Provider;"), 1272 "", 1273 "@ScopeMetadata", 1274 "@QualifierMetadata", 1275 GeneratedLines.generatedAnnotations(), 1276 "public final class InjectConstructor_Factory ", 1277 " implements Factory<InjectConstructor> {", 1278 "", 1279 " private final Provider<other.pkg.Factory> factoryProvider;", 1280 "", 1281 " public InjectConstructor_Factory(Provider<other.pkg.Factory> factoryProvider) {", 1282 " this.factoryProvider = factoryProvider;", 1283 " }", 1284 "", 1285 " @Override public InjectConstructor get() {", 1286 " return newInstance(factoryProvider.get());", 1287 " }", 1288 "", 1289 " public static InjectConstructor_Factory create(", 1290 " Provider<other.pkg.Factory> factoryProvider) {", 1291 " return new InjectConstructor_Factory(factoryProvider);", 1292 " }", 1293 "", 1294 " public static InjectConstructor newInstance(", 1295 " other.pkg.Factory factory) {", 1296 " return new InjectConstructor(factory);", 1297 " }", 1298 "}"); 1299 assertAbout(javaSources()).that(ImmutableList.of(factoryFile, file)) 1300 .processedWith(new ComponentProcessor()) 1301 .compilesWithoutError() 1302 .and().generatesSources(expected); 1303 } 1304 1305 @Test nestedNameCollision()1306 public void nestedNameCollision() { 1307 JavaFileObject factoryFile = JavaFileObjects.forSourceLines("other.pkg.Outer", 1308 "package other.pkg;", 1309 "", 1310 "public class Outer {", 1311 " public class Factory {}", 1312 "}"); 1313 JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor", 1314 "package test;", 1315 "", 1316 "import javax.inject.Inject;", 1317 "import other.pkg.Outer;", 1318 "", 1319 "class InjectConstructor {", 1320 " @Inject InjectConstructor(Outer.Factory factory) {}", 1321 "}"); 1322 JavaFileObject expected = 1323 JavaFileObjects.forSourceLines( 1324 "test.InjectConstructor_Factory", 1325 "package test;", 1326 "", 1327 GeneratedLines.generatedImports( 1328 "import dagger.internal.Factory;", 1329 "import dagger.internal.QualifierMetadata;", 1330 "import dagger.internal.ScopeMetadata;", 1331 "import javax.inject.Provider;", 1332 "import other.pkg.Outer;"), 1333 "", 1334 "@ScopeMetadata", 1335 "@QualifierMetadata", 1336 GeneratedLines.generatedAnnotations(), 1337 "public final class InjectConstructor_Factory ", 1338 " implements Factory<InjectConstructor> {", 1339 "", 1340 " private final Provider<Outer.Factory> factoryProvider;", 1341 "", 1342 " public InjectConstructor_Factory(Provider<Outer.Factory> factoryProvider) {", 1343 " this.factoryProvider = factoryProvider;", 1344 " }", 1345 "", 1346 " @Override public InjectConstructor get() {", 1347 " return newInstance(factoryProvider.get());", 1348 " }", 1349 "", 1350 " public static InjectConstructor_Factory create(", 1351 " Provider<Outer.Factory> factoryProvider) {", 1352 " return new InjectConstructor_Factory(factoryProvider);", 1353 " }", 1354 "", 1355 " public static InjectConstructor newInstance(", 1356 " Outer.Factory factory) {", 1357 " return new InjectConstructor(factory);", 1358 " }", 1359 "}"); 1360 assertAbout(javaSources()).that(ImmutableList.of(factoryFile, file)) 1361 .processedWith(new ComponentProcessor()) 1362 .compilesWithoutError() 1363 .and().generatesSources(expected); 1364 } 1365 1366 @Test samePackageNameCollision()1367 public void samePackageNameCollision() { 1368 JavaFileObject samePackageInterface = JavaFileObjects.forSourceLines("test.CommonName", 1369 "package test;", 1370 "", 1371 "public interface CommonName {}"); 1372 JavaFileObject differentPackageInterface = JavaFileObjects.forSourceLines( 1373 "other.pkg.CommonName", 1374 "package other.pkg;", 1375 "", 1376 "public interface CommonName {}"); 1377 JavaFileObject file = JavaFileObjects.forSourceLines("test.InjectConstructor", 1378 "package test;", 1379 "", 1380 "import javax.inject.Inject;", 1381 "", 1382 "class InjectConstructor implements CommonName {", 1383 " @Inject InjectConstructor(other.pkg.CommonName otherPackage, CommonName samePackage) {}", 1384 "}"); 1385 JavaFileObject expected = 1386 JavaFileObjects.forSourceLines( 1387 "test.InjectConstructor_Factory", 1388 "package test;", 1389 "", 1390 GeneratedLines.generatedImports( 1391 "import dagger.internal.Factory;", 1392 "import dagger.internal.QualifierMetadata;", 1393 "import dagger.internal.ScopeMetadata;", 1394 "import javax.inject.Provider;"), 1395 "", 1396 "@ScopeMetadata", 1397 "@QualifierMetadata", 1398 GeneratedLines.generatedAnnotations(), 1399 "public final class InjectConstructor_Factory ", 1400 " implements Factory<InjectConstructor> {", 1401 "", 1402 " private final Provider<other.pkg.CommonName> otherPackageProvider;", 1403 " private final Provider<CommonName> samePackageProvider;", 1404 "", 1405 " public InjectConstructor_Factory(", 1406 " Provider<other.pkg.CommonName> otherPackageProvider,", 1407 " Provider<CommonName> samePackageProvider) {", 1408 " this.otherPackageProvider = otherPackageProvider;", 1409 " this.samePackageProvider = samePackageProvider;", 1410 " }", 1411 "", 1412 " @Override public InjectConstructor get() {", 1413 " return newInstance(otherPackageProvider.get(), samePackageProvider.get());", 1414 " }", 1415 "", 1416 " public static InjectConstructor_Factory create(", 1417 " Provider<other.pkg.CommonName> otherPackageProvider,", 1418 " Provider<CommonName> samePackageProvider) {", 1419 " return new InjectConstructor_Factory(otherPackageProvider, samePackageProvider);", 1420 " }", 1421 "", 1422 " public static InjectConstructor newInstance(", 1423 " other.pkg.CommonName otherPackage, CommonName samePackage) {", 1424 " return new InjectConstructor(otherPackage, samePackage);", 1425 " }", 1426 "}"); 1427 assertAbout(javaSources()) 1428 .that(ImmutableList.of(samePackageInterface, differentPackageInterface, file)) 1429 .processedWith(new ComponentProcessor()) 1430 .compilesWithoutError() 1431 .and().generatesSources(expected); 1432 } 1433 1434 @Test noDeps()1435 public void noDeps() { 1436 JavaFileObject simpleType = JavaFileObjects.forSourceLines("test.SimpleType", 1437 "package test;", 1438 "", 1439 "import javax.inject.Inject;", 1440 "", 1441 "final class SimpleType {", 1442 " @Inject SimpleType() {}", 1443 "}"); 1444 JavaFileObject factory = 1445 JavaFileObjects.forSourceLines( 1446 "test.SimpleType_Factory", 1447 "package test;", 1448 "", 1449 GeneratedLines.generatedImports( 1450 "import dagger.internal.Factory;", 1451 "import dagger.internal.QualifierMetadata;", 1452 "import dagger.internal.ScopeMetadata;"), 1453 "", 1454 "@ScopeMetadata", 1455 "@QualifierMetadata", 1456 GeneratedLines.generatedAnnotations(), 1457 "public final class SimpleType_Factory implements Factory<SimpleType> {", 1458 " @Override public SimpleType get() {", 1459 " return newInstance();", 1460 " }", 1461 "", 1462 " public static SimpleType_Factory create() {", 1463 " return InstanceHolder.INSTANCE;", 1464 " }", 1465 "", 1466 " public static SimpleType newInstance() {", 1467 " return new SimpleType();", 1468 " }", 1469 "", 1470 " private static final class InstanceHolder {", 1471 " private static final SimpleType_Factory INSTANCE = new SimpleType_Factory();", 1472 " }", 1473 "}"); 1474 assertAbout(javaSource()) 1475 .that(simpleType) 1476 .processedWith(new ComponentProcessor()) 1477 .compilesWithoutError() 1478 .and().generatesSources(factory); 1479 } 1480 simpleComponentWithNesting()1481 @Test public void simpleComponentWithNesting() { 1482 JavaFileObject nestedTypesFile = JavaFileObjects.forSourceLines("test.OuterType", 1483 "package test;", 1484 "", 1485 "import dagger.Component;", 1486 "import javax.inject.Inject;", 1487 "", 1488 "final class OuterType {", 1489 " static class A {", 1490 " @Inject A() {}", 1491 " }", 1492 " static class B {", 1493 " @Inject A a;", 1494 " }", 1495 "}"); 1496 JavaFileObject aFactory = 1497 JavaFileObjects.forSourceLines( 1498 "test.OuterType_A_Factory", 1499 "package test;", 1500 "", 1501 GeneratedLines.generatedImports( 1502 "import dagger.internal.Factory;", 1503 "import dagger.internal.QualifierMetadata;", 1504 "import dagger.internal.ScopeMetadata;"), 1505 "", 1506 "@ScopeMetadata", 1507 "@QualifierMetadata", 1508 GeneratedLines.generatedAnnotations(), 1509 "public final class OuterType_A_Factory implements Factory<OuterType.A> {", 1510 " @Override public OuterType.A get() {", 1511 " return newInstance();", 1512 " }", 1513 "", 1514 " public static OuterType_A_Factory create() {", 1515 " return InstanceHolder.INSTANCE;", 1516 " }", 1517 "", 1518 " public static OuterType.A newInstance() {", 1519 " return new OuterType.A();", 1520 " }", 1521 "", 1522 " private static final class InstanceHolder {", 1523 " private static final OuterType_A_Factory INSTANCE = new OuterType_A_Factory();", 1524 " }", 1525 "}"); 1526 assertAbout(javaSources()).that(ImmutableList.of(nestedTypesFile)) 1527 .processedWith(new ComponentProcessor()) 1528 .compilesWithoutError() 1529 .and().generatesSources(aFactory); 1530 } 1531 1532 @Test testScopedMetadata()1533 public void testScopedMetadata() { 1534 JavaFileObject scopedBinding = 1535 JavaFileObjects.forSourceLines( 1536 "test.ScopedBinding", 1537 "package test;", 1538 "", 1539 "import javax.inject.Inject;", 1540 "import javax.inject.Singleton;", 1541 "", 1542 "@Singleton", 1543 "class ScopedBinding {", 1544 " @Inject", 1545 " ScopedBinding() {}", 1546 "}"); 1547 Compilation compilation = daggerCompiler().compile(scopedBinding); 1548 assertThat(compilation).succeeded(); 1549 assertThat(compilation) 1550 .generatedSourceFile("test.ScopedBinding_Factory") 1551 .containsElementsIn( 1552 JavaFileObjects.forSourceLines( 1553 "test.ScopedBinding_Factory", 1554 "package test;", 1555 "", 1556 "@ScopeMetadata(\"javax.inject.Singleton\")", 1557 "@QualifierMetadata", 1558 GeneratedLines.generatedAnnotations(), 1559 "public final class ScopedBinding_Factory implements Factory<ScopedBinding> {}")); 1560 } 1561 1562 @Test testScopedMetadataWithCustomScope()1563 public void testScopedMetadataWithCustomScope() { 1564 JavaFileObject customScope = 1565 JavaFileObjects.forSourceLines( 1566 "test.CustomScope", 1567 "package test;", 1568 "", 1569 "import javax.inject.Scope;", 1570 "", 1571 "@Scope", 1572 "@interface CustomScope {", 1573 " String value();", 1574 "}"); 1575 1576 JavaFileObject customAnnotation = 1577 JavaFileObjects.forSourceLines( 1578 "test.CustomAnnotation", 1579 "package test;", 1580 "", 1581 "@interface CustomAnnotation {", 1582 " String value();", 1583 "}"); 1584 1585 JavaFileObject scopedBinding = 1586 JavaFileObjects.forSourceLines( 1587 "test.ScopedBinding", 1588 "package test;", 1589 "", 1590 "import javax.inject.Inject;", 1591 "import javax.inject.Singleton;", 1592 "", 1593 "@CustomAnnotation(\"someValue\")", 1594 "@CustomScope(\"someOtherValue\")", 1595 "class ScopedBinding {", 1596 " @Inject", 1597 " ScopedBinding() {}", 1598 "}"); 1599 Compilation compilation = 1600 daggerCompiler().compile(scopedBinding, customScope, customAnnotation); 1601 assertThat(compilation).succeeded(); 1602 assertThat(compilation) 1603 .generatedSourceFile("test.ScopedBinding_Factory") 1604 .containsElementsIn( 1605 JavaFileObjects.forSourceLines( 1606 "test.ScopedBinding_Factory", 1607 "package test;", 1608 "", 1609 "@ScopeMetadata(\"test.CustomScope\")", 1610 "@QualifierMetadata", 1611 GeneratedLines.generatedAnnotations(), 1612 "public final class ScopedBinding_Factory implements Factory<ScopedBinding> {}")); 1613 } 1614 1615 @Test testQualifierMetadata()1616 public void testQualifierMetadata() { 1617 JavaFileObject someBinding = 1618 JavaFileObjects.forSourceLines( 1619 "test.SomeBinding", 1620 "package test;", 1621 "", 1622 "import javax.inject.Inject;", 1623 "import javax.inject.Singleton;", 1624 "", 1625 "@NonQualifier", 1626 "@MisplacedQualifier", 1627 "class SomeBinding {", 1628 " @NonQualifier @FieldQualifier @Inject String injectField;", 1629 " @NonQualifier @MisplacedQualifier String nonDaggerField;", 1630 "", 1631 " @NonQualifier", 1632 " @Inject", 1633 " SomeBinding(@NonQualifier @ConstructorParameterQualifier Double d) {}", 1634 "", 1635 " @NonQualifier", 1636 " @MisplacedQualifier", 1637 " SomeBinding(@NonQualifier @MisplacedQualifier Double d, int i) {}", 1638 "", 1639 " @NonQualifier", 1640 " @MisplacedQualifier", 1641 " @Inject", 1642 " void injectMethod(@NonQualifier @MethodParameterQualifier Float f) {}", 1643 "", 1644 " @NonQualifier", 1645 " @MisplacedQualifier", 1646 " void nonDaggerMethod(@NonQualifier @MisplacedQualifier Float f) {}", 1647 "}"); 1648 JavaFileObject fieldQualifier = 1649 JavaFileObjects.forSourceLines( 1650 "test.FieldQualifier", 1651 "package test;", 1652 "", 1653 "import javax.inject.Qualifier;", 1654 "", 1655 "@Qualifier", 1656 "@interface FieldQualifier {}"); 1657 JavaFileObject constructorParameterQualifier = 1658 JavaFileObjects.forSourceLines( 1659 "test.ConstructorParameterQualifier", 1660 "package test;", 1661 "", 1662 "import javax.inject.Qualifier;", 1663 "", 1664 "@Qualifier", 1665 "@interface ConstructorParameterQualifier {}"); 1666 JavaFileObject methodParameterQualifier = 1667 JavaFileObjects.forSourceLines( 1668 "test.MethodParameterQualifier", 1669 "package test;", 1670 "", 1671 "import javax.inject.Qualifier;", 1672 "", 1673 "@Qualifier", 1674 "@interface MethodParameterQualifier {}"); 1675 JavaFileObject misplacedQualifier = 1676 JavaFileObjects.forSourceLines( 1677 "test.MisplacedQualifier", 1678 "package test;", 1679 "", 1680 "import javax.inject.Qualifier;", 1681 "", 1682 "@Qualifier", 1683 "@interface MisplacedQualifier {}"); 1684 JavaFileObject nonQualifier = 1685 JavaFileObjects.forSourceLines( 1686 "test.NonQualifier", 1687 "package test;", 1688 "", 1689 "@interface NonQualifier {}"); 1690 Compilation compilation = 1691 daggerCompiler().compile( 1692 someBinding, 1693 fieldQualifier, 1694 constructorParameterQualifier, 1695 methodParameterQualifier, 1696 misplacedQualifier, 1697 nonQualifier); 1698 assertThat(compilation).succeeded(); 1699 assertThat(compilation) 1700 .generatedSourceFile("test.SomeBinding_Factory") 1701 .containsElementsIn( 1702 JavaFileObjects.forSourceLines( 1703 "test.SomeBinding_Factory", 1704 "package test;", 1705 "", 1706 // Verifies that the @QualifierMetadata for the generated Factory does not contain 1707 // @MisplacedQualifier, @NonQualifier, @MethodParameterQualifier or @FieldQualifier. 1708 "@ScopeMetadata", 1709 "@QualifierMetadata(\"test.ConstructorParameterQualifier\")", 1710 GeneratedLines.generatedAnnotations(), 1711 "public final class SomeBinding_Factory implements Factory<SomeBinding> {}")); 1712 assertThat(compilation) 1713 .generatedSourceFile("test.SomeBinding_MembersInjector") 1714 .containsElementsIn( 1715 JavaFileObjects.forSourceLines( 1716 "test.SomeBinding_MembersInjector", 1717 "package test;", 1718 "", 1719 // Verifies that the @QualifierMetadata for the generated MembersInjector does not 1720 // contain @MisplacedQualifier, @NonQualifier, or @ConstructorParameterQualifier. 1721 "@QualifierMetadata({", 1722 " \"test.FieldQualifier\",", 1723 " \"test.MethodParameterQualifier\"", 1724 "})", 1725 GeneratedLines.generatedAnnotations(), 1726 "public final class SomeBinding_MembersInjector", 1727 " implements MembersInjector<SomeBinding> {}")); 1728 } 1729 1730 @Test testComplexQualifierMetadata()1731 public void testComplexQualifierMetadata() { 1732 JavaFileObject someBinding = 1733 JavaFileObjects.forSourceLines( 1734 "test.SomeBinding", 1735 "package test;", 1736 "", 1737 "import javax.inject.Inject;", 1738 "import javax.inject.Inject;", 1739 "", 1740 "class SomeBinding {", 1741 " @QualifierWithValue(1) @Inject String injectField;", 1742 "", 1743 " @Inject", 1744 " SomeBinding(", 1745 " @pkg1.SameNameQualifier String str1,", 1746 " @pkg2.SameNameQualifier String str2) {}", 1747 "", 1748 " @Inject", 1749 " void injectMethod(@test.Outer.NestedQualifier Float f) {}", 1750 "}"); 1751 JavaFileObject qualifierWithValue = 1752 JavaFileObjects.forSourceLines( 1753 "test.QualifierWithValue", 1754 "package test;", 1755 "", 1756 "import javax.inject.Qualifier;", 1757 "", 1758 "@Qualifier", 1759 "@interface QualifierWithValue {", 1760 " int value();", 1761 "}"); 1762 JavaFileObject pkg1SameNameQualifier = 1763 JavaFileObjects.forSourceLines( 1764 "pkg1.SameNameQualifier", 1765 "package pkg1;", 1766 "", 1767 "import javax.inject.Qualifier;", 1768 "", 1769 "@Qualifier", 1770 "public @interface SameNameQualifier {}"); 1771 JavaFileObject pkg2SameNameQualifier = 1772 JavaFileObjects.forSourceLines( 1773 "pkg2.SameNameQualifier", 1774 "package pkg2;", 1775 "", 1776 "import javax.inject.Qualifier;", 1777 "", 1778 "@Qualifier", 1779 "public @interface SameNameQualifier {}"); 1780 JavaFileObject nestedQualifier = 1781 JavaFileObjects.forSourceLines( 1782 "test.Outer", 1783 "package test;", 1784 "", 1785 "import javax.inject.Qualifier;", 1786 "", 1787 "interface Outer {", 1788 " @Qualifier", 1789 " @interface NestedQualifier {}", 1790 "}"); 1791 Compilation compilation = 1792 daggerCompiler().compile( 1793 someBinding, 1794 qualifierWithValue, 1795 pkg1SameNameQualifier, 1796 pkg2SameNameQualifier, 1797 nestedQualifier); 1798 assertThat(compilation).succeeded(); 1799 assertThat(compilation) 1800 .generatedSourceFile("test.SomeBinding_Factory") 1801 .containsElementsIn( 1802 JavaFileObjects.forSourceLines( 1803 "test.SomeBinding_Factory", 1804 "package test;", 1805 "", 1806 "@ScopeMetadata", 1807 "@QualifierMetadata({\"pkg1.SameNameQualifier\", \"pkg2.SameNameQualifier\"})", 1808 GeneratedLines.generatedAnnotations(), 1809 "public final class SomeBinding_Factory implements Factory<SomeBinding> {}")); 1810 assertThat(compilation) 1811 .generatedSourceFile("test.SomeBinding_MembersInjector") 1812 .containsElementsIn( 1813 JavaFileObjects.forSourceLines( 1814 "test.SomeBinding_MembersInjector", 1815 "package test;", 1816 "", 1817 "@QualifierMetadata({", 1818 " \"test.QualifierWithValue\",", 1819 " \"test.Outer.NestedQualifier\"", 1820 "})", 1821 GeneratedLines.generatedAnnotations(), 1822 "public final class SomeBinding_MembersInjector", 1823 " implements MembersInjector<SomeBinding> {}")); 1824 } 1825 1826 @Test testBaseClassQualifierMetadata()1827 public void testBaseClassQualifierMetadata() { 1828 JavaFileObject foo = 1829 JavaFileObjects.forSourceLines( 1830 "test.Foo", 1831 "package test;", 1832 "", 1833 "import javax.inject.Inject;", 1834 "import javax.inject.Singleton;", 1835 "", 1836 "class Foo extends FooBase {", 1837 " @FooFieldQualifier @Inject String injectField;", 1838 "", 1839 " @Inject", 1840 " Foo(@FooConstructorQualifier int i) { super(i); }", 1841 "", 1842 " @Inject", 1843 " void injectMethod(@FooMethodQualifier float f) {}", 1844 "}"); 1845 JavaFileObject fooFieldQualifier = 1846 JavaFileObjects.forSourceLines( 1847 "test.FooFieldQualifier", 1848 "package test;", 1849 "", 1850 "import javax.inject.Qualifier;", 1851 "", 1852 "@Qualifier", 1853 "@interface FooFieldQualifier {}"); 1854 JavaFileObject fooConstructorQualifier = 1855 JavaFileObjects.forSourceLines( 1856 "test.FooConstructorQualifier", 1857 "package test;", 1858 "", 1859 "import javax.inject.Qualifier;", 1860 "", 1861 "@Qualifier", 1862 "@interface FooConstructorQualifier {}"); 1863 JavaFileObject fooMethodQualifier = 1864 JavaFileObjects.forSourceLines( 1865 "test.FooMethodQualifier", 1866 "package test;", 1867 "", 1868 "import javax.inject.Qualifier;", 1869 "", 1870 "@Qualifier", 1871 "@interface FooMethodQualifier {}"); 1872 JavaFileObject fooBase = 1873 JavaFileObjects.forSourceLines( 1874 "test.FooBase", 1875 "package test;", 1876 "", 1877 "import javax.inject.Inject;", 1878 "import javax.inject.Singleton;", 1879 "", 1880 "class FooBase {", 1881 " @FooBaseFieldQualifier @Inject String injectField;", 1882 "", 1883 " @Inject", 1884 " FooBase(@FooBaseConstructorQualifier int i) {}", 1885 "", 1886 " @Inject", 1887 " void injectMethod(@FooBaseMethodQualifier float f) {}", 1888 "}"); 1889 JavaFileObject fooBaseFieldQualifier = 1890 JavaFileObjects.forSourceLines( 1891 "test.FooBaseFieldQualifier", 1892 "package test;", 1893 "", 1894 "import javax.inject.Qualifier;", 1895 "", 1896 "@Qualifier", 1897 "@interface FooBaseFieldQualifier {}"); 1898 JavaFileObject fooBaseConstructorQualifier = 1899 JavaFileObjects.forSourceLines( 1900 "test.FooBaseConstructorQualifier", 1901 "package test;", 1902 "", 1903 "import javax.inject.Qualifier;", 1904 "", 1905 "@Qualifier", 1906 "@interface FooBaseConstructorQualifier {}"); 1907 JavaFileObject fooBaseMethodQualifier = 1908 JavaFileObjects.forSourceLines( 1909 "test.FooBaseMethodQualifier", 1910 "package test;", 1911 "", 1912 "import javax.inject.Qualifier;", 1913 "", 1914 "@Qualifier", 1915 "@interface FooBaseMethodQualifier {}"); 1916 Compilation compilation = 1917 daggerCompiler().compile( 1918 foo, 1919 fooBase, 1920 fooFieldQualifier, 1921 fooConstructorQualifier, 1922 fooMethodQualifier, 1923 fooBaseFieldQualifier, 1924 fooBaseConstructorQualifier, 1925 fooBaseMethodQualifier); 1926 assertThat(compilation).succeeded(); 1927 assertThat(compilation) 1928 .generatedSourceFile("test.Foo_Factory") 1929 .containsElementsIn( 1930 JavaFileObjects.forSourceLines( 1931 "test.Foo_Factory", 1932 "package test;", 1933 "", 1934 "@ScopeMetadata", 1935 // Verifies that Foo_Factory only contains Foo's qualifiers and not FooBase's too. 1936 "@QualifierMetadata(\"test.FooConstructorQualifier\")", 1937 GeneratedLines.generatedAnnotations(), 1938 "public final class Foo_Factory implements Factory<Foo> {}")); 1939 assertThat(compilation) 1940 .generatedSourceFile("test.Foo_MembersInjector") 1941 .containsElementsIn( 1942 JavaFileObjects.forSourceLines( 1943 "test.Foo_MembersInjector", 1944 "package test;", 1945 "", 1946 // Verifies that Foo_Factory only contains Foo's qualifiers and not FooBase's too. 1947 "@QualifierMetadata({", 1948 " \"test.FooFieldQualifier\",", 1949 " \"test.FooMethodQualifier\"", 1950 "})", 1951 GeneratedLines.generatedAnnotations(), 1952 "public final class Foo_MembersInjector implements MembersInjector<Foo> {}")); 1953 assertThat(compilation) 1954 .generatedSourceFile("test.FooBase_Factory") 1955 .containsElementsIn( 1956 JavaFileObjects.forSourceLines( 1957 "test.Foo_Factory", 1958 "package test;", 1959 "", 1960 "@ScopeMetadata", 1961 "@QualifierMetadata(\"test.FooBaseConstructorQualifier\")", 1962 GeneratedLines.generatedAnnotations(), 1963 "public final class FooBase_Factory implements Factory<FooBase> {}")); 1964 assertThat(compilation) 1965 .generatedSourceFile("test.FooBase_MembersInjector") 1966 .containsElementsIn( 1967 JavaFileObjects.forSourceLines( 1968 "test.FooBase_MembersInjector", 1969 "package test;", 1970 "", 1971 "@QualifierMetadata({", 1972 " \"test.FooBaseFieldQualifier\",", 1973 " \"test.FooBaseMethodQualifier\"", 1974 "})", 1975 GeneratedLines.generatedAnnotations(), 1976 "public final class FooBase_MembersInjector", 1977 " implements MembersInjector<FooBase> {}")); 1978 } 1979 } 1980