1 /* 2 * Copyright (C) 2015 Google, Inc. 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 package dagger.internal.codegen; 17 18 import com.google.common.collect.ImmutableList; 19 import com.google.testing.compile.JavaFileObjects; 20 import javax.tools.JavaFileObject; 21 import org.junit.Test; 22 import org.junit.runner.RunWith; 23 import org.junit.runners.JUnit4; 24 25 import static com.google.common.truth.Truth.assertAbout; 26 import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; 27 import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; 28 29 /** Tests for {@link dagger.Subcomponent.Builder} validation. */ 30 @RunWith(JUnit4.class) 31 public class SubcomponentBuilderValidationTest { 32 33 private static final ErrorMessages.SubcomponentBuilderMessages MSGS = 34 new ErrorMessages.SubcomponentBuilderMessages(); 35 36 @Test testRefSubcomponentAndSubBuilderFails()37 public void testRefSubcomponentAndSubBuilderFails() { 38 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent", 39 "package test;", 40 "", 41 "import dagger.Component;", 42 "", 43 "import javax.inject.Provider;", 44 "", 45 "@Component", 46 "interface ParentComponent {", 47 " ChildComponent child();", 48 " ChildComponent.Builder builder();", 49 "}"); 50 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 51 "package test;", 52 "", 53 "import dagger.Subcomponent;", 54 "", 55 "@Subcomponent", 56 "interface ChildComponent {", 57 " @Subcomponent.Builder", 58 " static interface Builder {", 59 " ChildComponent build();", 60 " }", 61 "}"); 62 assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile)) 63 .processedWith(new ComponentProcessor()) 64 .failsToCompile() 65 .withErrorContaining(String.format(MSGS.moreThanOneRefToSubcomponent(), 66 "test.ChildComponent", "[child(), builder()]")) 67 .in(componentFile); 68 } 69 70 @Test testRefSubBuilderTwiceFails()71 public void testRefSubBuilderTwiceFails() { 72 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent", 73 "package test;", 74 "", 75 "import dagger.Component;", 76 "", 77 "import javax.inject.Provider;", 78 "", 79 "@Component", 80 "interface ParentComponent {", 81 " ChildComponent.Builder builder1();", 82 " ChildComponent.Builder builder2();", 83 "}"); 84 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 85 "package test;", 86 "", 87 "import dagger.Subcomponent;", 88 "", 89 "@Subcomponent", 90 "interface ChildComponent {", 91 " @Subcomponent.Builder", 92 " static interface Builder {", 93 " ChildComponent build();", 94 " }", 95 "}"); 96 assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile)) 97 .processedWith(new ComponentProcessor()) 98 .failsToCompile() 99 .withErrorContaining(String.format(MSGS.moreThanOneRefToSubcomponent(), 100 "test.ChildComponent", "[builder1(), builder2()]")) 101 .in(componentFile); 102 } 103 104 @Test testMoreThanOneBuilderFails()105 public void testMoreThanOneBuilderFails() { 106 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent", 107 "package test;", 108 "", 109 "import dagger.Component;", 110 "", 111 "import javax.inject.Provider;", 112 "", 113 "@Component", 114 "interface ParentComponent {", 115 " ChildComponent.Builder1 build();", 116 "}"); 117 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 118 "package test;", 119 "", 120 "import dagger.Subcomponent;", 121 "", 122 "@Subcomponent", 123 "interface ChildComponent {", 124 " @Subcomponent.Builder", 125 " static interface Builder1 {", 126 " ChildComponent build();", 127 " }", 128 "", 129 " @Subcomponent.Builder", 130 " static interface Builder2 {", 131 " ChildComponent build();", 132 " }", 133 "}"); 134 assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile)) 135 .processedWith(new ComponentProcessor()) 136 .failsToCompile() 137 .withErrorContaining(String.format(MSGS.moreThanOne(), 138 "[test.ChildComponent.Builder1, test.ChildComponent.Builder2]")) 139 .in(childComponentFile); 140 } 141 142 @Test testBuilderGenericsFails()143 public void testBuilderGenericsFails() { 144 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent", 145 "package test;", 146 "", 147 "import dagger.Component;", 148 "", 149 "import javax.inject.Provider;", 150 "", 151 "@Component", 152 "interface ParentComponent {", 153 " ChildComponent.Builder1 build();", 154 "}"); 155 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 156 "package test;", 157 "", 158 "import dagger.Subcomponent;", 159 "", 160 "@Subcomponent", 161 "interface ChildComponent {", 162 " @Subcomponent.Builder", 163 " interface Builder<T> {", 164 " ChildComponent build();", 165 " }", 166 "}"); 167 assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile)) 168 .processedWith(new ComponentProcessor()) 169 .failsToCompile() 170 .withErrorContaining(MSGS.generics()) 171 .in(childComponentFile); 172 } 173 174 @Test testBuilderNotInComponentFails()175 public void testBuilderNotInComponentFails() { 176 JavaFileObject builder = JavaFileObjects.forSourceLines("test.Builder", 177 "package test;", 178 "", 179 "import dagger.Subcomponent;", 180 "", 181 "@Subcomponent.Builder", 182 "interface Builder {}"); 183 assertAbout(javaSource()).that(builder) 184 .processedWith(new ComponentProcessor()) 185 .failsToCompile() 186 .withErrorContaining(MSGS.mustBeInComponent()) 187 .in(builder); 188 } 189 190 @Test testBuilderMissingBuildMethodFails()191 public void testBuilderMissingBuildMethodFails() { 192 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent", 193 "package test;", 194 "", 195 "import dagger.Component;", 196 "", 197 "import javax.inject.Provider;", 198 "", 199 "@Component", 200 "interface ParentComponent {", 201 " ChildComponent.Builder1 build();", 202 "}"); 203 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 204 "package test;", 205 "", 206 "import dagger.Subcomponent;", 207 "", 208 "@Subcomponent", 209 "interface ChildComponent {", 210 " @Subcomponent.Builder", 211 " interface Builder {}", 212 "}"); 213 assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile)) 214 .processedWith(new ComponentProcessor()) 215 .failsToCompile() 216 .withErrorContaining(MSGS.missingBuildMethod()) 217 .in(childComponentFile); 218 } 219 220 @Test testPrivateBuilderFails()221 public void testPrivateBuilderFails() { 222 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 223 "package test;", 224 "", 225 "import dagger.Subcomponent;", 226 "", 227 "@Subcomponent", 228 "abstract class ChildComponent {", 229 " @Subcomponent.Builder", 230 " private interface Builder {}", 231 "}"); 232 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 233 .processedWith(new ComponentProcessor()) 234 .failsToCompile() 235 .withErrorContaining(MSGS.isPrivate()) 236 .in(childComponentFile); 237 } 238 239 @Test testNonStaticBuilderFails()240 public void testNonStaticBuilderFails() { 241 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 242 "package test;", 243 "", 244 "import dagger.Subcomponent;", 245 "", 246 "@Subcomponent", 247 "abstract class ChildComponent {", 248 " @Subcomponent.Builder", 249 " abstract class Builder {}", 250 "}"); 251 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 252 .processedWith(new ComponentProcessor()) 253 .failsToCompile() 254 .withErrorContaining(MSGS.mustBeStatic()) 255 .in(childComponentFile); 256 } 257 258 @Test testNonAbstractBuilderFails()259 public void testNonAbstractBuilderFails() { 260 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 261 "package test;", 262 "", 263 "import dagger.Subcomponent;", 264 "", 265 "@Subcomponent", 266 "abstract class ChildComponent {", 267 " @Subcomponent.Builder", 268 " static class Builder {}", 269 "}"); 270 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 271 .processedWith(new ComponentProcessor()) 272 .failsToCompile() 273 .withErrorContaining(MSGS.mustBeAbstract()) 274 .in(childComponentFile); 275 } 276 277 @Test testBuilderOneCxtorWithArgsFails()278 public void testBuilderOneCxtorWithArgsFails() { 279 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 280 "package test;", 281 "", 282 "import dagger.Subcomponent;", 283 "", 284 "@Subcomponent", 285 "abstract class ChildComponent {", 286 " @Subcomponent.Builder", 287 " static abstract class Builder {", 288 " Builder(String unused) {}", 289 " }", 290 "}"); 291 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 292 .processedWith(new ComponentProcessor()) 293 .failsToCompile() 294 .withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs()) 295 .in(childComponentFile); 296 } 297 298 @Test testBuilderMoreThanOneCxtorFails()299 public void testBuilderMoreThanOneCxtorFails() { 300 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 301 "package test;", 302 "", 303 "import dagger.Subcomponent;", 304 "", 305 "@Subcomponent", 306 "abstract class ChildComponent {", 307 " @Subcomponent.Builder", 308 " static abstract class Builder {", 309 " Builder() {}", 310 " Builder(String unused) {}", 311 " }", 312 "}"); 313 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 314 .processedWith(new ComponentProcessor()) 315 .failsToCompile() 316 .withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs()) 317 .in(childComponentFile); 318 } 319 320 @Test testBuilderEnumFails()321 public void testBuilderEnumFails() { 322 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 323 "package test;", 324 "", 325 "import dagger.Subcomponent;", 326 "", 327 "@Subcomponent", 328 "abstract class ChildComponent {", 329 " @Subcomponent.Builder", 330 " enum Builder {}", 331 "}"); 332 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 333 .processedWith(new ComponentProcessor()) 334 .failsToCompile() 335 .withErrorContaining(MSGS.mustBeClassOrInterface()) 336 .in(childComponentFile); 337 } 338 339 @Test testBuilderBuildReturnsWrongTypeFails()340 public void testBuilderBuildReturnsWrongTypeFails() { 341 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 342 "package test;", 343 "", 344 "import dagger.Subcomponent;", 345 "", 346 "@Subcomponent", 347 "abstract class ChildComponent {", 348 " @Subcomponent.Builder", 349 " interface Builder {", 350 " String build();", 351 " }", 352 "}"); 353 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 354 .processedWith(new ComponentProcessor()) 355 .failsToCompile() 356 .withErrorContaining(MSGS.buildMustReturnComponentType()) 357 .in(childComponentFile).onLine(9); 358 } 359 360 @Test testInheritedBuilderBuildReturnsWrongTypeFails()361 public void testInheritedBuilderBuildReturnsWrongTypeFails() { 362 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 363 "package test;", 364 "", 365 "import dagger.Subcomponent;", 366 "", 367 "@Subcomponent", 368 "abstract class ChildComponent {", 369 " interface Parent {", 370 " String build();", 371 " }", 372 "", 373 " @Subcomponent.Builder", 374 " interface Builder extends Parent {}", 375 "}"); 376 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 377 .processedWith(new ComponentProcessor()) 378 .failsToCompile() 379 .withErrorContaining( 380 String.format(MSGS.inheritedBuildMustReturnComponentType(), "build")) 381 .in(childComponentFile).onLine(12); 382 } 383 384 @Test testTwoBuildMethodsFails()385 public void testTwoBuildMethodsFails() { 386 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 387 "package test;", 388 "", 389 "import dagger.Subcomponent;", 390 "", 391 "@Subcomponent", 392 "abstract class ChildComponent {", 393 " @Subcomponent.Builder", 394 " interface Builder {", 395 " ChildComponent build();", 396 " ChildComponent create();", 397 " }", 398 "}"); 399 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 400 .processedWith(new ComponentProcessor()) 401 .failsToCompile() 402 .withErrorContaining(String.format(MSGS.twoBuildMethods(), "build()")) 403 .in(childComponentFile).onLine(10); 404 } 405 406 @Test testInheritedTwoBuildMethodsFails()407 public void testInheritedTwoBuildMethodsFails() { 408 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 409 "package test;", 410 "", 411 "import dagger.Subcomponent;", 412 "", 413 "@Subcomponent", 414 "abstract class ChildComponent {", 415 " interface Parent {", 416 " ChildComponent build();", 417 " ChildComponent create();", 418 " }", 419 "", 420 " @Subcomponent.Builder", 421 " interface Builder extends Parent {}", 422 "}"); 423 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 424 .processedWith(new ComponentProcessor()) 425 .failsToCompile() 426 .withErrorContaining( 427 String.format(MSGS.inheritedTwoBuildMethods(), "create()", "build()")) 428 .in(childComponentFile).onLine(13); 429 } 430 431 @Test testMoreThanOneArgFails()432 public void testMoreThanOneArgFails() { 433 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 434 "package test;", 435 "", 436 "import dagger.Subcomponent;", 437 "", 438 "@Subcomponent", 439 "abstract class ChildComponent {", 440 " @Subcomponent.Builder", 441 " interface Builder {", 442 " ChildComponent build();", 443 " Builder set(String s, Integer i);", 444 " Builder set(Number n, Double d);", 445 " }", 446 "}"); 447 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 448 .processedWith(new ComponentProcessor()) 449 .failsToCompile() 450 .withErrorContaining(MSGS.methodsMustTakeOneArg()) 451 .in(childComponentFile).onLine(10) 452 .and().withErrorContaining(MSGS.methodsMustTakeOneArg()) 453 .in(childComponentFile).onLine(11); 454 } 455 456 @Test testInheritedMoreThanOneArgFails()457 public void testInheritedMoreThanOneArgFails() { 458 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 459 "package test;", 460 "", 461 "import dagger.Subcomponent;", 462 "", 463 "@Subcomponent", 464 "abstract class ChildComponent {", 465 " interface Parent {", 466 " ChildComponent build();", 467 " Builder set1(String s, Integer i);", 468 " }", 469 "", 470 " @Subcomponent.Builder", 471 " interface Builder extends Parent {}", 472 "}"); 473 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 474 .processedWith(new ComponentProcessor()) 475 .failsToCompile() 476 .withErrorContaining( 477 String.format(MSGS.inheritedMethodsMustTakeOneArg(), 478 "set1(java.lang.String,java.lang.Integer)")) 479 .in(childComponentFile).onLine(13); 480 } 481 482 @Test testSetterReturningNonVoidOrBuilderFails()483 public void testSetterReturningNonVoidOrBuilderFails() { 484 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 485 "package test;", 486 "", 487 "import dagger.Subcomponent;", 488 "", 489 "@Subcomponent", 490 "abstract class ChildComponent {", 491 " @Subcomponent.Builder", 492 " interface Builder {", 493 " ChildComponent build();", 494 " String set(Integer i);", 495 " }", 496 "}"); 497 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 498 .processedWith(new ComponentProcessor()) 499 .failsToCompile() 500 .withErrorContaining(MSGS.methodsMustReturnVoidOrBuilder()) 501 .in(childComponentFile).onLine(10); 502 } 503 504 @Test testInheritedSetterReturningNonVoidOrBuilderFails()505 public void testInheritedSetterReturningNonVoidOrBuilderFails() { 506 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 507 "package test;", 508 "", 509 "import dagger.Subcomponent;", 510 "", 511 "@Subcomponent", 512 "abstract class ChildComponent {", 513 " interface Parent {", 514 " ChildComponent build();", 515 " String set(Integer i);", 516 " }", 517 "", 518 " @Subcomponent.Builder", 519 " interface Builder extends Parent {}", 520 "}"); 521 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 522 .processedWith(new ComponentProcessor()) 523 .failsToCompile() 524 .withErrorContaining( 525 String.format(MSGS.inheritedMethodsMustReturnVoidOrBuilder(), 526 "set(java.lang.Integer)")) 527 .in(childComponentFile).onLine(13); 528 } 529 530 @Test testGenericsOnSetterMethodFails()531 public void testGenericsOnSetterMethodFails() { 532 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 533 "package test;", 534 "", 535 "import dagger.Subcomponent;", 536 "", 537 "@Subcomponent", 538 "abstract class ChildComponent {", 539 " @Subcomponent.Builder", 540 " interface Builder {", 541 " ChildComponent build();", 542 " <T> Builder set(T t);", 543 " }", 544 "}"); 545 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 546 .processedWith(new ComponentProcessor()) 547 .failsToCompile() 548 .withErrorContaining(MSGS.methodsMayNotHaveTypeParameters()) 549 .in(childComponentFile).onLine(10); 550 } 551 552 @Test testGenericsOnInheritedSetterMethodFails()553 public void testGenericsOnInheritedSetterMethodFails() { 554 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 555 "package test;", 556 "", 557 "import dagger.Subcomponent;", 558 "", 559 "@Subcomponent", 560 "abstract class ChildComponent {", 561 " interface Parent {", 562 " ChildComponent build();", 563 " <T> Builder set(T t);", 564 " }", 565 "", 566 " @Subcomponent.Builder", 567 " interface Builder extends Parent {}", 568 "}"); 569 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 570 .processedWith(new ComponentProcessor()) 571 .failsToCompile() 572 .withErrorContaining( 573 String.format(MSGS.inheritedMethodsMayNotHaveTypeParameters(), "<T>set(T)")) 574 .in(childComponentFile).onLine(13); 575 } 576 577 @Test testMultipleSettersPerTypeFails()578 public void testMultipleSettersPerTypeFails() { 579 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 580 "package test;", 581 "", 582 "import dagger.Subcomponent;", 583 "", 584 "@Subcomponent", 585 "abstract class ChildComponent {", 586 " @Subcomponent.Builder", 587 " interface Builder {", 588 " ChildComponent build();", 589 " void set1(String s);", 590 " void set2(String s);", 591 " }", 592 "}"); 593 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 594 .processedWith(new ComponentProcessor()) 595 .failsToCompile() 596 .withErrorContaining( 597 String.format(MSGS.manyMethodsForType(), 598 "java.lang.String", "[set1(java.lang.String), set2(java.lang.String)]")) 599 .in(childComponentFile).onLine(8); 600 } 601 602 @Test testMultipleSettersPerTypeIncludingResolvedGenericsFails()603 public void testMultipleSettersPerTypeIncludingResolvedGenericsFails() { 604 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 605 "package test;", 606 "", 607 "import dagger.Subcomponent;", 608 "", 609 "@Subcomponent", 610 "abstract class ChildComponent {", 611 " interface Parent<T> {", 612 " void set1(T t);", 613 " }", 614 "", 615 " @Subcomponent.Builder", 616 " interface Builder extends Parent<String> {", 617 " ChildComponent build();", 618 " void set2(String s);", 619 " }", 620 "}"); 621 assertAbout(javaSources()).that(ImmutableList.of(childComponentFile)) 622 .processedWith(new ComponentProcessor()) 623 .failsToCompile() 624 .withErrorContaining( 625 String.format(MSGS.manyMethodsForType(), 626 "java.lang.String", "[set1(T), set2(java.lang.String)]")) 627 .in(childComponentFile).onLine(12); 628 } 629 630 @Test testExtraSettersFails()631 public void testExtraSettersFails() { 632 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent", 633 "package test;", 634 "", 635 "import dagger.Component;", 636 "", 637 "import javax.inject.Provider;", 638 "", 639 "@Component", 640 "interface ParentComponent {", 641 " ChildComponent.Builder build();", 642 "}"); 643 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 644 "package test;", 645 "", 646 "import dagger.Subcomponent;", 647 "", 648 "@Subcomponent", 649 "interface ChildComponent {", 650 " @Subcomponent.Builder", 651 " interface Builder {", 652 " ChildComponent build();", 653 " void set1(String s);", 654 " void set2(Integer s);", 655 " }", 656 "}"); 657 assertAbout(javaSources()).that(ImmutableList.of(componentFile, childComponentFile)) 658 .processedWith(new ComponentProcessor()) 659 .failsToCompile() 660 .withErrorContaining( 661 String.format(MSGS.extraSetters(), 662 "[void test.ChildComponent.Builder.set1(String)," 663 + " void test.ChildComponent.Builder.set2(Integer)]")) 664 .in(childComponentFile).onLine(8); 665 666 } 667 668 @Test testMissingSettersFail()669 public void testMissingSettersFail() { 670 JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule", 671 "package test;", 672 "", 673 "import dagger.Module;", 674 "import dagger.Provides;", 675 "", 676 "@Module", 677 "final class TestModule {", 678 " TestModule(String unused) {}", 679 " @Provides String s() { return null; }", 680 "}"); 681 JavaFileObject module2File = JavaFileObjects.forSourceLines("test.Test2Module", 682 "package test;", 683 "", 684 "import dagger.Module;", 685 "import dagger.Provides;", 686 "", 687 "@Module", 688 "final class Test2Module {", 689 " @Provides Integer i() { return null; }", 690 "}"); 691 JavaFileObject module3File = JavaFileObjects.forSourceLines("test.Test3Module", 692 "package test;", 693 "", 694 "import dagger.Module;", 695 "import dagger.Provides;", 696 "", 697 "@Module", 698 "final class Test3Module {", 699 " Test3Module(String unused) {}", 700 " @Provides Double d() { return null; }", 701 "}"); 702 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.ParentComponent", 703 "package test;", 704 "", 705 "import dagger.Component;", 706 "", 707 "import javax.inject.Provider;", 708 "", 709 "@Component", 710 "interface ParentComponent {", 711 " ChildComponent.Builder build();", 712 "}"); 713 JavaFileObject childComponentFile = JavaFileObjects.forSourceLines("test.ChildComponent", 714 "package test;", 715 "", 716 "import dagger.Subcomponent;", 717 "", 718 "@Subcomponent(modules = {TestModule.class, Test2Module.class, Test3Module.class})", 719 "interface ChildComponent {", 720 " String string();", 721 " Integer integer();", 722 "", 723 " @Subcomponent.Builder", 724 " interface Builder {", 725 " ChildComponent create();", 726 " }", 727 "}"); 728 assertAbout(javaSources()) 729 .that(ImmutableList.of(moduleFile, 730 module2File, 731 module3File, 732 componentFile, 733 childComponentFile)) 734 .processedWith(new ComponentProcessor()) 735 .failsToCompile() 736 .withErrorContaining( 737 // Ignores Test2Module because we can construct it ourselves. 738 // TODO(sameb): Ignore Test3Module because it's not used within transitive dependencies. 739 String.format(MSGS.missingSetters(), "[test.TestModule, test.Test3Module]")) 740 .in(childComponentFile).onLine(11); 741 } 742 } 743