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.internal.codegen; 18 19 import androidx.room.compiler.processing.util.Source; 20 import com.google.common.collect.ImmutableList; 21 import dagger.testing.compile.CompilerTests; 22 import dagger.testing.golden.GoldenFileRule; 23 import org.junit.Rule; 24 import org.junit.Test; 25 import org.junit.runner.RunWith; 26 import org.junit.runners.Parameterized; 27 import org.junit.runners.Parameterized.Parameters; 28 29 @RunWith(Parameterized.class) 30 public class MapRequestRepresentationWithGuavaTest { 31 @Parameters(name = "{0}") parameters()32 public static ImmutableList<Object[]> parameters() { 33 return CompilerMode.TEST_PARAMETERS; 34 } 35 36 @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); 37 38 private final CompilerMode compilerMode; 39 MapRequestRepresentationWithGuavaTest(CompilerMode compilerMode)40 public MapRequestRepresentationWithGuavaTest(CompilerMode compilerMode) { 41 this.compilerMode = compilerMode; 42 } 43 44 @Test mapBindings()45 public void mapBindings() throws Exception { 46 Source mapModuleFile = 47 CompilerTests.javaSource( 48 "test.MapModule", 49 "package test;", 50 "", 51 "import dagger.Module;", 52 "import dagger.Provides;", 53 "import dagger.multibindings.IntKey;", 54 "import dagger.multibindings.IntoMap;", 55 "import dagger.multibindings.LongKey;", 56 "import dagger.multibindings.Multibinds;", 57 "import java.util.Map;", 58 "", 59 "@Module", 60 "interface MapModule {", 61 " @Multibinds Map<String, String> stringMap();", 62 " @Provides @IntoMap @IntKey(0) static int provideInt() { return 0; }", 63 " @Provides @IntoMap @LongKey(0) static long provideLong0() { return 0; }", 64 " @Provides @IntoMap @LongKey(1) static long provideLong1() { return 1; }", 65 " @Provides @IntoMap @LongKey(2) static long provideLong2() { return 2; }", 66 "}"); 67 Source subcomponentModuleFile = 68 CompilerTests.javaSource( 69 "test.SubcomponentMapModule", 70 "package test;", 71 "", 72 "import dagger.Module;", 73 "import dagger.Provides;", 74 "import dagger.multibindings.IntKey;", 75 "import dagger.multibindings.IntoMap;", 76 "import dagger.multibindings.LongKey;", 77 "import dagger.multibindings.Multibinds;", 78 "import java.util.Map;", 79 "", 80 "@Module", 81 "interface SubcomponentMapModule {", 82 " @Provides @IntoMap @LongKey(3) static long provideLong3() { return 3; }", 83 " @Provides @IntoMap @LongKey(4) static long provideLong4() { return 4; }", 84 " @Provides @IntoMap @LongKey(5) static long provideLong5() { return 5; }", 85 "}"); 86 Source componentFile = 87 CompilerTests.javaSource( 88 "test.TestComponent", 89 "package test;", 90 "", 91 "import dagger.Component;", 92 "import java.util.Map;", 93 "import javax.inject.Provider;", 94 "", 95 "@Component(modules = MapModule.class)", 96 "interface TestComponent {", 97 " Map<String, String> strings();", 98 " Map<String, Provider<String>> providerStrings();", 99 "", 100 " Map<Integer, Integer> ints();", 101 " Map<Integer, Provider<Integer>> providerInts();", 102 " Map<Long, Long> longs();", 103 " Map<Long, Provider<Long>> providerLongs();", 104 "", 105 " Sub sub();", 106 "}"); 107 Source subcomponent = 108 CompilerTests.javaSource( 109 "test.Sub", 110 "package test;", 111 "", 112 "import dagger.Subcomponent;", 113 "import java.util.Map;", 114 "import javax.inject.Provider;", 115 "", 116 "@Subcomponent(modules = SubcomponentMapModule.class)", 117 "interface Sub {", 118 " Map<Long, Long> longs();", 119 " Map<Long, Provider<Long>> providerLongs();", 120 "}"); 121 CompilerTests.daggerCompiler(mapModuleFile, componentFile, subcomponentModuleFile, subcomponent) 122 .withProcessingOptions(compilerMode.processorOptions()) 123 .compile( 124 subject -> { 125 subject.hasErrorCount(0); 126 subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 127 }); 128 } 129 130 @Test inaccessible()131 public void inaccessible() throws Exception { 132 Source inaccessible = 133 CompilerTests.javaSource( 134 "other.Inaccessible", "package other;", "", "class Inaccessible {}"); 135 Source usesInaccessible = 136 CompilerTests.javaSource( 137 "other.UsesInaccessible", 138 "package other;", 139 "", 140 "import java.util.Map;", 141 "import javax.inject.Inject;", 142 "", 143 "public class UsesInaccessible {", 144 " @Inject UsesInaccessible(Map<Integer, Inaccessible> map) {}", 145 "}"); 146 147 Source module = 148 CompilerTests.javaSource( 149 "other.TestModule", 150 "package other;", 151 "", 152 "import dagger.Module;", 153 "import dagger.multibindings.Multibinds;", 154 "import java.util.Map;", 155 "", 156 "@Module", 157 "public abstract class TestModule {", 158 " @Multibinds abstract Map<Integer, Inaccessible> ints();", 159 "}"); 160 Source componentFile = 161 CompilerTests.javaSource( 162 "test.TestComponent", 163 "package test;", 164 "", 165 "import dagger.Component;", 166 "import java.util.Map;", 167 "import javax.inject.Provider;", 168 "import other.TestModule;", 169 "import other.UsesInaccessible;", 170 "", 171 "@Component(modules = TestModule.class)", 172 "interface TestComponent {", 173 " UsesInaccessible usesInaccessible();", 174 "}"); 175 176 CompilerTests.daggerCompiler(module, inaccessible, usesInaccessible, componentFile) 177 .withProcessingOptions(compilerMode.processorOptions()) 178 .compile( 179 subject -> { 180 subject.hasErrorCount(0); 181 subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 182 }); 183 } 184 185 @Test subcomponentOmitsInheritedBindings()186 public void subcomponentOmitsInheritedBindings() throws Exception { 187 Source parent = 188 CompilerTests.javaSource( 189 "test.Parent", 190 "package test;", 191 "", 192 "import dagger.Component;", 193 "", 194 "@Component(modules = ParentModule.class)", 195 "interface Parent {", 196 " Child child();", 197 "}"); 198 Source parentModule = 199 CompilerTests.javaSource( 200 "test.ParentModule", 201 "package test;", 202 "", 203 "import dagger.Module;", 204 "import dagger.Provides;", 205 "import dagger.multibindings.IntoMap;", 206 "import dagger.multibindings.StringKey;", 207 "", 208 "@Module", 209 "class ParentModule {", 210 " @Provides @IntoMap @StringKey(\"parent key\") Object parentKeyObject() {", 211 " return \"parent value\";", 212 " }", 213 "}"); 214 Source child = 215 CompilerTests.javaSource( 216 "test.Child", 217 "package test;", 218 "", 219 "import dagger.Subcomponent;", 220 "import java.util.Map;", 221 "", 222 "@Subcomponent", 223 "interface Child {", 224 " Map<String, Object> objectMap();", 225 "}"); 226 227 CompilerTests.daggerCompiler(parent, parentModule, child) 228 .withProcessingOptions(compilerMode.processorOptions()) 229 .compile( 230 subject -> { 231 subject.hasErrorCount(0); 232 subject.generatedSource(goldenFileRule.goldenSource("test/DaggerParent")); 233 }); 234 } 235 236 @Test productionComponents()237 public void productionComponents() throws Exception { 238 Source mapModuleFile = 239 CompilerTests.javaSource( 240 "test.MapModule", 241 "package test;", 242 "", 243 "import dagger.Module;", 244 "import dagger.multibindings.Multibinds;", 245 "import java.util.Map;", 246 "", 247 "@Module", 248 "interface MapModule {", 249 " @Multibinds Map<String, String> stringMap();", 250 "}"); 251 Source componentFile = 252 CompilerTests.javaSource( 253 "test.TestComponent", 254 "package test;", 255 "", 256 "import com.google.common.util.concurrent.ListenableFuture;", 257 "import dagger.producers.ProductionComponent;", 258 "import java.util.Map;", 259 "", 260 "@ProductionComponent(modules = MapModule.class)", 261 "interface TestComponent {", 262 " ListenableFuture<Map<String, String>> stringMap();", 263 "}"); 264 265 CompilerTests.daggerCompiler(mapModuleFile, componentFile) 266 .withProcessingOptions(compilerMode.processorOptions()) 267 .compile( 268 subject -> { 269 subject.hasErrorCount(0); 270 subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); 271 }); 272 } 273 } 274