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 ViewModelProcessorTest { 27 compilernull28 private fun compiler(): Compiler = Compiler.javac().withProcessors(ViewModelProcessor()) 29 30 @Test 31 fun validViewModel() { 32 val myViewModel = """ 33 package dagger.hilt.android.test; 34 35 import androidx.lifecycle.ViewModel; 36 import dagger.hilt.android.lifecycle.HiltViewModel; 37 import javax.inject.Inject; 38 39 @HiltViewModel 40 class MyViewModel extends ViewModel { 41 @Inject MyViewModel() { } 42 } 43 """.toJFO("dagger.hilt.android.test.MyViewModel") 44 45 val compilation = compiler().compile(myViewModel) 46 assertThat(compilation).succeeded() 47 } 48 49 @Test verifyEnclosingElementExtendsViewModelnull50 fun verifyEnclosingElementExtendsViewModel() { 51 val myViewModel = """ 52 package dagger.hilt.android.test; 53 54 import dagger.hilt.android.lifecycle.HiltViewModel; 55 import javax.inject.Inject; 56 57 @HiltViewModel 58 class MyViewModel { 59 @Inject 60 MyViewModel() { } 61 } 62 """.toJFO("dagger.hilt.android.test.MyViewModel") 63 64 val compilation = compiler().compile(myViewModel) 65 assertThat(compilation).apply { 66 failed() 67 hadErrorCount(1) 68 hadErrorContainingMatch( 69 "@HiltViewModel is only supported on types that subclass androidx.lifecycle.ViewModel." 70 ) 71 } 72 } 73 74 @Test verifySingleAnnotatedConstructornull75 fun verifySingleAnnotatedConstructor() { 76 val myViewModel = """ 77 package dagger.hilt.android.test; 78 79 import androidx.lifecycle.ViewModel; 80 import dagger.hilt.android.lifecycle.HiltViewModel; 81 import javax.inject.Inject; 82 83 @HiltViewModel 84 class MyViewModel extends ViewModel { 85 @Inject 86 MyViewModel() { } 87 88 @Inject 89 MyViewModel(String s) { } 90 } 91 """.toJFO("dagger.hilt.android.test.MyViewModel") 92 93 val compilation = compiler().compile(myViewModel) 94 assertThat(compilation).apply { 95 failed() 96 hadErrorCount(1) 97 hadErrorContainingMatch( 98 "@HiltViewModel annotated class should contain exactly one @Inject annotated constructor." 99 ) 100 } 101 } 102 103 @Test verifyNonPrivateConstructornull104 fun verifyNonPrivateConstructor() { 105 val myViewModel = """ 106 package dagger.hilt.android.test; 107 108 import androidx.lifecycle.ViewModel; 109 import dagger.hilt.android.lifecycle.HiltViewModel; 110 import javax.inject.Inject; 111 112 @HiltViewModel 113 class MyViewModel extends ViewModel { 114 @Inject 115 private MyViewModel() { } 116 } 117 """.toJFO("dagger.hilt.android.test.MyViewModel") 118 119 val compilation = compiler().compile(myViewModel) 120 assertThat(compilation).apply { 121 failed() 122 hadErrorCount(1) 123 hadErrorContainingMatch( 124 "@Inject annotated constructors must not be " + 125 "private." 126 ) 127 } 128 } 129 130 @Test verifyInnerClassIsStaticnull131 fun verifyInnerClassIsStatic() { 132 val myViewModel = """ 133 package dagger.hilt.android.test; 134 135 import androidx.lifecycle.ViewModel; 136 import dagger.hilt.android.lifecycle.HiltViewModel; 137 import javax.inject.Inject; 138 139 class Outer { 140 @HiltViewModel 141 class MyViewModel extends ViewModel { 142 @Inject 143 MyViewModel() { } 144 } 145 } 146 """.toJFO("dagger.hilt.android.test.Outer") 147 148 val compilation = compiler().compile(myViewModel) 149 assertThat(compilation).apply { 150 failed() 151 hadErrorCount(1) 152 hadErrorContainingMatch( 153 "@HiltViewModel may only be used on inner classes if they are static." 154 ) 155 } 156 } 157 158 @Test verifyNoScopeAnnotationnull159 fun verifyNoScopeAnnotation() { 160 val myViewModel = """ 161 package dagger.hilt.android.test; 162 163 import androidx.lifecycle.ViewModel; 164 import dagger.hilt.android.lifecycle.HiltViewModel; 165 import javax.inject.Inject; 166 import javax.inject.Singleton; 167 168 @Singleton 169 @HiltViewModel 170 class MyViewModel extends ViewModel { 171 @Inject MyViewModel() { } 172 } 173 """.toJFO("dagger.hilt.android.test.MyViewModel") 174 175 val compilation = compiler().compile(myViewModel) 176 assertThat(compilation).apply { 177 failed() 178 hadErrorCount(1) 179 hadErrorContainingMatch( 180 "@HiltViewModel classes should not be scoped. Found: @javax.inject.Singleton" 181 ) 182 } 183 } 184 } 185