xref: /aosp_15_r20/external/dagger2/javatests/dagger/internal/codegen/UnresolvableDependencyTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2021 The Dagger Authors.
3*f585d8a3SJacky Wang  *
4*f585d8a3SJacky Wang  * Licensed under the Apache License, Version 2.0 (the "License");
5*f585d8a3SJacky Wang  * you may not use this file except in compliance with the License.
6*f585d8a3SJacky Wang  * You may obtain a copy of the License at
7*f585d8a3SJacky Wang  *
8*f585d8a3SJacky Wang  * http://www.apache.org/licenses/LICENSE-2.0
9*f585d8a3SJacky Wang  *
10*f585d8a3SJacky Wang  * Unless required by applicable law or agreed to in writing, software
11*f585d8a3SJacky Wang  * distributed under the License is distributed on an "AS IS" BASIS,
12*f585d8a3SJacky Wang  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*f585d8a3SJacky Wang  * See the License for the specific language governing permissions and
14*f585d8a3SJacky Wang  * limitations under the License.
15*f585d8a3SJacky Wang  */
16*f585d8a3SJacky Wang 
17*f585d8a3SJacky Wang package dagger.internal.codegen;
18*f585d8a3SJacky Wang 
19*f585d8a3SJacky Wang import static com.google.common.truth.Truth.assertThat;
20*f585d8a3SJacky Wang 
21*f585d8a3SJacky Wang import androidx.room.compiler.processing.XProcessingEnv;
22*f585d8a3SJacky Wang import androidx.room.compiler.processing.util.Source;
23*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap;
24*f585d8a3SJacky Wang import dagger.testing.compile.CompilerTests;
25*f585d8a3SJacky Wang import org.junit.Test;
26*f585d8a3SJacky Wang import org.junit.runner.RunWith;
27*f585d8a3SJacky Wang import org.junit.runners.JUnit4;
28*f585d8a3SJacky Wang 
29*f585d8a3SJacky Wang @RunWith(JUnit4.class)
30*f585d8a3SJacky Wang public final class UnresolvableDependencyTest {
31*f585d8a3SJacky Wang 
32*f585d8a3SJacky Wang   @Test
referencesUnresolvableDependency()33*f585d8a3SJacky Wang   public void referencesUnresolvableDependency() {
34*f585d8a3SJacky Wang     Source fooComponent =
35*f585d8a3SJacky Wang         CompilerTests.javaSource(
36*f585d8a3SJacky Wang             "test.FooComponent",
37*f585d8a3SJacky Wang             "package test;",
38*f585d8a3SJacky Wang             "",
39*f585d8a3SJacky Wang             "import dagger.Component;",
40*f585d8a3SJacky Wang             "",
41*f585d8a3SJacky Wang             "@Component",
42*f585d8a3SJacky Wang             "interface FooComponent {",
43*f585d8a3SJacky Wang             "  Foo foo();",
44*f585d8a3SJacky Wang             "}");
45*f585d8a3SJacky Wang 
46*f585d8a3SJacky Wang     Source foo =
47*f585d8a3SJacky Wang         CompilerTests.javaSource(
48*f585d8a3SJacky Wang             "test.Foo",
49*f585d8a3SJacky Wang             "package test;",
50*f585d8a3SJacky Wang             "",
51*f585d8a3SJacky Wang             "import javax.inject.Inject;",
52*f585d8a3SJacky Wang             "",
53*f585d8a3SJacky Wang             "class Foo {",
54*f585d8a3SJacky Wang             "  @Inject",
55*f585d8a3SJacky Wang             "  Foo(Bar bar) {}",
56*f585d8a3SJacky Wang             "}");
57*f585d8a3SJacky Wang 
58*f585d8a3SJacky Wang     Source bar =
59*f585d8a3SJacky Wang         CompilerTests.javaSource(
60*f585d8a3SJacky Wang             "test.Bar",
61*f585d8a3SJacky Wang             "package test;",
62*f585d8a3SJacky Wang             "",
63*f585d8a3SJacky Wang             "import javax.inject.Inject;",
64*f585d8a3SJacky Wang             "",
65*f585d8a3SJacky Wang             "class Bar {",
66*f585d8a3SJacky Wang             "  @Inject",
67*f585d8a3SJacky Wang             "  Bar(UnresolvableDependency dep) {}",
68*f585d8a3SJacky Wang             "}");
69*f585d8a3SJacky Wang 
70*f585d8a3SJacky Wang     // Only include a minimal portion of the stacktrace to minimize breaking tests due to refactors.
71*f585d8a3SJacky Wang     String stacktraceErrorMessage =
72*f585d8a3SJacky Wang         "dagger.internal.codegen.base"
73*f585d8a3SJacky Wang             + ".DaggerSuperficialValidation$ValidationException$KnownErrorType";
74*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(fooComponent, foo, bar)
75*f585d8a3SJacky Wang         .compile(
76*f585d8a3SJacky Wang             subject -> {
77*f585d8a3SJacky Wang               switch (CompilerTests.backend(subject)) {
78*f585d8a3SJacky Wang                 case JAVAC:
79*f585d8a3SJacky Wang                   subject.hasErrorCount(3);
80*f585d8a3SJacky Wang                   subject.hasErrorContaining(
81*f585d8a3SJacky Wang                       "cannot find symbol"
82*f585d8a3SJacky Wang                           + "\n  symbol:   class UnresolvableDependency"
83*f585d8a3SJacky Wang                           + "\n  location: class test.Bar");
84*f585d8a3SJacky Wang                   break;
85*f585d8a3SJacky Wang                 case KSP:
86*f585d8a3SJacky Wang                   subject.hasErrorCount(2);
87*f585d8a3SJacky Wang                   break;
88*f585d8a3SJacky Wang               }
89*f585d8a3SJacky Wang               // TODO(b/248552462): Javac and KSP should match once this bug is fixed.
90*f585d8a3SJacky Wang               boolean isJavac = CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC;
91*f585d8a3SJacky Wang               String trace = "\n  "
92*f585d8a3SJacky Wang                   + "\n  Dependency trace:"
93*f585d8a3SJacky Wang                   + "\n      => element (CLASS): test.Bar"
94*f585d8a3SJacky Wang                   + "\n      => element (CONSTRUCTOR): Bar(%1$s)"
95*f585d8a3SJacky Wang                   + "\n      => type (EXECUTABLE constructor): (%1$s)void"
96*f585d8a3SJacky Wang                   + "\n      => type (ERROR parameter type): %1$s";
97*f585d8a3SJacky Wang               subject.hasErrorContaining(
98*f585d8a3SJacky Wang                   String.format(
99*f585d8a3SJacky Wang                       "InjectProcessingStep was unable to process 'Bar(%1$s)' because '%1$s' could "
100*f585d8a3SJacky Wang                           + "not be resolved." + trace,
101*f585d8a3SJacky Wang                       isJavac ? "UnresolvableDependency" : "error.NonExistentClass"));
102*f585d8a3SJacky Wang               subject.hasErrorContaining(
103*f585d8a3SJacky Wang                   String.format(
104*f585d8a3SJacky Wang                       "ComponentProcessingStep was unable to process 'test.FooComponent' because "
105*f585d8a3SJacky Wang                           + "'%1$s' could not be resolved." + trace,
106*f585d8a3SJacky Wang                       isJavac ? "UnresolvableDependency" : "error.NonExistentClass"));
107*f585d8a3SJacky Wang 
108*f585d8a3SJacky Wang               // Check that the stacktrace is not included in the error message by default.
109*f585d8a3SJacky Wang               assertThat(subject.getCompilationResult().rawOutput())
110*f585d8a3SJacky Wang                   .doesNotContain(stacktraceErrorMessage);
111*f585d8a3SJacky Wang             });
112*f585d8a3SJacky Wang 
113*f585d8a3SJacky Wang 
114*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(fooComponent, foo, bar)
115*f585d8a3SJacky Wang         .withProcessingOptions(
116*f585d8a3SJacky Wang             ImmutableMap.of("dagger.includeStacktraceWithDeferredErrorMessages", "ENABLED"))
117*f585d8a3SJacky Wang         .compile(
118*f585d8a3SJacky Wang             subject -> {
119*f585d8a3SJacky Wang               switch (CompilerTests.backend(subject)) {
120*f585d8a3SJacky Wang                 case JAVAC:
121*f585d8a3SJacky Wang                   subject.hasErrorCount(3);
122*f585d8a3SJacky Wang                   break;
123*f585d8a3SJacky Wang                 case KSP:
124*f585d8a3SJacky Wang                   subject.hasErrorCount(2);
125*f585d8a3SJacky Wang                   break;
126*f585d8a3SJacky Wang               }
127*f585d8a3SJacky Wang               subject.hasErrorContaining(stacktraceErrorMessage);
128*f585d8a3SJacky Wang             });
129*f585d8a3SJacky Wang   }
130*f585d8a3SJacky Wang 
131*f585d8a3SJacky Wang   @Test
referencesUnresolvableAnnotationOnType()132*f585d8a3SJacky Wang   public void referencesUnresolvableAnnotationOnType() {
133*f585d8a3SJacky Wang     Source fooComponent =
134*f585d8a3SJacky Wang         CompilerTests.javaSource(
135*f585d8a3SJacky Wang             "test.FooComponent",
136*f585d8a3SJacky Wang             "package test;",
137*f585d8a3SJacky Wang             "",
138*f585d8a3SJacky Wang             "import dagger.Component;",
139*f585d8a3SJacky Wang             "",
140*f585d8a3SJacky Wang             "@Component",
141*f585d8a3SJacky Wang             "interface FooComponent {",
142*f585d8a3SJacky Wang             "  Foo foo();",
143*f585d8a3SJacky Wang             "}");
144*f585d8a3SJacky Wang 
145*f585d8a3SJacky Wang     Source foo =
146*f585d8a3SJacky Wang         CompilerTests.javaSource(
147*f585d8a3SJacky Wang             "test.Foo",
148*f585d8a3SJacky Wang             "package test;",
149*f585d8a3SJacky Wang             "",
150*f585d8a3SJacky Wang             "import javax.inject.Inject;",
151*f585d8a3SJacky Wang             "",
152*f585d8a3SJacky Wang             "class Foo {",
153*f585d8a3SJacky Wang             "  @Inject",
154*f585d8a3SJacky Wang             "  Foo(Bar bar) {}",
155*f585d8a3SJacky Wang             "}");
156*f585d8a3SJacky Wang 
157*f585d8a3SJacky Wang     Source bar =
158*f585d8a3SJacky Wang         CompilerTests.javaSource(
159*f585d8a3SJacky Wang             "test.Bar",
160*f585d8a3SJacky Wang             "package test;",
161*f585d8a3SJacky Wang             "",
162*f585d8a3SJacky Wang             "import javax.inject.Inject;",
163*f585d8a3SJacky Wang             "",
164*f585d8a3SJacky Wang             "@UnresolvableAnnotation",
165*f585d8a3SJacky Wang             "class Bar {",
166*f585d8a3SJacky Wang             "  @Inject",
167*f585d8a3SJacky Wang             "  Bar(String dep) {}",
168*f585d8a3SJacky Wang             "}");
169*f585d8a3SJacky Wang 
170*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(fooComponent, foo, bar)
171*f585d8a3SJacky Wang         .compile(
172*f585d8a3SJacky Wang             subject -> {
173*f585d8a3SJacky Wang               switch (CompilerTests.backend(subject)) {
174*f585d8a3SJacky Wang                 case JAVAC:
175*f585d8a3SJacky Wang                   subject.hasErrorCount(3);
176*f585d8a3SJacky Wang                   subject.hasErrorContaining(
177*f585d8a3SJacky Wang                       "cannot find symbol"
178*f585d8a3SJacky Wang                           + "\n  symbol: class UnresolvableAnnotation");
179*f585d8a3SJacky Wang                   break;
180*f585d8a3SJacky Wang                 case KSP:
181*f585d8a3SJacky Wang                   subject.hasErrorCount(2);
182*f585d8a3SJacky Wang                   break;
183*f585d8a3SJacky Wang               }
184*f585d8a3SJacky Wang               // TODO(b/248552462): Javac and KSP should match once this bug is fixed.
185*f585d8a3SJacky Wang               boolean isJavac = CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC;
186*f585d8a3SJacky Wang               String trace = "\n  "
187*f585d8a3SJacky Wang                   + "\n  Dependency trace:"
188*f585d8a3SJacky Wang                   + "\n      => element (CLASS): test.Bar"
189*f585d8a3SJacky Wang                   + "\n      => annotation: @UnresolvableAnnotation"
190*f585d8a3SJacky Wang                   + "\n      => type (ERROR annotation type): %1$s";
191*f585d8a3SJacky Wang               subject.hasErrorContaining(
192*f585d8a3SJacky Wang                   String.format(
193*f585d8a3SJacky Wang                       "InjectProcessingStep was unable to process 'Bar(java.lang.String)' because "
194*f585d8a3SJacky Wang                           + "'%1$s' could not be resolved." + trace,
195*f585d8a3SJacky Wang                       isJavac ? "UnresolvableAnnotation" : "error.NonExistentClass"));
196*f585d8a3SJacky Wang               subject.hasErrorContaining(
197*f585d8a3SJacky Wang                   String.format(
198*f585d8a3SJacky Wang                       "ComponentProcessingStep was unable to process 'test.FooComponent' because "
199*f585d8a3SJacky Wang                           + "'%1$s' could not be resolved." + trace,
200*f585d8a3SJacky Wang                       isJavac ? "UnresolvableAnnotation" : "error.NonExistentClass"));
201*f585d8a3SJacky Wang             });
202*f585d8a3SJacky Wang   }
203*f585d8a3SJacky Wang 
204*f585d8a3SJacky Wang   @Test
referencesUnresolvableAnnotationOnTypeOnParameter()205*f585d8a3SJacky Wang   public void referencesUnresolvableAnnotationOnTypeOnParameter() {
206*f585d8a3SJacky Wang     Source fooComponent =
207*f585d8a3SJacky Wang         CompilerTests.javaSource(
208*f585d8a3SJacky Wang             "test.FooComponent",
209*f585d8a3SJacky Wang             "package test;",
210*f585d8a3SJacky Wang             "",
211*f585d8a3SJacky Wang             "import dagger.Component;",
212*f585d8a3SJacky Wang             "",
213*f585d8a3SJacky Wang             "@Component",
214*f585d8a3SJacky Wang             "interface FooComponent {",
215*f585d8a3SJacky Wang             "  Foo foo();",
216*f585d8a3SJacky Wang             "}");
217*f585d8a3SJacky Wang 
218*f585d8a3SJacky Wang     Source foo =
219*f585d8a3SJacky Wang         CompilerTests.javaSource(
220*f585d8a3SJacky Wang             "test.Foo",
221*f585d8a3SJacky Wang             "package test;",
222*f585d8a3SJacky Wang             "",
223*f585d8a3SJacky Wang             "import javax.inject.Inject;",
224*f585d8a3SJacky Wang             "",
225*f585d8a3SJacky Wang             "class Foo {",
226*f585d8a3SJacky Wang             "  @Inject",
227*f585d8a3SJacky Wang             "  Foo(Bar bar) {}",
228*f585d8a3SJacky Wang             "}");
229*f585d8a3SJacky Wang 
230*f585d8a3SJacky Wang     Source bar =
231*f585d8a3SJacky Wang         CompilerTests.javaSource(
232*f585d8a3SJacky Wang             "test.Bar",
233*f585d8a3SJacky Wang             "package test;",
234*f585d8a3SJacky Wang             "",
235*f585d8a3SJacky Wang             "import javax.inject.Inject;",
236*f585d8a3SJacky Wang             "",
237*f585d8a3SJacky Wang             "class Bar {",
238*f585d8a3SJacky Wang             "  @Inject",
239*f585d8a3SJacky Wang             "  Bar(@UnresolvableAnnotation String dep) {}",
240*f585d8a3SJacky Wang             "}");
241*f585d8a3SJacky Wang 
242*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(fooComponent, foo, bar)
243*f585d8a3SJacky Wang         .compile(
244*f585d8a3SJacky Wang             subject -> {
245*f585d8a3SJacky Wang               switch (CompilerTests.backend(subject)) {
246*f585d8a3SJacky Wang                 case JAVAC:
247*f585d8a3SJacky Wang                   subject.hasErrorCount(3);
248*f585d8a3SJacky Wang                   subject.hasErrorContaining(
249*f585d8a3SJacky Wang                       "cannot find symbol"
250*f585d8a3SJacky Wang                           + "\n  symbol:   class UnresolvableAnnotation"
251*f585d8a3SJacky Wang                           + "\n  location: class test.Bar");
252*f585d8a3SJacky Wang                   break;
253*f585d8a3SJacky Wang                 case KSP:
254*f585d8a3SJacky Wang                   subject.hasErrorCount(2);
255*f585d8a3SJacky Wang                   break;
256*f585d8a3SJacky Wang               }
257*f585d8a3SJacky Wang               // TODO(b/248552462): Javac and KSP should match once this bug is fixed.
258*f585d8a3SJacky Wang               boolean isJavac = CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC;
259*f585d8a3SJacky Wang               String trace = "\n  "
260*f585d8a3SJacky Wang                   + "\n  Dependency trace:"
261*f585d8a3SJacky Wang                   + "\n      => element (CLASS): test.Bar"
262*f585d8a3SJacky Wang                   + "\n      => element (CONSTRUCTOR): Bar(java.lang.String)"
263*f585d8a3SJacky Wang                   + "\n      => element (PARAMETER): dep"
264*f585d8a3SJacky Wang                   + "\n      => annotation: @UnresolvableAnnotation"
265*f585d8a3SJacky Wang                   + "\n      => type (ERROR annotation type): %1$s";
266*f585d8a3SJacky Wang               subject.hasErrorContaining(
267*f585d8a3SJacky Wang                   String.format(
268*f585d8a3SJacky Wang                       "InjectProcessingStep was unable to process 'Bar(java.lang.String)' because "
269*f585d8a3SJacky Wang                           + "'%1$s' could not be resolved." + trace,
270*f585d8a3SJacky Wang                       isJavac ? "UnresolvableAnnotation" : "error.NonExistentClass"));
271*f585d8a3SJacky Wang               subject.hasErrorContaining(
272*f585d8a3SJacky Wang                   String.format(
273*f585d8a3SJacky Wang                       "ComponentProcessingStep was unable to process 'test.FooComponent' because "
274*f585d8a3SJacky Wang                           + "'%1$s' could not be resolved." + trace,
275*f585d8a3SJacky Wang                       isJavac ? "UnresolvableAnnotation" : "error.NonExistentClass"));
276*f585d8a3SJacky Wang             });
277*f585d8a3SJacky Wang   }
278*f585d8a3SJacky Wang }
279