1 /* 2 * Copyright (C) 2017 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.android.processor; 18 19 import androidx.room.compiler.processing.util.Source; 20 import dagger.testing.compile.CompilerTests; 21 import dagger.testing.compile.CompilerTests.DaggerCompiler; 22 import org.junit.Test; 23 import org.junit.runner.RunWith; 24 import org.junit.runners.JUnit4; 25 26 @RunWith(JUnit4.class) 27 public final class ContributesAndroidInjectorTest { 28 private static final Source TEST_ACTIVITY = 29 CompilerTests.javaSource( 30 "test.TestActivity", 31 "package test;", 32 "", 33 "import android.app.Activity;", 34 "", 35 "class TestActivity extends Activity {}"); 36 37 @Test notAbstract()38 public void notAbstract() { 39 Source module = 40 CompilerTests.javaSource( 41 "test.TestModule", 42 "package test;", 43 "", 44 "import dagger.Module;", 45 "import dagger.android.ContributesAndroidInjector;", 46 "", 47 "@Module", 48 "abstract class TestModule {", 49 " @ContributesAndroidInjector", 50 " static TestActivity test() {", 51 " return null;", 52 " }", 53 "}"); 54 55 compile(module, TEST_ACTIVITY) 56 .compile( 57 subject -> { 58 subject.compilationDidFail(); 59 subject.hasErrorContaining("must be abstract").onLineContaining("test()"); 60 }); 61 } 62 63 @Test hasParameters()64 public void hasParameters() { 65 Source otherActivity = 66 CompilerTests.javaSource( 67 "test.OtherActivity", 68 "package test;", 69 "", 70 "import android.app.Activity;", 71 "", 72 "class OtherActivity extends Activity {}"); 73 Source module = 74 CompilerTests.javaSource( 75 "test.TestModule", 76 "package test;", 77 "", 78 "import dagger.Module;", 79 "import dagger.android.ContributesAndroidInjector;", 80 "", 81 "@Module", 82 "abstract class TestModule {", 83 " @ContributesAndroidInjector", 84 " abstract TestActivity oneParam(TestActivity one);", 85 "", 86 " @ContributesAndroidInjector", 87 " abstract OtherActivity manyParams(OtherActivity two, Object o);", 88 "}"); 89 90 compile(module, TEST_ACTIVITY, otherActivity) 91 .compile( 92 subject -> { 93 subject.compilationDidFail(); 94 subject.hasErrorContaining("cannot have parameters").onLineContaining("oneParam("); 95 subject.hasErrorContaining("cannot have parameters").onLineContaining("manyParams("); 96 }); 97 } 98 99 @Test notInAModule()100 public void notInAModule() { 101 Source randomFile = 102 CompilerTests.javaSource( 103 "test.RandomFile", 104 "package test;", 105 "", 106 "import dagger.android.ContributesAndroidInjector;", 107 "", 108 "abstract class RandomFile {", 109 " @ContributesAndroidInjector", 110 " abstract TestActivity test() {}", 111 "}"); 112 113 compile(randomFile, TEST_ACTIVITY) 114 .compile( 115 subject -> { 116 subject.compilationDidFail(); 117 subject.hasErrorContaining("must be in a @Module").onLineContaining("test()"); 118 }); 119 } 120 121 @Test parameterizedReturnType()122 public void parameterizedReturnType() { 123 Source parameterizedActivity = 124 CompilerTests.javaSource( 125 "test.ParameterizedActivity", 126 "package test;", 127 "", 128 "import android.app.Activity;", 129 "", 130 "class ParameterizedActivity<T> extends Activity {}"); 131 Source module = 132 CompilerTests.javaSource( 133 "test.TestModule", 134 "package test;", 135 "", 136 "import dagger.Module;", 137 "import dagger.android.ContributesAndroidInjector;", 138 "", 139 "@Module", 140 "abstract class TestModule {", 141 " @ContributesAndroidInjector", 142 " abstract <T> ParameterizedActivity<T> test();", 143 "}"); 144 145 compile(module, TEST_ACTIVITY, parameterizedActivity) 146 .compile( 147 subject -> { 148 subject.compilationDidFail(); 149 subject 150 .hasErrorContaining("cannot return parameterized types") 151 .onLineContaining("test()"); 152 }); 153 } 154 155 @Test moduleIsntModule()156 public void moduleIsntModule() { 157 Source module = 158 CompilerTests.javaSource( 159 "test.TestModule", 160 "package test;", 161 "", 162 "import dagger.Module;", 163 "import dagger.android.ContributesAndroidInjector;", 164 "", 165 "@Module", 166 "abstract class TestModule {", 167 " @ContributesAndroidInjector(modules = android.content.Intent.class)", 168 " abstract TestActivity test();", 169 "}"); 170 171 compile(module, TEST_ACTIVITY) 172 .compile( 173 subject -> { 174 subject.compilationDidFail(); 175 subject 176 .hasErrorContaining("Intent is not a @Module") 177 .onLineContaining("modules = android.content.Intent.class"); 178 }); 179 } 180 181 @Test hasQualifier()182 public void hasQualifier() { 183 Source module = 184 CompilerTests.javaSource( 185 "test.TestModule", 186 "package test;", 187 "", 188 "import dagger.Module;", 189 "import dagger.android.ContributesAndroidInjector;", 190 "import javax.inject.Qualifier;", 191 "", 192 "@Module", 193 "abstract class TestModule {", 194 " @Qualifier @interface AndroidQualifier {}", 195 "", 196 " @AndroidQualifier", 197 " @ContributesAndroidInjector", 198 " abstract TestActivity test();", 199 "}"); 200 201 compile(module, TEST_ACTIVITY) 202 .compile( 203 subject -> { 204 subject.compilationDidFail(); 205 subject 206 .hasErrorContaining("@ContributesAndroidInjector methods cannot have qualifiers") 207 .onLineContaining("@AndroidQualifier"); 208 }); 209 } 210 compile(Source... sources)211 private static DaggerCompiler compile(Source... sources) { 212 return CompilerTests.daggerCompiler(sources) 213 .withAdditionalJavacProcessors(new AndroidProcessor()) 214 .withAdditionalKspProcessors(new KspAndroidProcessor.Provider()); 215 } 216 } 217