1 /*
2  * Copyright (C) 2015 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.testing.compile.CompilationSubject.assertThat;
20 import static dagger.internal.codegen.Compilers.compilerWithOptions;
21 import static dagger.internal.codegen.GeneratedLines.GENERATED_CODE_ANNOTATIONS;
22 import static dagger.internal.codegen.binding.ComponentCreatorAnnotation.COMPONENT_FACTORY;
23 import static dagger.internal.codegen.binding.ErrorMessages.creatorMessagesFor;
24 
25 import com.google.testing.compile.Compilation;
26 import com.google.testing.compile.JavaFileObjects;
27 import dagger.internal.codegen.binding.ErrorMessages;
28 import java.util.Collection;
29 import javax.tools.JavaFileObject;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.junit.runners.Parameterized;
33 import org.junit.runners.Parameterized.Parameters;
34 
35 /** Tests for {@link dagger.Component.Factory} */
36 @RunWith(Parameterized.class)
37 public class ComponentFactoryTest {
38   @Parameters(name = "{0}")
parameters()39   public static Collection<Object[]> parameters() {
40     return CompilerMode.TEST_PARAMETERS;
41   }
42 
43   private final CompilerMode compilerMode;
44 
ComponentFactoryTest(CompilerMode compilerMode)45   public ComponentFactoryTest(CompilerMode compilerMode) {
46     this.compilerMode = compilerMode;
47   }
48 
49   private static final ErrorMessages.ComponentCreatorMessages MSGS =
50       creatorMessagesFor(COMPONENT_FACTORY);
51 
52   @Test
testUsesParameterNames()53   public void testUsesParameterNames() {
54     JavaFileObject moduleFile =
55         JavaFileObjects.forSourceLines(
56             "test.TestModule",
57             "package test;",
58             "",
59             "import dagger.Module;",
60             "import dagger.Provides;",
61             "",
62             "@Module",
63             "final class TestModule {",
64             "  @Provides String string() { return null; }",
65             "}");
66 
67     JavaFileObject componentFile =
68         JavaFileObjects.forSourceLines(
69             "test.TestComponent",
70             "package test;",
71             "",
72             "import dagger.Component;",
73             "",
74             "@Component(modules = TestModule.class)",
75             "interface TestComponent {",
76             "  String string();",
77             "",
78             "  @Component.Factory",
79             "  interface Factory {",
80             "    TestComponent newTestComponent(TestModule mod);",
81             "  }",
82             "}");
83     JavaFileObject generatedComponent =
84         JavaFileObjects.forSourceLines(
85             "test.DaggerTestComponent",
86             "package test;",
87             "",
88             "import dagger.internal.Preconditions;",
89             "",
90             GENERATED_CODE_ANNOTATIONS,
91             "final class DaggerTestComponent implements TestComponent {",
92             "  private static final class Factory implements TestComponent.Factory {",
93             "    @Override",
94             "    public TestComponent newTestComponent(TestModule mod) {",
95             "      Preconditions.checkNotNull(mod);",
96             "      return new DaggerTestComponent(mod);",
97             "    }",
98             "  }",
99             "}");
100     Compilation compilation =
101         compilerWithOptions(compilerMode.javacopts()).compile(moduleFile, componentFile);
102     assertThat(compilation).succeeded();
103     assertThat(compilation)
104         .generatedSourceFile("test.DaggerTestComponent")
105         .containsElementsIn(generatedComponent);
106   }
107 
108   @Test
testSetterMethodFails()109   public void testSetterMethodFails() {
110     JavaFileObject componentFile =
111         JavaFileObjects.forSourceLines(
112             "test.SimpleComponent",
113             "package test;",
114             "",
115             "import dagger.Component;",
116             "import javax.inject.Provider;",
117             "",
118             "@Component",
119             "abstract class SimpleComponent {",
120             "  @Component.Factory",
121             "  interface Factory {",
122             "    SimpleComponent create();",
123             "    Factory set(String s);",
124             "  }",
125             "}");
126     Compilation compilation =
127         compilerWithOptions(compilerMode.javacopts()).compile(componentFile);
128     assertThat(compilation).failed();
129     assertThat(compilation)
130         .hadErrorContaining(String.format(MSGS.twoFactoryMethods(), "create()"))
131         .inFile(componentFile)
132         .onLineContaining("Factory set(String s);");
133   }
134 
135   @Test
testInheritedSetterMethodFails()136   public void testInheritedSetterMethodFails() {
137     JavaFileObject componentFile =
138         JavaFileObjects.forSourceLines(
139             "test.SimpleComponent",
140             "package test;",
141             "",
142             "import dagger.Component;",
143             "import javax.inject.Provider;",
144             "",
145             "@Component",
146             "abstract class SimpleComponent {",
147             "  interface Parent {",
148             "    SimpleComponent create();",
149             "    Parent set(String s);",
150             "  }",
151             "",
152             "  @Component.Factory",
153             "  interface Factory extends Parent {}",
154             "}");
155     Compilation compilation =
156         compilerWithOptions(compilerMode.javacopts()).compile(componentFile);
157     assertThat(compilation).failed();
158     assertThat(compilation)
159         .hadErrorContaining(String.format(MSGS.twoFactoryMethods(), "create()"))
160         .inFile(componentFile)
161         .onLineContaining("interface Factory");
162   }
163 }
164