• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.assertThat;
20 import static com.google.testing.compile.CompilationSubject.assertThat;
21 import static dagger.internal.codegen.Compilers.compilerWithOptions;
22 import static dagger.internal.codegen.Compilers.daggerCompiler;
23 import static java.util.stream.Collectors.joining;
24 
25 import com.google.testing.compile.Compilation;
26 import com.google.testing.compile.JavaFileObjects;
27 import javax.tools.JavaFileObject;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.junit.runners.JUnit4;
31 
32 @RunWith(JUnit4.class)
33 public final class UnresolvableDependencyTest {
34 
35   @Test
referencesUnresolvableDependency()36   public void referencesUnresolvableDependency() {
37     JavaFileObject fooComponent =
38         JavaFileObjects.forSourceLines(
39             "test.FooComponent",
40             "package test;",
41             "",
42             "import dagger.Component;",
43             "",
44             "@Component",
45             "interface FooComponent {",
46             "  Foo foo();",
47             "}");
48 
49     JavaFileObject foo =
50         JavaFileObjects.forSourceLines(
51             "test.Foo",
52             "package test;",
53             "",
54             "import javax.inject.Inject;",
55             "",
56             "class Foo {",
57             "  @Inject",
58             "  Foo(Bar bar) {}",
59             "}");
60 
61     JavaFileObject bar =
62         JavaFileObjects.forSourceLines(
63             "test.Bar",
64             "package test;",
65             "",
66             "import javax.inject.Inject;",
67             "",
68             "class Bar {",
69             "  @Inject",
70             "  Bar(UnresolvableDependency dep) {}",
71             "}");
72 
73     Compilation compilation = daggerCompiler().compile(fooComponent, foo, bar);
74     assertThat(compilation).failed();
75     assertThat(compilation).hadErrorCount(3);
76     assertThat(compilation).hadErrorContaining(
77         "cannot find symbol"
78             + "\n  symbol:   class UnresolvableDependency"
79             + "\n  location: class test.Bar");
80     String trace = "\n  "
81         + "\n  Dependency trace:"
82         + "\n      => element (CLASS): test.Bar"
83         + "\n      => element (CONSTRUCTOR): Bar(UnresolvableDependency)"
84         + "\n      => type (EXECUTABLE constructor): (UnresolvableDependency)void"
85         + "\n      => type (ERROR parameter type): UnresolvableDependency";
86     assertThat(compilation).hadErrorContaining(
87         "InjectProcessingStep was unable to process 'Bar(UnresolvableDependency)' because "
88             + "'UnresolvableDependency' could not be resolved." + trace);
89     assertThat(compilation).hadErrorContaining(
90         "ComponentProcessingStep was unable to process 'test.FooComponent' because "
91             + "'UnresolvableDependency' could not be resolved." + trace);
92 
93     // Only include a minimal portion of the stacktrace to minimize breaking tests due to refactors.
94     String stacktraceErrorMessage =
95         "dagger.internal.codegen.base"
96             + ".DaggerSuperficialValidation$ValidationException$KnownErrorType";
97 
98     // Check that the stacktrace is not included in the error message by default.
99     assertThat(
100             compilation.errors().stream()
101                 .map(error -> error.getMessage(null))
102                 .collect(joining("\n")))
103         .doesNotContain(stacktraceErrorMessage);
104 
105     // Recompile with the option enabled and check that the stacktrace is now included
106     compilation =
107         compilerWithOptions("-Adagger.includeStacktraceWithDeferredErrorMessages=ENABLED")
108             .compile(fooComponent, foo, bar);
109     assertThat(compilation).failed();
110     assertThat(compilation).hadErrorCount(3);
111     assertThat(compilation).hadErrorContaining(stacktraceErrorMessage);
112   }
113 
114   @Test
referencesUnresolvableAnnotationOnType()115   public void referencesUnresolvableAnnotationOnType() {
116     JavaFileObject fooComponent =
117         JavaFileObjects.forSourceLines(
118             "test.FooComponent",
119             "package test;",
120             "",
121             "import dagger.Component;",
122             "",
123             "@Component",
124             "interface FooComponent {",
125             "  Foo foo();",
126             "}");
127 
128     JavaFileObject foo =
129         JavaFileObjects.forSourceLines(
130             "test.Foo",
131             "package test;",
132             "",
133             "import javax.inject.Inject;",
134             "",
135             "class Foo {",
136             "  @Inject",
137             "  Foo(Bar bar) {}",
138             "}");
139 
140     JavaFileObject bar =
141         JavaFileObjects.forSourceLines(
142             "test.Bar",
143             "package test;",
144             "",
145             "import javax.inject.Inject;",
146             "",
147             "@UnresolvableAnnotation",
148             "class Bar {",
149             "  @Inject",
150             "  Bar(String dep) {}",
151             "}");
152 
153     Compilation compilation = daggerCompiler().compile(fooComponent, foo, bar);
154     assertThat(compilation).failed();
155     assertThat(compilation).hadErrorCount(3);
156     assertThat(compilation).hadErrorContaining(
157         "cannot find symbol"
158             + "\n  symbol: class UnresolvableAnnotation");
159     String trace = "\n  "
160         + "\n  Dependency trace:"
161         + "\n      => element (CLASS): test.Bar"
162         + "\n      => annotation: @UnresolvableAnnotation"
163         + "\n      => type (ERROR annotation type): UnresolvableAnnotation";
164     assertThat(compilation).hadErrorContaining(
165         "InjectProcessingStep was unable to process 'Bar(java.lang.String)' because "
166             + "'UnresolvableAnnotation' could not be resolved." + trace);
167     assertThat(compilation).hadErrorContaining(
168         "ComponentProcessingStep was unable to process 'test.FooComponent' because "
169             + "'UnresolvableAnnotation' could not be resolved." + trace);
170   }
171 
172   @Test
referencesUnresolvableAnnotationOnTypeOnParameter()173   public void referencesUnresolvableAnnotationOnTypeOnParameter() {
174     JavaFileObject fooComponent =
175         JavaFileObjects.forSourceLines(
176             "test.FooComponent",
177             "package test;",
178             "",
179             "import dagger.Component;",
180             "",
181             "@Component",
182             "interface FooComponent {",
183             "  Foo foo();",
184             "}");
185 
186     JavaFileObject foo =
187         JavaFileObjects.forSourceLines(
188             "test.Foo",
189             "package test;",
190             "",
191             "import javax.inject.Inject;",
192             "",
193             "class Foo {",
194             "  @Inject",
195             "  Foo(Bar bar) {}",
196             "}");
197 
198     JavaFileObject bar =
199         JavaFileObjects.forSourceLines(
200             "test.Bar",
201             "package test;",
202             "",
203             "import javax.inject.Inject;",
204             "",
205             "class Bar {",
206             "  @Inject",
207             "  Bar(@UnresolvableAnnotation String dep) {}",
208             "}");
209 
210     Compilation compilation = daggerCompiler().compile(fooComponent, foo, bar);
211     assertThat(compilation).failed();
212     assertThat(compilation).hadErrorCount(3);
213     assertThat(compilation).hadErrorContaining(
214         "cannot find symbol"
215             + "\n  symbol:   class UnresolvableAnnotation"
216             + "\n  location: class test.Bar");
217     String trace = "\n  "
218         + "\n  Dependency trace:"
219         + "\n      => element (CLASS): test.Bar"
220         + "\n      => element (CONSTRUCTOR): Bar(java.lang.String)"
221         + "\n      => element (PARAMETER): dep"
222         + "\n      => annotation: @UnresolvableAnnotation"
223         + "\n      => type (ERROR annotation type): UnresolvableAnnotation";
224     assertThat(compilation).hadErrorContaining(
225         "InjectProcessingStep was unable to process 'Bar(java.lang.String)' because "
226             + "'UnresolvableAnnotation' could not be resolved." + trace);
227     assertThat(compilation).hadErrorContaining(
228         "ComponentProcessingStep was unable to process 'test.FooComponent' because "
229             + "'UnresolvableAnnotation' could not be resolved." + trace);
230   }
231 }
232