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 static com.google.testing.compile.CompilationSubject.assertThat;
20 import static dagger.hilt.android.processor.AndroidCompilers.compiler;
21 
22 import com.google.testing.compile.Compilation;
23 import com.google.testing.compile.JavaFileObjects;
24 import javax.tools.JavaFileObject;
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 
32   @Test
missingBaseClass()33   public void missingBaseClass() {
34     JavaFileObject testActivity =
35         JavaFileObjects.forSourceLines(
36             "test.MyActivity",
37             "package test;",
38             "",
39             "import androidx.activity.ComponentActivity;",
40             "import dagger.hilt.android.AndroidEntryPoint;",
41             "",
42             "@AndroidEntryPoint",
43             "public class MyActivity extends ComponentActivity { }");
44     Compilation compilation = compiler().compile(testActivity);
45     assertThat(compilation).failed();
46     assertThat(compilation)
47         .hadErrorContaining("Expected @AndroidEntryPoint to have a value.")
48         ;
49   }
50 
51   @Test
incorrectSuperclass()52   public void incorrectSuperclass() {
53     JavaFileObject testActivity =
54         JavaFileObjects.forSourceLines(
55             "test.MyActivity",
56             "package test;",
57             "",
58             "import androidx.activity.ComponentActivity;",
59             "import dagger.hilt.android.AndroidEntryPoint;",
60             "",
61             "@AndroidEntryPoint(ComponentActivity.class)",
62             "public class MyActivity extends ComponentActivity { }");
63     Compilation compilation = compiler().compile(testActivity);
64     assertThat(compilation).failed();
65     assertThat(compilation)
66         .hadErrorContaining(
67             "@AndroidEntryPoint class expected to extend Hilt_MyActivity. "
68                 + "Found: ComponentActivity")
69         ;
70   }
71 
72   @Test
disableSuperclassValidation_activity()73   public void disableSuperclassValidation_activity() {
74     JavaFileObject testActivity =
75         JavaFileObjects.forSourceLines(
76             "test.MyActivity",
77             "package test;",
78             "",
79             "import androidx.activity.ComponentActivity;",
80             "import dagger.hilt.android.AndroidEntryPoint;",
81             "",
82             "@AndroidEntryPoint",
83             "public class MyActivity extends ComponentActivity { }");
84     Compilation compilation =
85         compiler()
86             .withOptions("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
87             .compile(testActivity);
88     assertThat(compilation).succeeded();
89   }
90 
91   @Test
disableSuperclassValidation_application()92   public void disableSuperclassValidation_application() {
93     JavaFileObject testApplication =
94         JavaFileObjects.forSourceLines(
95             "test.MyApp",
96             "package test;",
97             "",
98             "import android.app.Application;",
99             "import dagger.hilt.android.HiltAndroidApp;",
100             "",
101             "@HiltAndroidApp",
102             "public class MyApp extends Application { }");
103     Compilation compilation =
104         compiler()
105             .withOptions("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
106             .compile(testApplication);
107     assertThat(compilation).succeeded();
108   }
109 
110   @Test
checkBaseActivityExtendsComponentActivity()111   public void checkBaseActivityExtendsComponentActivity() {
112     JavaFileObject testActivity =
113         JavaFileObjects.forSourceLines(
114             "test.MyActivity",
115             "package test;",
116             "",
117             "import android.app.Activity;",
118             "import dagger.hilt.android.AndroidEntryPoint;",
119             "",
120             "@AndroidEntryPoint(Activity.class)",
121             "public class MyActivity extends Hilt_MyActivity { }");
122     Compilation compilation = compiler().compile(testActivity);
123     assertThat(compilation).failed();
124     assertThat(compilation)
125         .hadErrorContaining("Activities annotated with @AndroidEntryPoint must be a subclass of "
126             + "androidx.activity.ComponentActivity. (e.g. FragmentActivity, AppCompatActivity, "
127             + "etc.)");
128   }
129 
130   @Test
checkBaseActivityWithTypeParameters()131   public void checkBaseActivityWithTypeParameters() {
132     JavaFileObject testActivity =
133         JavaFileObjects.forSourceLines(
134             "test.BaseActivity",
135             "package test;",
136             "",
137             "import androidx.activity.ComponentActivity;",
138             "import dagger.hilt.android.AndroidEntryPoint;",
139             "",
140             "@AndroidEntryPoint(ComponentActivity.class)",
141             "public class BaseActivity<T> extends Hilt_BaseActivity {}");
142     Compilation compilation = compiler().compile(testActivity);
143     assertThat(compilation).failed();
144     assertThat(compilation).hadErrorCount(2);
145     assertThat(compilation).hadErrorContaining(
146         "cannot find symbol\n  symbol: class Hilt_BaseActivity");
147     assertThat(compilation).hadErrorContaining(
148         "@AndroidEntryPoint-annotated classes cannot have type parameters.");
149   }
150 
151   @Test
checkAndroidEntryPointOnApplicationRecommendsHiltAndroidApp()152   public void checkAndroidEntryPointOnApplicationRecommendsHiltAndroidApp() {
153     JavaFileObject testActivity =
154         JavaFileObjects.forSourceLines(
155             "test.MyApplication",
156             "package test;",
157             "",
158             "import android.app.Application;",
159             "import dagger.hilt.android.AndroidEntryPoint;",
160             "",
161             "@AndroidEntryPoint(Application.class)",
162             "public class MyApplication extends Hilt_MyApplication { }");
163     Compilation compilation = compiler().compile(testActivity);
164     assertThat(compilation).failed();
165     assertThat(compilation)
166         .hadErrorContaining("@AndroidEntryPoint cannot be used on an Application. "
167             + "Use @HiltAndroidApp instead.");
168   }
169 }
170