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