• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.functional.producers;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.fail;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.Mockito.inOrder;
23 import static org.mockito.Mockito.when;
24 
25 import com.google.common.util.concurrent.ListenableFuture;
26 import com.google.common.util.concurrent.MoreExecutors;
27 import com.google.common.util.concurrent.SettableFuture;
28 import dagger.internal.Provider;
29 import dagger.producers.Producer;
30 import dagger.producers.internal.AbstractProducer;
31 import dagger.producers.internal.CancellableProducer;
32 import dagger.producers.monitoring.ProducerMonitor;
33 import dagger.producers.monitoring.ProducerToken;
34 import dagger.producers.monitoring.ProductionComponentMonitor;
35 import java.util.concurrent.ExecutionException;
36 import java.util.concurrent.Executor;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.junit.runners.JUnit4;
41 import org.mockito.InOrder;
42 import org.mockito.Mock;
43 import org.mockito.Mockito;
44 import org.mockito.MockitoAnnotations;
45 
46 @RunWith(JUnit4.class)
47 public class ProducerFactoryTest {
48   @Mock private ProductionComponentMonitor componentMonitor;
49   private ProducerMonitor monitor;
50   private Provider<Executor> executorProvider;
51   private Provider<ProductionComponentMonitor> componentMonitorProvider;
52 
53   @Before
setUpMocks()54   public void setUpMocks() {
55     MockitoAnnotations.initMocks(this);
56     monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS);
57     when(componentMonitor.producerMonitorFor(any(ProducerToken.class))).thenReturn(monitor);
58     executorProvider =
59         new Provider<Executor>() {
60           @Override
61           public Executor get() {
62             return MoreExecutors.directExecutor();
63           }
64         };
65     componentMonitorProvider =
66         new Provider<ProductionComponentMonitor>() {
67           @Override
68           public ProductionComponentMonitor get() {
69             return componentMonitor;
70           }
71         };
72   }
73 
74   @Test
noArgMethod()75   public void noArgMethod() throws Exception {
76     ProducerToken token = ProducerToken.create(SimpleProducerModule_StrFactory.class);
77     Producer<String> producer =
78         SimpleProducerModule_StrFactory.create(executorProvider, componentMonitorProvider);
79     assertThat(producer.get().get()).isEqualTo("str");
80     InOrder order = inOrder(componentMonitor, monitor);
81     order.verify(componentMonitor).producerMonitorFor(token);
82     order.verify(monitor).methodStarting();
83     order.verify(monitor).methodFinished();
84     order.verify(monitor).succeeded("str");
85     order.verifyNoMoreInteractions();
86   }
87 
88   @Test
singleArgMethod()89   public void singleArgMethod() throws Exception {
90     SettableFuture<Integer> intFuture = SettableFuture.create();
91     CancellableProducer<Integer> intProducer = producerOfFuture(intFuture);
92     Producer<String> producer =
93         SimpleProducerModule_StrWithArgFactory.create(
94             executorProvider, componentMonitorProvider, intProducer);
95     assertThat(producer.get().isDone()).isFalse();
96     intFuture.set(42);
97     assertThat(producer.get().get()).isEqualTo("str with arg");
98   }
99 
100   @Test
successMonitor()101   public void successMonitor() throws Exception {
102     ProducerToken token = ProducerToken.create(SimpleProducerModule_SettableFutureStrFactory.class);
103 
104     SettableFuture<String> strFuture = SettableFuture.create();
105     @SuppressWarnings("FutureReturnValueIgnored")
106     SettableFuture<SettableFuture<String>> strFutureFuture = SettableFuture.create();
107     CancellableProducer<SettableFuture<String>> strFutureProducer =
108         producerOfFuture(strFutureFuture);
109     Producer<String> producer =
110         SimpleProducerModule_SettableFutureStrFactory.create(
111             executorProvider, componentMonitorProvider, strFutureProducer);
112     assertThat(producer.get().isDone()).isFalse();
113 
114     InOrder order = inOrder(componentMonitor, monitor);
115     order.verify(componentMonitor).producerMonitorFor(token);
116 
117     strFutureFuture.set(strFuture);
118     order.verify(monitor).methodStarting();
119     order.verify(monitor).methodFinished();
120     assertThat(producer.get().isDone()).isFalse();
121 
122     strFuture.set("monkey");
123     assertThat(producer.get().get()).isEqualTo("monkey");
124     order.verify(monitor).succeeded("monkey");
125 
126     order.verifyNoMoreInteractions();
127   }
128 
129   @Test
failureMonitor()130   public void failureMonitor() throws Exception {
131     ProducerToken token = ProducerToken.create(SimpleProducerModule_SettableFutureStrFactory.class);
132 
133     SettableFuture<String> strFuture = SettableFuture.create();
134     @SuppressWarnings("FutureReturnValueIgnored")
135     SettableFuture<SettableFuture<String>> strFutureFuture = SettableFuture.create();
136     CancellableProducer<SettableFuture<String>> strFutureProducer =
137         producerOfFuture(strFutureFuture);
138     Producer<String> producer =
139         SimpleProducerModule_SettableFutureStrFactory.create(
140             executorProvider, componentMonitorProvider, strFutureProducer);
141     assertThat(producer.get().isDone()).isFalse();
142 
143     InOrder order = inOrder(componentMonitor, monitor);
144     order.verify(componentMonitor).producerMonitorFor(token);
145 
146     strFutureFuture.set(strFuture);
147     order.verify(monitor).methodStarting();
148     order.verify(monitor).methodFinished();
149     assertThat(producer.get().isDone()).isFalse();
150 
151     Throwable t = new RuntimeException("monkey");
152     strFuture.setException(t);
153     try {
154       producer.get().get();
155       fail();
156     } catch (ExecutionException e) {
157       assertThat(e).hasCauseThat().isSameInstanceAs(t);
158       order.verify(monitor).failed(t);
159     }
160 
161     order.verifyNoMoreInteractions();
162   }
163 
164   @Test
failureMonitorDueToThrowingProducer()165   public void failureMonitorDueToThrowingProducer() throws Exception {
166     ProducerToken token = ProducerToken.create(SimpleProducerModule_ThrowingProducerFactory.class);
167 
168     Producer<String> producer =
169         SimpleProducerModule_ThrowingProducerFactory.create(
170             executorProvider, componentMonitorProvider);
171     assertThat(producer.get().isDone()).isTrue();
172 
173     InOrder order = inOrder(componentMonitor, monitor);
174     order.verify(componentMonitor).producerMonitorFor(token);
175 
176     order.verify(monitor).methodStarting();
177     order.verify(monitor).methodFinished();
178 
179     try {
180       producer.get().get();
181       fail();
182     } catch (ExecutionException e) {
183       order.verify(monitor).failed(e.getCause());
184     }
185 
186     order.verifyNoMoreInteractions();
187   }
188 
189   @Test(expected = NullPointerException.class)
nullComponentMonitorProvider()190   public void nullComponentMonitorProvider() throws Exception {
191     SimpleProducerModule_StrFactory.create(executorProvider, null);
192   }
193 
producerOfFuture(final ListenableFuture<T> future)194   private static <T> CancellableProducer<T> producerOfFuture(final ListenableFuture<T> future) {
195     return new AbstractProducer<T>() {
196       @Override
197       public ListenableFuture<T> compute() {
198         return future;
199       }
200     };
201   }
202 }
203