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