1 /* 2 * Copyright (C) 2014 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.producers.internal; 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.ArgumentMatchers.nullable; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.verifyNoMoreInteractions; 25 import static org.mockito.Mockito.when; 26 27 import com.google.common.util.concurrent.Futures; 28 import com.google.common.util.concurrent.ListenableFuture; 29 import com.google.common.util.concurrent.MoreExecutors; 30 import com.google.common.util.concurrent.SettableFuture; 31 import dagger.internal.Provider; 32 import dagger.producers.Producer; 33 import dagger.producers.monitoring.ProducerMonitor; 34 import dagger.producers.monitoring.ProducerToken; 35 import dagger.producers.monitoring.ProductionComponentMonitor; 36 import java.util.concurrent.ExecutionException; 37 import java.util.concurrent.Executor; 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.junit.runners.JUnit4; 42 import org.mockito.Mock; 43 import org.mockito.Mockito; 44 import org.mockito.MockitoAnnotations; 45 46 /** 47 * Tests {@link AbstractProducer}. 48 */ 49 @RunWith(JUnit4.class) 50 public class AbstractProducesMethodProducerTest { 51 @Mock private ProductionComponentMonitor componentMonitor; 52 private ProducerMonitor monitor; 53 private Provider<ProductionComponentMonitor> componentMonitorProvider; 54 55 @Before initMocks()56 public void initMocks() { 57 MockitoAnnotations.initMocks(this); 58 monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS); 59 when(componentMonitor.producerMonitorFor(nullable(ProducerToken.class))).thenReturn(monitor); 60 componentMonitorProvider = 61 new Provider<ProductionComponentMonitor>() { 62 @Override 63 public ProductionComponentMonitor get() { 64 return componentMonitor; 65 } 66 }; 67 } 68 69 @Test monitor_success()70 public void monitor_success() throws Exception { 71 SettableFuture<Integer> delegateFuture = SettableFuture.create(); 72 Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture); 73 74 ListenableFuture<Integer> future = producer.get(); 75 assertThat(future.isDone()).isFalse(); 76 verify(monitor).ready(); 77 verify(monitor).requested(); 78 verify(monitor).addCallbackTo(anyListenableFuture()); 79 verify(monitor).methodStarting(); 80 verify(monitor).methodFinished(); 81 delegateFuture.set(-42); 82 assertThat(future.get()).isEqualTo(-42); 83 verify(monitor).succeeded(-42); 84 verifyNoMoreInteractions(monitor); 85 } 86 87 @Test monitor_failure()88 public void monitor_failure() throws Exception { 89 SettableFuture<Integer> delegateFuture = SettableFuture.create(); 90 Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture); 91 92 ListenableFuture<Integer> future = producer.get(); 93 assertThat(future.isDone()).isFalse(); 94 verify(monitor).ready(); 95 verify(monitor).requested(); 96 verify(monitor).addCallbackTo(anyListenableFuture()); 97 verify(monitor).methodStarting(); 98 verify(monitor).methodFinished(); 99 Throwable t = new RuntimeException("monkey"); 100 delegateFuture.setException(t); 101 try { 102 future.get(); 103 fail(); 104 } catch (ExecutionException e) { 105 assertThat(e).hasCauseThat().isSameInstanceAs(t); 106 } 107 verify(monitor).failed(t); 108 verifyNoMoreInteractions(monitor); 109 } 110 anyListenableFuture()111 private ListenableFuture<?> anyListenableFuture() { 112 return any(ListenableFuture.class); 113 } 114 115 @Test(expected = NullPointerException.class) monitor_null()116 public void monitor_null() throws Exception { 117 new DelegateProducer<>(null, Futures.immediateFuture(42)); 118 } 119 120 static final class DelegateProducer<T> extends AbstractProducesMethodProducer<Void, T> { 121 private final ListenableFuture<T> delegate; 122 DelegateProducer( Provider<ProductionComponentMonitor> componentMonitorProvider, ListenableFuture<T> delegate)123 DelegateProducer( 124 Provider<ProductionComponentMonitor> componentMonitorProvider, 125 ListenableFuture<T> delegate) { 126 super( 127 componentMonitorProvider, 128 null, // token 129 new Provider<Executor>() { 130 @Override 131 public Executor get() { 132 return MoreExecutors.directExecutor(); 133 } 134 }); 135 this.delegate = delegate; 136 } 137 138 @Override collectDependencies()139 protected ListenableFuture<Void> collectDependencies() { 140 return Futures.immediateFuture(null); 141 } 142 143 @Override callProducesMethod(Void asyncDependencies)144 protected ListenableFuture<T> callProducesMethod(Void asyncDependencies) { 145 return delegate; 146 } 147 } 148 } 149