1 /* 2 * Copyright (C) 2020 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.hilt.android.processor.internal.aggregateddeps; 18 19 import static com.google.testing.compile.CompilationSubject.assertThat; 20 import static dagger.hilt.android.testing.compile.HiltCompilerTests.compiler; 21 22 import androidx.room.compiler.processing.util.Source; 23 import com.google.testing.compile.Compilation; 24 import com.google.testing.compile.JavaFileObjects; 25 import dagger.hilt.android.testing.compile.HiltCompilerTests; 26 import javax.tools.JavaFileObject; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.junit.runners.JUnit4; 30 31 @RunWith(JUnit4.class) 32 public class TestInstallInTest { 33 34 // TODO(danysantiago): Migrate to hiltCompiler() after b/288893275 is fixed. 35 @Test testMissingValues()36 public void testMissingValues() { 37 JavaFileObject testInstallInModule = 38 JavaFileObjects.forSourceLines( 39 "test.TestInstallInModule", 40 "package test;", 41 "", 42 "import dagger.Module;", 43 "import dagger.hilt.testing.TestInstallIn;", 44 "", 45 "@Module", 46 "@TestInstallIn", 47 "interface TestInstallInModule {}"); 48 Compilation compilation = compiler().compile(testInstallInModule); 49 assertThat(compilation).failed(); 50 assertThat(compilation).hadErrorCount(1); 51 assertThat(compilation) 52 .hadErrorContaining( 53 "@dagger.hilt.testing.TestInstallIn is missing default values for elements " 54 + "components,replaces") 55 .inFile(testInstallInModule) 56 .onLine(7); 57 } 58 59 @Test testEmptyComponentValues()60 public void testEmptyComponentValues() { 61 Source installInModule = 62 HiltCompilerTests.javaSource( 63 "test.InstallInModule", 64 "package test;", 65 "", 66 "import dagger.Module;", 67 "import dagger.hilt.InstallIn;", 68 "import dagger.hilt.components.SingletonComponent;", 69 "", 70 "@Module", 71 "@InstallIn(SingletonComponent.class)", 72 "interface InstallInModule {}"); 73 Source testInstallInModule = 74 HiltCompilerTests.javaSource( 75 "test.TestInstallInModule", 76 "package test;", 77 "", 78 "import dagger.Module;", 79 "import dagger.hilt.testing.TestInstallIn;", 80 "", 81 "@Module", 82 "@TestInstallIn(components = {}, replaces = InstallInModule.class)", 83 "interface TestInstallInModule {}"); 84 HiltCompilerTests.hiltCompiler(installInModule, testInstallInModule) 85 .compile( 86 subject -> { 87 subject.hasErrorCount(1); 88 // TODO(bcorso): Add inFile().onLine() whenever we've fixed 89 // Processors.getAnnotationClassValues 90 subject.hasErrorContaining( 91 "@TestInstallIn, 'components' class is invalid or missing: " 92 + "@dagger.hilt.testing.TestInstallIn(" 93 + "components={}, replaces={test.InstallInModule})"); 94 }); 95 } 96 97 @Test testEmptyReplacesValues()98 public void testEmptyReplacesValues() { 99 Source testInstallInModule = 100 HiltCompilerTests.javaSource( 101 "test.TestInstallInModule", 102 "package test;", 103 "", 104 "import dagger.Module;", 105 "import dagger.hilt.testing.TestInstallIn;", 106 "import dagger.hilt.components.SingletonComponent;", 107 "", 108 "@Module", 109 "@TestInstallIn(components = SingletonComponent.class, replaces = {})", 110 "interface TestInstallInModule {}"); 111 HiltCompilerTests.hiltCompiler(testInstallInModule) 112 .compile( 113 subject -> { 114 subject.hasErrorCount(1); 115 // TODO(bcorso): Add inFile().onLine() whenever we've fixed 116 // Processors.getAnnotationClassValues 117 subject.hasErrorContaining( 118 "@TestInstallIn, 'replaces' class is invalid or missing: " 119 + "@dagger.hilt.testing.TestInstallIn(" 120 + "components={dagger.hilt.components.SingletonComponent}, replaces={})"); 121 }); 122 } 123 124 @Test testMissingModuleAnnotation()125 public void testMissingModuleAnnotation() { 126 Source installInModule = 127 HiltCompilerTests.javaSource( 128 "test.InstallInModule", 129 "package test;", 130 "", 131 "import dagger.Module;", 132 "import dagger.hilt.InstallIn;", 133 "import dagger.hilt.components.SingletonComponent;", 134 "", 135 "@Module", 136 "@InstallIn(SingletonComponent.class)", 137 "interface InstallInModule {}"); 138 Source testInstallInModule = 139 HiltCompilerTests.javaSource( 140 "test.TestInstallInModule", 141 "package test;", 142 "", 143 "import dagger.Module;", 144 "import dagger.hilt.components.SingletonComponent;", 145 "import dagger.hilt.testing.TestInstallIn;", 146 "", 147 "@TestInstallIn(", 148 " components = SingletonComponent.class,", 149 " replaces = InstallInModule.class)", 150 "interface TestInstallInModule {}"); 151 HiltCompilerTests.hiltCompiler(installInModule, testInstallInModule) 152 .compile( 153 subject -> { 154 subject.hasErrorCount(1); 155 subject 156 .hasErrorContaining( 157 "@TestInstallIn-annotated classes must also be annotated with @Module or" 158 + " @EntryPoint: test.TestInstallInModule") 159 .onSource(testInstallInModule) 160 .onLine(10); 161 }); 162 } 163 164 @Test testInvalidUsageOnEntryPoint()165 public void testInvalidUsageOnEntryPoint() { 166 Source installInModule = 167 HiltCompilerTests.javaSource( 168 "test.InstallInModule", 169 "package test;", 170 "", 171 "import dagger.Module;", 172 "import dagger.hilt.InstallIn;", 173 "import dagger.hilt.components.SingletonComponent;", 174 "", 175 "@Module", 176 "@InstallIn(SingletonComponent.class)", 177 "interface InstallInModule {}"); 178 Source testInstallInEntryPoint = 179 HiltCompilerTests.javaSource( 180 "test.TestInstallInEntryPoint", 181 "package test;", 182 "", 183 "import dagger.hilt.EntryPoint;", 184 "import dagger.hilt.components.SingletonComponent;", 185 "import dagger.hilt.testing.TestInstallIn;", 186 "", 187 "@EntryPoint", 188 "@TestInstallIn(", 189 " components = SingletonComponent.class,", 190 " replaces = InstallInModule.class)", 191 "interface TestInstallInEntryPoint {}"); 192 HiltCompilerTests.hiltCompiler(installInModule, testInstallInEntryPoint) 193 .compile( 194 subject -> { 195 subject.hasErrorCount(1); 196 subject 197 .hasErrorContaining("@TestInstallIn can only be used with modules") 198 .onSource(testInstallInEntryPoint) 199 .onLine(11); 200 }); 201 } 202 203 @Test testInvalidReplaceModules()204 public void testInvalidReplaceModules() { 205 Source foo = HiltCompilerTests.javaSource("test.Foo", "package test;", "", "class Foo {}"); 206 Source testInstallInModule = 207 HiltCompilerTests.javaSource( 208 "test.TestInstallInModule", 209 "package test;", 210 "", 211 "import dagger.Module;", 212 "import dagger.hilt.components.SingletonComponent;", 213 "import dagger.hilt.testing.TestInstallIn;", 214 "", 215 "@Module", 216 "@TestInstallIn(", 217 " components = SingletonComponent.class,", 218 " replaces = Foo.class)", 219 "interface TestInstallInModule {}"); 220 HiltCompilerTests.hiltCompiler(foo, testInstallInModule) 221 .compile( 222 subject -> { 223 subject.hasErrorCount(1); 224 subject 225 .hasErrorContaining( 226 "@TestInstallIn#replaces() can only contain @InstallIn modules, but found:" 227 + " [test.Foo]") 228 .onSource(testInstallInModule) 229 .onLine(11); 230 }); 231 } 232 233 @Test testInternalDaggerReplaceModules()234 public void testInternalDaggerReplaceModules() { 235 Source testInstallInModule = 236 HiltCompilerTests.javaSource( 237 "test.TestInstallInModule", 238 "package test;", 239 "", 240 "import dagger.Module;", 241 "import dagger.hilt.components.SingletonComponent;", 242 "import dagger.hilt.testing.TestInstallIn;", 243 "", 244 "@Module", 245 "@TestInstallIn(", 246 " components = SingletonComponent.class,", 247 " replaces = dagger.hilt.android.internal.modules.ApplicationContextModule.class)", 248 "interface TestInstallInModule {}"); 249 HiltCompilerTests.hiltCompiler(testInstallInModule) 250 .compile( 251 subject -> { 252 subject.hasErrorCount(1); 253 subject 254 .hasErrorContaining( 255 "@TestInstallIn#replaces() cannot contain internal Hilt modules, but found: " 256 + "[dagger.hilt.android.internal.modules.ApplicationContextModule]") 257 .onSource(testInstallInModule) 258 .onLine(11); 259 }); 260 } 261 262 @Test testHiltWrapperDaggerReplaceModules()263 public void testHiltWrapperDaggerReplaceModules() { 264 Source testInstallInModule = 265 HiltCompilerTests.javaSource( 266 "test.TestInstallInModule", 267 "package test;", 268 "", 269 "import dagger.Module;", 270 "import dagger.hilt.components.SingletonComponent;", 271 "import dagger.hilt.testing.TestInstallIn;", 272 "import" 273 + " dagger.hilt.android.processor.internal.aggregateddeps.HiltWrapper_InstallInModule;", 274 "", 275 "@Module", 276 "@TestInstallIn(", 277 " components = SingletonComponent.class,", 278 // Note: this module is built in a separate library since AggregatedDepsProcessor can't 279 // handle modules generated in the same round. 280 " replaces = HiltWrapper_InstallInModule.class)", 281 "interface TestInstallInModule {}"); 282 HiltCompilerTests.hiltCompiler(testInstallInModule) 283 .compile( 284 subject -> { 285 subject.hasErrorCount(1); 286 subject 287 .hasErrorContaining( 288 "@TestInstallIn#replaces() cannot contain Hilt generated public wrapper" 289 + " modules, but found:" 290 + " [dagger.hilt.android.processor.internal.aggregateddeps." 291 + "HiltWrapper_InstallInModule]") 292 .onSource(testInstallInModule) 293 .onLine(12); 294 }); 295 } 296 297 @Test testCannotReplaceLocalInstallInModule()298 public void testCannotReplaceLocalInstallInModule() { 299 Source test = 300 HiltCompilerTests.javaSource( 301 "test.MyTest", 302 "package test;", 303 "", 304 "import dagger.Module;", 305 "import dagger.hilt.InstallIn;", 306 "import dagger.hilt.components.SingletonComponent;", 307 "import dagger.hilt.testing.TestInstallIn;", 308 "import dagger.hilt.android.testing.HiltAndroidTest;", 309 "", 310 "@HiltAndroidTest", 311 "public class MyTest {", 312 " @Module", 313 " @InstallIn(SingletonComponent.class)", 314 " interface LocalInstallInModule {}", 315 "}"); 316 Source testInstallIn = 317 HiltCompilerTests.javaSource( 318 "test.TestInstallInModule", 319 "package test;", 320 "", 321 "import dagger.Module;", 322 "import dagger.hilt.components.SingletonComponent;", 323 "import dagger.hilt.testing.TestInstallIn;", 324 "", 325 "@Module", 326 "@TestInstallIn(", 327 " components = SingletonComponent.class,", 328 " replaces = MyTest.LocalInstallInModule.class)", 329 "interface TestInstallInModule {}"); 330 HiltCompilerTests.hiltCompiler(test, testInstallIn) 331 .compile( 332 subject -> { 333 subject.hasErrorCount(1); 334 subject 335 .hasErrorContaining( 336 "TestInstallIn#replaces() cannot replace test specific @InstallIn modules," 337 + " but found: [test.MyTest.LocalInstallInModule].") 338 .onSource(testInstallIn) 339 .onLine(11); 340 }); 341 } 342 343 @Test testThatTestInstallInCannotOriginateFromTest()344 public void testThatTestInstallInCannotOriginateFromTest() { 345 Source installInModule = 346 HiltCompilerTests.javaSource( 347 "test.InstallInModule", 348 "package test;", 349 "", 350 "import dagger.Module;", 351 "import dagger.hilt.InstallIn;", 352 "import dagger.hilt.components.SingletonComponent;", 353 "", 354 "@Module", 355 "@InstallIn(SingletonComponent.class)", 356 "interface InstallInModule {}"); 357 Source test = 358 HiltCompilerTests.javaSource( 359 "test.MyTest", 360 "package test;", 361 "", 362 "import dagger.Module;", 363 "import dagger.hilt.components.SingletonComponent;", 364 "import dagger.hilt.testing.TestInstallIn;", 365 "import dagger.hilt.android.testing.HiltAndroidTest;", 366 "", 367 "@HiltAndroidTest", 368 "public class MyTest {", 369 " @Module", 370 " @TestInstallIn(", 371 " components = SingletonComponent.class,", 372 " replaces = InstallInModule.class)", 373 " interface TestInstallInModule {}", 374 "}"); 375 HiltCompilerTests.hiltCompiler(test, installInModule) 376 .compile( 377 subject -> { 378 subject.hasErrorCount(1); 379 subject 380 .hasErrorContaining( 381 "@TestInstallIn modules cannot be nested in (or originate from) a " 382 + "@HiltAndroidTest-annotated class: test.MyTest") 383 .onSource(test) 384 .onLine(14); 385 }); 386 } 387 } 388