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 static com.google.testing.compile.CompilationSubject.assertThat; 20 import static dagger.internal.codegen.Compilers.CLASS_PATH_WITHOUT_GUAVA_OPTION; 21 import static dagger.internal.codegen.Compilers.compilerWithOptions; 22 23 import com.google.testing.compile.Compilation; 24 import com.google.testing.compile.Compiler; 25 import com.google.testing.compile.JavaFileObjects; 26 import dagger.testing.golden.GoldenFileRule; 27 import java.util.Collection; 28 import javax.tools.JavaFileObject; 29 import org.junit.Rule; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.junit.runners.Parameterized; 33 import org.junit.runners.Parameterized.Parameters; 34 35 @RunWith(Parameterized.class) 36 public class SetBindingRequestFulfillmentTest { 37 @Parameters(name = "{0}") parameters()38 public static Collection<Object[]> parameters() { 39 return CompilerMode.TEST_PARAMETERS; 40 } 41 42 @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); 43 44 private final CompilerMode compilerMode; 45 SetBindingRequestFulfillmentTest(CompilerMode compilerMode)46 public SetBindingRequestFulfillmentTest(CompilerMode compilerMode) { 47 this.compilerMode = compilerMode; 48 } 49 50 @Test setBindings()51 public void setBindings() throws Exception { 52 JavaFileObject emptySetModuleFile = JavaFileObjects.forSourceLines("test.EmptySetModule", 53 "package test;", 54 "", 55 "import dagger.Module;", 56 "import dagger.Provides;", 57 "import dagger.multibindings.ElementsIntoSet;", 58 "import dagger.multibindings.Multibinds;", 59 "import java.util.Collections;", 60 "import java.util.Set;", 61 "", 62 "@Module", 63 "abstract class EmptySetModule {", 64 " @Multibinds abstract Set<Object> objects();", 65 "", 66 " @Provides @ElementsIntoSet", 67 " static Set<String> emptySet() { ", 68 " return Collections.emptySet();", 69 " }", 70 "}"); 71 JavaFileObject setModuleFile = JavaFileObjects.forSourceLines("test.SetModule", 72 "package test;", 73 "", 74 "import dagger.Module;", 75 "import dagger.Provides;", 76 "import dagger.multibindings.IntoSet;", 77 "", 78 "@Module", 79 "final class SetModule {", 80 " @Provides @IntoSet static String string() { return \"\"; }", 81 "}"); 82 JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent", 83 "package test;", 84 "", 85 "import dagger.Component;", 86 "import java.util.Set;", 87 "import javax.inject.Provider;", 88 "", 89 "@Component(modules = {EmptySetModule.class, SetModule.class})", 90 "interface TestComponent {", 91 " Set<String> strings();", 92 " Set<Object> objects();", 93 "}"); 94 95 Compilation compilation = 96 daggerCompilerWithoutGuava().compile(emptySetModuleFile, setModuleFile, componentFile); 97 assertThat(compilation).succeeded(); 98 assertThat(compilation) 99 .generatedSourceFile("test.DaggerTestComponent") 100 .hasSourceEquivalentTo(goldenFileRule.goldenFile("test.DaggerTestComponent")); 101 } 102 103 @Test inaccessible()104 public void inaccessible() throws Exception { 105 JavaFileObject inaccessible = 106 JavaFileObjects.forSourceLines( 107 "other.Inaccessible", 108 "package other;", 109 "", 110 "class Inaccessible {}"); 111 JavaFileObject inaccessible2 = 112 JavaFileObjects.forSourceLines( 113 "other.Inaccessible2", 114 "package other;", 115 "", 116 "class Inaccessible2 {}"); 117 JavaFileObject usesInaccessible = 118 JavaFileObjects.forSourceLines( 119 "other.UsesInaccessible", 120 "package other;", 121 "", 122 "import java.util.Set;", 123 "import javax.inject.Inject;", 124 "", 125 "public class UsesInaccessible {", 126 " @Inject UsesInaccessible(Set<Inaccessible> set1, Set<Inaccessible2> set2) {}", 127 "}"); 128 129 JavaFileObject module = 130 JavaFileObjects.forSourceLines( 131 "other.TestModule", 132 "package other;", 133 "", 134 "import dagger.Module;", 135 "import dagger.Provides;", 136 "import dagger.multibindings.ElementsIntoSet;", 137 "import dagger.multibindings.Multibinds;", 138 "import java.util.Collections;", 139 "import java.util.Set;", 140 "", 141 "@Module", 142 "public abstract class TestModule {", 143 " @Multibinds abstract Set<Inaccessible> objects();", 144 "", 145 " @Provides @ElementsIntoSet", 146 " static Set<Inaccessible2> emptySet() { ", 147 " return Collections.emptySet();", 148 " }", 149 "}"); 150 JavaFileObject componentFile = 151 JavaFileObjects.forSourceLines( 152 "test.TestComponent", 153 "package test;", 154 "", 155 "import dagger.Component;", 156 "import java.util.Set;", 157 "import javax.inject.Provider;", 158 "import other.TestModule;", 159 "import other.UsesInaccessible;", 160 "", 161 "@Component(modules = TestModule.class)", 162 "interface TestComponent {", 163 " UsesInaccessible usesInaccessible();", 164 "}"); 165 166 Compilation compilation = 167 daggerCompilerWithoutGuava() 168 .compile(module, inaccessible, inaccessible2, usesInaccessible, componentFile); 169 assertThat(compilation).succeeded(); 170 assertThat(compilation) 171 .generatedSourceFile("test.DaggerTestComponent") 172 .hasSourceEquivalentTo(goldenFileRule.goldenFile("test.DaggerTestComponent")); 173 } 174 175 @Test subcomponentOmitsInheritedBindings()176 public void subcomponentOmitsInheritedBindings() throws Exception { 177 JavaFileObject parent = 178 JavaFileObjects.forSourceLines( 179 "test.Parent", 180 "package test;", 181 "", 182 "import dagger.Component;", 183 "", 184 "@Component(modules = ParentModule.class)", 185 "interface Parent {", 186 " Child child();", 187 "}"); 188 JavaFileObject parentModule = 189 JavaFileObjects.forSourceLines( 190 "test.ParentModule", 191 "package test;", 192 "", 193 "import dagger.Module;", 194 "import dagger.Provides;", 195 "import dagger.multibindings.IntoSet;", 196 "import dagger.multibindings.StringKey;", 197 "", 198 "@Module", 199 "class ParentModule {", 200 " @Provides @IntoSet static Object parentObject() {", 201 " return \"parent object\";", 202 " }", 203 "}"); 204 JavaFileObject child = 205 JavaFileObjects.forSourceLines( 206 "test.Child", 207 "package test;", 208 "", 209 "import dagger.Subcomponent;", 210 "import java.util.Set;", 211 "", 212 "@Subcomponent", 213 "interface Child {", 214 " Set<Object> objectSet();", 215 "}"); 216 217 Compilation compilation = daggerCompilerWithoutGuava().compile(parent, parentModule, child); 218 assertThat(compilation).succeeded(); 219 assertThat(compilation) 220 .generatedSourceFile("test.DaggerParent") 221 .hasSourceEquivalentTo(goldenFileRule.goldenFile("test.DaggerTestComponent")); 222 } 223 daggerCompilerWithoutGuava()224 private Compiler daggerCompilerWithoutGuava() { 225 return compilerWithOptions(compilerMode.javacopts()) 226 .withClasspath(CLASS_PATH_WITHOUT_GUAVA_OPTION); 227 } 228 } 229