• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.viewmodel
18 
19 import com.google.testing.compile.CompilationSubject.assertThat
20 import com.google.testing.compile.Compiler
21 import org.junit.Test
22 import org.junit.runner.RunWith
23 import org.junit.runners.JUnit4
24 
25 @RunWith(JUnit4::class)
26 class ViewModelGeneratorTest {
27 
compilernull28   private fun compiler(): Compiler = Compiler.javac().withProcessors(ViewModelProcessor())
29 
30   @Test
31   fun verifyModule_noArg() {
32     val myViewModel = """
33         package dagger.hilt.android.test;
34 
35         import dagger.hilt.android.lifecycle.HiltViewModel;
36         import androidx.lifecycle.ViewModel;
37         import javax.inject.Inject;
38 
39         @HiltViewModel
40         class MyViewModel extends ViewModel {
41             @Inject
42             MyViewModel() { }
43         }
44         """.toJFO("dagger.hilt.android.test.MyViewModel")
45 
46     val expected = """
47         package dagger.hilt.android.test;
48 
49         $GENERATED_ANNOTATION
50         @OriginatingElement(
51             topLevelClass = MyViewModel.class
52         )
53         public final class MyViewModel_HiltModules {
54           private MyViewModel_HiltModules() {
55           }
56 
57           @Module
58           @InstallIn(ViewModelComponent.class)
59           public static abstract class BindsModule {
60             private BindsModule() {}
61 
62             @Binds
63             @IntoMap
64             @StringKey("dagger.hilt.android.test.MyViewModel")
65             @HiltViewModelMap
66             public abstract ViewModel binds(MyViewModel vm);
67           }
68 
69           @Module
70           @InstallIn(ActivityRetainedComponent.class)
71           public static final class KeyModule {
72             private KeyModule() {
73             }
74 
75             @Provides
76             @IntoSet
77             @HiltViewModelMap.KeySet
78             public static String provide() {
79               return "dagger.hilt.android.test.MyViewModel";
80             }
81           }
82         }
83         """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModule")
84 
85     val compilation = compiler()
86       .compile(myViewModel)
87     assertThat(compilation).apply {
88       succeeded()
89       generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules")
90         .containsElementsIn(expected)
91     }
92   }
93 
94   @Test
verifyModule_savedStateOnlyArgnull95   fun verifyModule_savedStateOnlyArg() {
96     val myViewModel = """
97         package dagger.hilt.android.test;
98 
99         import dagger.hilt.android.lifecycle.HiltViewModel;
100         import androidx.lifecycle.ViewModel;
101         import androidx.lifecycle.SavedStateHandle;
102         import javax.inject.Inject;
103 
104         @HiltViewModel
105         class MyViewModel extends ViewModel {
106             @Inject
107             MyViewModel(SavedStateHandle savedState) { }
108         }
109         """.toJFO("dagger.hilt.android.test.MyViewModel")
110 
111     val expected = """
112         package dagger.hilt.android.test;
113 
114         $GENERATED_ANNOTATION
115         @OriginatingElement(
116             topLevelClass = MyViewModel.class
117         )
118         public final class MyViewModel_HiltModules {
119           private MyViewModel_HiltModules() {
120           }
121 
122           @Module
123           @InstallIn(ViewModelComponent.class)
124           public static abstract class BindsModule {
125             private BindsModule() {}
126 
127             @Binds
128             @IntoMap
129             @StringKey("dagger.hilt.android.test.MyViewModel")
130             @HiltViewModelMap
131             public abstract ViewModel binds(MyViewModel vm);
132           }
133 
134           @Module
135           @InstallIn(ActivityRetainedComponent.class)
136           public static final class KeyModule {
137             private KeyModule() {
138             }
139 
140             @Provides
141             @IntoSet
142             @HiltViewModelMap.KeySet
143             public static String provide() {
144               return "dagger.hilt.android.test.MyViewModel";
145             }
146           }
147         }
148         """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModule")
149 
150     val compilation = compiler()
151       .compile(myViewModel)
152     assertThat(compilation).apply {
153       succeeded()
154       generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules")
155         .containsElementsIn(expected)
156     }
157   }
158 
159   @Test
verifyModule_mixedArgsnull160   fun verifyModule_mixedArgs() {
161     val foo = """
162         package dagger.hilt.android.test;
163 
164         public class Foo { }
165         """.toJFO("dagger.hilt.android.test.Foo")
166 
167     val myViewModel = """
168         package dagger.hilt.android.test;
169 
170         import dagger.hilt.android.lifecycle.HiltViewModel;
171         import androidx.lifecycle.ViewModel;
172         import androidx.lifecycle.SavedStateHandle;
173         import java.lang.String;
174         import javax.inject.Inject;
175 
176         @HiltViewModel
177         class MyViewModel extends ViewModel {
178             @Inject
179             MyViewModel(String s, Foo f, SavedStateHandle savedState, long l) { }
180         }
181         """.toJFO("dagger.hilt.android.test.MyViewModel")
182 
183     val expected = """
184         package dagger.hilt.android.test;
185 
186         $GENERATED_ANNOTATION
187         @OriginatingElement(
188             topLevelClass = MyViewModel.class
189         )
190         public final class MyViewModel_HiltModules {
191           private MyViewModel_HiltModules() {
192           }
193 
194           @Module
195           @InstallIn(ViewModelComponent.class)
196           public static abstract class BindsModule {
197             private BindsModule() {}
198 
199             @Binds
200             @IntoMap
201             @StringKey("dagger.hilt.android.test.MyViewModel")
202             @HiltViewModelMap
203             public abstract ViewModel binds(MyViewModel vm);
204           }
205 
206           @Module
207           @InstallIn(ActivityRetainedComponent.class)
208           public static final class KeyModule {
209             private KeyModule() {
210             }
211 
212             @Provides
213             @IntoSet
214             @HiltViewModelMap.KeySet
215             public static String provide() {
216               return "dagger.hilt.android.test.MyViewModel";
217             }
218           }
219         }
220         """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModule")
221 
222     val compilation = compiler()
223       .compile(foo, myViewModel)
224     assertThat(compilation).apply {
225       succeeded()
226       generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules")
227         .containsElementsIn(expected)
228     }
229   }
230 
231   @Test
verifyModule_mixedAndProviderArgsnull232   fun verifyModule_mixedAndProviderArgs() {
233     val foo = """
234         package dagger.hilt.android.test;
235 
236         public class Foo { }
237         """.toJFO("dagger.hilt.android.test.Foo")
238 
239     val myViewModel = """
240         package dagger.hilt.android.test;
241 
242         import dagger.hilt.android.lifecycle.HiltViewModel;
243         import androidx.lifecycle.ViewModel;
244         import androidx.lifecycle.SavedStateHandle;
245         import java.lang.String;
246         import javax.inject.Inject;
247         import javax.inject.Provider;
248 
249         @HiltViewModel
250         class MyViewModel extends ViewModel {
251             @Inject
252             MyViewModel(String s, Provider<Foo> f, SavedStateHandle savedState) { }
253         }
254         """.toJFO("dagger.hilt.android.test.MyViewModel")
255 
256     val expected = """
257         package dagger.hilt.android.test;
258 
259         $GENERATED_ANNOTATION
260         @OriginatingElement(
261             topLevelClass = MyViewModel.class
262         )
263         public final class MyViewModel_HiltModules {
264           private MyViewModel_HiltModules() {
265           }
266 
267           @Module
268           @InstallIn(ViewModelComponent.class)
269           public static abstract class BindsModule {
270             private BindsModule() {}
271 
272             @Binds
273             @IntoMap
274             @StringKey("dagger.hilt.android.test.MyViewModel")
275             @HiltViewModelMap
276             public abstract ViewModel binds(MyViewModel vm);
277           }
278 
279           @Module
280           @InstallIn(ActivityRetainedComponent.class)
281           public static final class KeyModule {
282             private KeyModule() {
283             }
284 
285             @Provides
286             @IntoSet
287             @HiltViewModelMap.KeySet
288             public static String provide() {
289               return "dagger.hilt.android.test.MyViewModel";
290             }
291           }
292         }
293         """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModules")
294 
295     val compilation = compiler()
296       .compile(foo, myViewModel)
297     assertThat(compilation).apply {
298       succeeded()
299       generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules")
300         .containsElementsIn(expected)
301     }
302   }
303 
304   @Test
verifyModule_qualifiedArgsnull305   fun verifyModule_qualifiedArgs() {
306     val myQualifier = """
307         package dagger.hilt.android.test;
308 
309         import javax.inject.Qualifier;
310 
311         @Qualifier
312         public @interface MyQualifier { }
313         """.toJFO("dagger.hilt.android.test.MyQualifier")
314 
315     val myViewModel = """
316         package dagger.hilt.android.test;
317 
318         import dagger.hilt.android.lifecycle.HiltViewModel;
319         import androidx.lifecycle.ViewModel;
320         import androidx.lifecycle.SavedStateHandle;
321         import java.lang.Long;
322         import java.lang.String;
323         import javax.inject.Inject;
324         import javax.inject.Named;
325         import javax.inject.Provider;
326 
327         @HiltViewModel
328         class MyViewModel extends ViewModel {
329             @Inject
330             MyViewModel(@Named("TheString") String s, @MyQualifier Provider<Long> l,
331                     SavedStateHandle savedState) {
332             }
333         }
334         """.toJFO("dagger.hilt.android.test.MyViewModel")
335 
336     val expected = """
337         package dagger.hilt.android.test;
338 
339         $GENERATED_ANNOTATION
340         @OriginatingElement(
341             topLevelClass = MyViewModel.class
342         )
343         public final class MyViewModel_HiltModules {
344           private MyViewModel_HiltModules() {
345           }
346 
347           @Module
348           @InstallIn(ViewModelComponent.class)
349           public static abstract class BindsModule {
350             private BindsModule() {}
351 
352             @Binds
353             @IntoMap
354             @StringKey("dagger.hilt.android.test.MyViewModel")
355             @HiltViewModelMap
356             public abstract ViewModel binds(MyViewModel vm);
357           }
358 
359           @Module
360           @InstallIn(ActivityRetainedComponent.class)
361           public static final class KeyModule {
362             private KeyModule() {
363             }
364 
365             @Provides
366             @IntoSet
367             @HiltViewModelMap.KeySet
368             public static String provide() {
369               return "dagger.hilt.android.test.MyViewModel";
370             }
371           }
372         }
373         """.toJFO("dagger.hilt.android.test.MyViewModel_HiltModules")
374 
375     val compilation = compiler()
376       .compile(myQualifier, myViewModel)
377     assertThat(compilation).apply {
378       succeeded()
379       generatedSourceFile("dagger.hilt.android.test.MyViewModel_HiltModules")
380         .containsElementsIn(expected)
381     }
382   }
383 
384   @Test
verifyInnerClassnull385   fun verifyInnerClass() {
386     val viewModel = """
387         package dagger.hilt.android.test;
388 
389         import dagger.hilt.android.lifecycle.HiltViewModel;
390         import androidx.lifecycle.ViewModel;
391         import javax.inject.Inject;
392 
393         class Outer {
394             @HiltViewModel
395             static class InnerViewModel extends ViewModel {
396                 @Inject
397                 InnerViewModel() { }
398             }
399         }
400         """.toJFO("dagger.hilt.android.test.Outer")
401 
402     val expectedModule = """
403         package dagger.hilt.android.test;
404 
405         $GENERATED_ANNOTATION
406         @OriginatingElement(
407             topLevelClass = Outer.class
408         )
409         public final class Outer_InnerViewModel_HiltModules {
410           private Outer_InnerViewModel_HiltModules() {
411           }
412 
413           @Module
414           @InstallIn(ViewModelComponent.class)
415           public static abstract class BindsModule {
416             private BindsModule() {}
417 
418             @Binds
419             @IntoMap
420             @StringKey("dagger.hilt.android.test.Outer${'$'}InnerViewModel")
421             @HiltViewModelMap
422             public abstract ViewModel binds(Outer.InnerViewModel vm);
423           }
424 
425           @Module
426           @InstallIn(ActivityRetainedComponent.class)
427           public static final class KeyModule {
428             private KeyModule() {
429             }
430 
431             @Provides
432             @IntoSet
433             @HiltViewModelMap.KeySet
434             public static String provide() {
435               return "dagger.hilt.android.test.Outer${'$'}InnerViewModel";
436             }
437           }
438         }
439         """.toJFO("dagger.hilt.android.test.Outer_InnerViewModel_HiltModules")
440 
441     val compilation = compiler()
442       .compile(viewModel)
443     assertThat(compilation).apply {
444       succeeded()
445       generatedSourceFile("dagger.hilt.android.test.Outer_InnerViewModel_HiltModules")
446         .containsElementsIn(expectedModule)
447     }
448   }
449 }
450