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.JavaSourcesSubjectFactory.javaSources;
     27 
     28 @RunWith(JUnit4.class)
     29 public class MissingBindingSuggestionsTest {
     30   private static JavaFileObject injectable(String className, String constructorParams) {
     31     return JavaFileObjects.forSourceLines("test." + className,
     32         "package test;",
     33         "",
     34         "import javax.inject.Inject;",
     35         "",
     36         "class " + className +" {",
     37         "  @Inject " + className + "(" + constructorParams + ") {}",
     38         "}");
     39   }
     40 
     41   private static JavaFileObject emptyInterface(String interfaceName) {
     42     return JavaFileObjects.forSourceLines("test." + interfaceName,
     43         "package test;",
     44         "",
     45         "import javax.inject.Inject;",
     46         "",
     47         "interface " + interfaceName +" {}");
     48   }
     49 
     50   @Test public void suggestsBindingInSeparateComponent() {
     51     JavaFileObject fooComponent = JavaFileObjects.forSourceLines("test.FooComponent",
     52         "package test;",
     53         "",
     54         "import dagger.Subcomponent;",
     55         "",
     56         "@Subcomponent",
     57         "interface FooComponent {",
     58         "  Foo getFoo();",
     59         "}");
     60     JavaFileObject barModule = JavaFileObjects.forSourceLines("test.BarModule",
     61         "package test;",
     62         "",
     63         "import dagger.Provides;",
     64         "import javax.inject.Inject;",
     65         "",
     66         "@dagger.Module",
     67         "final class BarModule {",
     68         "  @Provides Bar provideBar() {return null;}",
     69         "}");
     70     JavaFileObject barComponent = JavaFileObjects.forSourceLines("test.BarComponent",
     71         "package test;",
     72         "",
     73         "import dagger.Subcomponent;",
     74         "",
     75         "@Subcomponent(modules = {BarModule.class})",
     76         "interface BarComponent {",
     77         "  Bar getBar();",
     78         "}");
     79     JavaFileObject foo = injectable("Foo", "Bar bar");
     80     JavaFileObject bar = emptyInterface("Bar");
     81 
     82     JavaFileObject topComponent = JavaFileObjects.forSourceLines("test.TopComponent",
     83         "package test;",
     84         "",
     85         "import dagger.Component;",
     86         "",
     87         "@Component",
     88         "interface TopComponent {",
     89         "  FooComponent getFoo();",
     90         "  BarComponent getBar(BarModule barModule);",
     91         "}");
     92 
     93     assertAbout(javaSources())
     94         .that(ImmutableList.of(
     95             fooComponent, barComponent, topComponent, foo, bar, barModule))
     96         .processedWith(new ComponentProcessor())
     97         .failsToCompile()
     98         .withErrorContaining("A binding with matching key exists in component: test.BarComponent");
     99   }
    100 
    101   @Test public void suggestsBindingInNestedSubcomponent() {
    102     JavaFileObject fooComponent = JavaFileObjects.forSourceLines("test.FooComponent",
    103         "package test;",
    104         "",
    105         "import dagger.Subcomponent;",
    106         "",
    107         "@Subcomponent",
    108         "interface FooComponent {",
    109         "  Foo getFoo();",
    110         "}");
    111     JavaFileObject barComponent = JavaFileObjects.forSourceLines("test.BarComponent",
    112         "package test;",
    113         "",
    114         "import dagger.Subcomponent;",
    115         "",
    116         "@Subcomponent()",
    117         "interface BarComponent {",
    118         "  BazComponent getBaz();",
    119         "}");
    120     JavaFileObject bazModule = JavaFileObjects.forSourceLines("test.BazModule",
    121         "package test;",
    122         "",
    123         "import dagger.Provides;",
    124         "import javax.inject.Inject;",
    125         "",
    126         "@dagger.Module",
    127         "final class BazModule {",
    128         "  @Provides Baz provideBaz() {return null;}",
    129         "}");
    130     JavaFileObject bazComponent = JavaFileObjects.forSourceLines("test.BazComponent",
    131         "package test;",
    132         "",
    133         "import dagger.Subcomponent;",
    134         "",
    135         "@Subcomponent(modules = {BazModule.class})",
    136         "interface BazComponent {",
    137         "  Baz getBaz();",
    138         "}");
    139     JavaFileObject foo = injectable("Foo", "Baz baz");
    140     JavaFileObject baz = emptyInterface("Baz");
    141 
    142     JavaFileObject topComponent = JavaFileObjects.forSourceLines("test.TopComponent",
    143         "package test;",
    144         "",
    145         "import dagger.Component;",
    146         "",
    147         "@Component",
    148         "interface TopComponent {",
    149         "  FooComponent getFoo();",
    150         "  BarComponent getBar();",
    151         "}");
    152 
    153     assertAbout(javaSources())
    154         .that(ImmutableList.of(
    155             fooComponent, barComponent, bazComponent, topComponent, foo, baz, bazModule))
    156         .processedWith(new ComponentProcessor())
    157         .failsToCompile()
    158         .withErrorContaining("A binding with matching key exists in component: test.BazComponent");
    159   }
    160 }
    161