• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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