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.CompilerMode.DEFAULT_MODE; 21 import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE; 22 import static dagger.internal.codegen.Compilers.compilerWithOptions; 23 24 import com.google.testing.compile.Compilation; 25 import com.google.testing.compile.JavaFileObjects; 26 import java.util.Collection; 27 import javax.tools.JavaFileObject; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.junit.runners.Parameterized; 31 import org.junit.runners.Parameterized.Parameters; 32 33 @RunWith(Parameterized.class) 34 public class OptionalBindingRequestFulfillmentTest { 35 @Parameters(name = "{0}") parameters()36 public static Collection<Object[]> parameters() { 37 return CompilerMode.TEST_PARAMETERS; 38 } 39 40 private final CompilerMode compilerMode; 41 OptionalBindingRequestFulfillmentTest(CompilerMode compilerMode)42 public OptionalBindingRequestFulfillmentTest(CompilerMode compilerMode) { 43 this.compilerMode = compilerMode; 44 } 45 46 @Test inlinedOptionalBindings()47 public void inlinedOptionalBindings() { 48 JavaFileObject module = 49 JavaFileObjects.forSourceLines( 50 "test.TestModule", 51 "package test;", 52 "", 53 "import dagger.Module;", 54 "import dagger.BindsOptionalOf;", 55 "import other.Maybe;", 56 "import other.DefinitelyNot;", 57 "", 58 "@Module", 59 "interface TestModule {", 60 " @BindsOptionalOf Maybe maybe();", 61 " @BindsOptionalOf DefinitelyNot definitelyNot();", 62 "}"); 63 JavaFileObject maybe = 64 JavaFileObjects.forSourceLines( 65 "other.Maybe", 66 "package other;", 67 "", 68 "import dagger.Module;", 69 "import dagger.Provides;", 70 "", 71 "public class Maybe {", 72 " @Module", 73 " public static class MaybeModule {", 74 " @Provides static Maybe provideMaybe() { return new Maybe(); }", 75 " }", 76 "}"); 77 JavaFileObject definitelyNot = 78 JavaFileObjects.forSourceLines( 79 "other.DefinitelyNot", 80 "package other;", 81 "", 82 "public class DefinitelyNot {}"); 83 84 JavaFileObject component = 85 JavaFileObjects.forSourceLines( 86 "test.TestComponent", 87 "package test;", 88 "", 89 "import com.google.common.base.Optional;", 90 "import dagger.Component;", 91 "import dagger.Lazy;", 92 "import javax.inject.Provider;", 93 "import other.Maybe;", 94 "import other.DefinitelyNot;", 95 "", 96 "@Component(modules = {TestModule.class, Maybe.MaybeModule.class})", 97 "interface TestComponent {", 98 " Optional<Maybe> maybe();", 99 " Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe();", 100 " Optional<DefinitelyNot> definitelyNot();", 101 " Optional<Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot();", 102 "}"); 103 104 JavaFileObject generatedComponent = 105 compilerMode 106 .javaFileBuilder("test.DaggerTestComponent") 107 .addLines( 108 "package test;", 109 "", 110 GeneratedLines.generatedAnnotations(), 111 "final class DaggerTestComponent implements TestComponent {") 112 .addLinesIn( 113 FAST_INIT_MODE, 114 " private Provider<Maybe> provideMaybeProvider;", 115 "", 116 " @SuppressWarnings(\"unchecked\")", 117 " private void initialize() {", 118 " this.provideMaybeProvider = new SwitchingProvider<>(testComponent, 0);", 119 " }") 120 .addLinesIn( 121 DEFAULT_MODE, 122 " @Override", 123 " public Optional<Maybe> maybe() {", 124 " return Optional.of(Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe());", 125 " }") 126 .addLinesIn( 127 FAST_INIT_MODE, 128 " @Override", 129 " public Optional<Maybe> maybe() {", 130 " return Optional.of(provideMaybeProvider.get());", 131 " }") 132 .addLinesIn( 133 DEFAULT_MODE, 134 " @Override", 135 " public Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() {", 136 " return Optional.of(ProviderOfLazy.create(", 137 " Maybe_MaybeModule_ProvideMaybeFactory.create()));", 138 " }") 139 .addLinesIn( 140 FAST_INIT_MODE, 141 " @Override", 142 " public Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() {", 143 " return Optional.of(ProviderOfLazy.create(provideMaybeProvider));", 144 " }") 145 .addLines( 146 " @Override", 147 " public Optional<DefinitelyNot> definitelyNot() {", 148 " return Optional.<DefinitelyNot>absent();", 149 " }", 150 "", 151 " @Override", 152 " public Optional<Provider<Lazy<DefinitelyNot>>>", 153 " providerOfLazyOfDefinitelyNot() {", 154 " return Optional.<Provider<Lazy<DefinitelyNot>>>absent();", 155 " }") 156 .addLinesIn( 157 FAST_INIT_MODE, 158 " private static final class SwitchingProvider<T> implements Provider<T> {", 159 " @SuppressWarnings(\"unchecked\")", 160 " @Override", 161 " public T get() {", 162 " switch (id) {", 163 " case 0: return (T) Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe();", 164 " default: throw new AssertionError(id);", 165 " }", 166 " }", 167 " }", 168 "}") 169 .build(); 170 Compilation compilation = 171 compilerWithOptions( 172 compilerMode 173 , CompilerMode.JAVA7 174 ) 175 .compile(module, maybe, definitelyNot, component); 176 assertThat(compilation).succeeded(); 177 assertThat(compilation) 178 .generatedSourceFile("test.DaggerTestComponent") 179 .containsElementsIn(generatedComponent); 180 } 181 182 @Test requestForFuture()183 public void requestForFuture() { 184 JavaFileObject module = 185 JavaFileObjects.forSourceLines( 186 "test.TestModule", 187 "package test;", 188 "", 189 "import dagger.Module;", 190 "import dagger.BindsOptionalOf;", 191 "import other.Maybe;", 192 "import other.DefinitelyNot;", 193 "", 194 "@Module", 195 "interface TestModule {", 196 " @BindsOptionalOf Maybe maybe();", 197 " @BindsOptionalOf DefinitelyNot definitelyNot();", 198 "}"); 199 JavaFileObject maybe = 200 JavaFileObjects.forSourceLines( 201 "other.Maybe", 202 "package other;", 203 "", 204 "import dagger.Module;", 205 "import dagger.Provides;", 206 "", 207 "public class Maybe {", 208 " @Module", 209 " public static class MaybeModule {", 210 " @Provides static Maybe provideMaybe() { return new Maybe(); }", 211 " }", 212 "}"); 213 JavaFileObject definitelyNot = 214 JavaFileObjects.forSourceLines( 215 "other.DefinitelyNot", 216 "package other;", 217 "", 218 "public class DefinitelyNot {}"); 219 220 JavaFileObject component = 221 JavaFileObjects.forSourceLines( 222 "test.TestComponent", 223 "package test;", 224 "", 225 "import com.google.common.base.Optional;", 226 "import com.google.common.util.concurrent.ListenableFuture;", 227 "import dagger.producers.ProductionComponent;", 228 "import javax.inject.Provider;", 229 "import other.Maybe;", 230 "import other.DefinitelyNot;", 231 "", 232 "@ProductionComponent(modules = {TestModule.class, Maybe.MaybeModule.class})", 233 "interface TestComponent {", 234 " ListenableFuture<Optional<Maybe>> maybe();", 235 " ListenableFuture<Optional<DefinitelyNot>> definitelyNot();", 236 "}"); 237 JavaFileObject generatedComponent = 238 JavaFileObjects.forSourceLines( 239 "test.DaggerTestComponent", 240 "package test;", 241 "", 242 "import com.google.common.base.Optional;", 243 "import dagger.producers.internal.CancellationListener;", 244 "", 245 GeneratedLines.generatedAnnotations(), 246 "final class DaggerTestComponent implements TestComponent, CancellationListener {", 247 " @Override", 248 " public ListenableFuture<Optional<Maybe>> maybe() {", 249 " return Futures.immediateFuture(", 250 " Optional.of(Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe()));", 251 " }", 252 "", 253 " @Override", 254 " public ListenableFuture<Optional<DefinitelyNot>> definitelyNot() {", 255 " return Futures.immediateFuture(Optional.<DefinitelyNot>absent());", 256 " }", 257 "", 258 " @Override", 259 " public void onProducerFutureCancelled(boolean mayInterruptIfRunning) {}", 260 "}"); 261 262 Compilation compilation = 263 compilerWithOptions( 264 compilerMode 265 , CompilerMode.JAVA7 266 ) 267 .compile(module, maybe, definitelyNot, component); 268 assertThat(compilation).succeeded(); 269 assertThat(compilation) 270 .generatedSourceFile("test.DaggerTestComponent") 271 .containsElementsIn(generatedComponent); 272 } 273 } 274