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.androidentrypoint; 18 19 import androidx.room.compiler.processing.XProcessingEnv; 20 import androidx.room.compiler.processing.XProcessingEnv.Backend; 21 import androidx.room.compiler.processing.util.CompilationResultSubject; 22 import androidx.room.compiler.processing.util.Source; 23 import com.google.common.collect.ImmutableMap; 24 import dagger.hilt.android.testing.compile.HiltCompilerTests; 25 import org.junit.Test; 26 import org.junit.runner.RunWith; 27 import org.junit.runners.JUnit4; 28 29 @RunWith(JUnit4.class) 30 public class AndroidEntryPointProcessorTest { 31 @Test testAndroidEntryPoint()32 public void testAndroidEntryPoint() { 33 Source testActivity = 34 HiltCompilerTests.javaSource( 35 "test.MyActivity", 36 "package test;", 37 "", 38 "import androidx.activity.ComponentActivity;", 39 "import dagger.hilt.android.AndroidEntryPoint;", 40 "", 41 "@AndroidEntryPoint(ComponentActivity.class)", 42 "public class MyActivity extends Hilt_MyActivity {}"); 43 44 HiltCompilerTests.hiltCompiler(testActivity) 45 .compile( 46 (CompilationResultSubject subject) -> { 47 subject.hasErrorCount(0); 48 subject.generatedSourceFileWithPath("test/Hilt_MyActivity.java"); 49 }); 50 } 51 52 @Test missingBaseClass()53 public void missingBaseClass() { 54 Source testActivity = 55 HiltCompilerTests.javaSource( 56 "test.MyActivity", 57 "package test;", 58 "", 59 "import androidx.activity.ComponentActivity;", 60 "import dagger.hilt.android.AndroidEntryPoint;", 61 "", 62 "@AndroidEntryPoint", 63 "public class MyActivity extends ComponentActivity { }"); 64 HiltCompilerTests.hiltCompiler(testActivity) 65 .compile( 66 (CompilationResultSubject subject) -> { 67 subject.hasErrorCount(1); 68 subject 69 .hasErrorContaining("Expected @AndroidEntryPoint to have a value.") 70 ; 71 }); 72 } 73 74 @Test incorrectSuperclass()75 public void incorrectSuperclass() { 76 Source testActivity = 77 HiltCompilerTests.javaSource( 78 "test.MyActivity", 79 "package test;", 80 "", 81 "import androidx.activity.ComponentActivity;", 82 "import dagger.hilt.android.AndroidEntryPoint;", 83 "", 84 "@AndroidEntryPoint(ComponentActivity.class)", 85 "public class MyActivity extends ComponentActivity { }"); 86 HiltCompilerTests.hiltCompiler(testActivity) 87 .compile( 88 (CompilationResultSubject subject) -> { 89 // TODO(b/288210593): Add this check back to KSP once this bug is fixed. 90 if (HiltCompilerTests.backend(subject) == XProcessingEnv.Backend.KSP) { 91 subject.hasErrorCount(0); 92 } else { 93 subject.hasErrorCount(1); 94 subject 95 .hasErrorContaining( 96 "@AndroidEntryPoint class expected to extend Hilt_MyActivity. " 97 + "Found: ComponentActivity") 98 ; 99 } 100 }); 101 } 102 103 @Test disableSuperclassValidation_activity()104 public void disableSuperclassValidation_activity() { 105 Source testActivity = 106 HiltCompilerTests.javaSource( 107 "test.MyActivity", 108 "package test;", 109 "", 110 "import androidx.activity.ComponentActivity;", 111 "import dagger.hilt.android.AndroidEntryPoint;", 112 "", 113 "@AndroidEntryPoint", 114 "public class MyActivity extends ComponentActivity { }"); 115 HiltCompilerTests.hiltCompiler(testActivity) 116 .withProcessorOptions( 117 ImmutableMap.of( 118 "dagger.hilt.android.internal.disableAndroidSuperclassValidation", "true")) 119 .compile(subject -> subject.hasErrorCount(0)); 120 } 121 122 @Test disableSuperclassValidation_application()123 public void disableSuperclassValidation_application() { 124 Source testApplication = 125 HiltCompilerTests.javaSource( 126 "test.MyApp", 127 "package test;", 128 "", 129 "import android.app.Application;", 130 "import dagger.hilt.android.HiltAndroidApp;", 131 "", 132 "@HiltAndroidApp", 133 "public class MyApp extends Application { }"); 134 HiltCompilerTests.hiltCompiler(testApplication) 135 .withProcessorOptions( 136 ImmutableMap.of( 137 "dagger.hilt.android.internal.disableAndroidSuperclassValidation", "true")) 138 .compile(subject -> subject.hasErrorCount(0)); 139 } 140 141 @Test checkBaseActivityExtendsComponentActivity()142 public void checkBaseActivityExtendsComponentActivity() { 143 Source testActivity = 144 HiltCompilerTests.javaSource( 145 "test.MyActivity", 146 "package test;", 147 "", 148 "import android.app.Activity;", 149 "import dagger.hilt.android.AndroidEntryPoint;", 150 "", 151 "@AndroidEntryPoint(Activity.class)", 152 "public class MyActivity extends Hilt_MyActivity { }"); 153 HiltCompilerTests.hiltCompiler(testActivity).compile(subject -> { 154 subject.compilationDidFail(); 155 subject.hasErrorContaining( 156 "Activities annotated with @AndroidEntryPoint must be a subclass of " 157 + "androidx.activity.ComponentActivity. (e.g. FragmentActivity, AppCompatActivity, " 158 + "etc.)"); }); 159 } 160 161 @Test checkBaseActivityWithTypeParameters()162 public void checkBaseActivityWithTypeParameters() { 163 Source testActivity = 164 HiltCompilerTests.javaSource( 165 "test.BaseActivity", 166 "package test;", 167 "", 168 "import androidx.activity.ComponentActivity;", 169 "import dagger.hilt.android.AndroidEntryPoint;", 170 "", 171 "@AndroidEntryPoint(ComponentActivity.class)", 172 "public class BaseActivity<T> extends Hilt_BaseActivity {}"); 173 HiltCompilerTests.hiltCompiler(testActivity) 174 .compile( 175 subject -> { 176 subject.compilationDidFail(); 177 if (HiltCompilerTests.backend(subject) == Backend.JAVAC) { 178 subject.hasErrorCount(2); 179 } else { 180 subject.hasErrorCount(1); 181 } 182 subject.hasErrorContaining( 183 "@AndroidEntryPoint-annotated classes cannot have type parameters."); 184 }); 185 } 186 187 @Test checkAndroidEntryPointOnApplicationRecommendsHiltAndroidApp()188 public void checkAndroidEntryPointOnApplicationRecommendsHiltAndroidApp() { 189 Source testActivity = 190 HiltCompilerTests.javaSource( 191 "test.MyApplication", 192 "package test;", 193 "", 194 "import android.app.Application;", 195 "import dagger.hilt.android.AndroidEntryPoint;", 196 "", 197 "@AndroidEntryPoint(Application.class)", 198 "public class MyApplication extends Hilt_MyApplication { }"); 199 HiltCompilerTests.hiltCompiler(testActivity) 200 .compile( 201 (CompilationResultSubject subject) -> { 202 if (HiltCompilerTests.backend(subject) == XProcessingEnv.Backend.KSP) { 203 subject.hasErrorCount(1); 204 } else { 205 // Javac has an extra error due to the missing symbol. 206 subject.hasErrorCount(2); 207 subject.hasErrorContaining( 208 "cannot find symbol\n symbol: class Hilt_MyApplication"); 209 } 210 subject.hasErrorContaining( 211 "@AndroidEntryPoint cannot be used on an Application. " 212 + "Use @HiltAndroidApp instead."); 213 }); 214 } 215 } 216