Home | History | Annotate | Download | only in codegen
      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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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