1 /* 2 * Copyright (C) 2016 The Guava 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 com.google.common.util.concurrent; 18 19 import static com.google.common.base.Verify.verify; 20 import static com.google.common.truth.Truth.assertThat; 21 import static com.google.common.util.concurrent.Futures.immediateFailedFuture; 22 import static com.google.common.util.concurrent.Futures.immediateFuture; 23 import static com.google.common.util.concurrent.MoreExecutors.directExecutor; 24 import static java.util.concurrent.Executors.newScheduledThreadPool; 25 import static java.util.concurrent.TimeUnit.SECONDS; 26 27 import com.google.common.annotations.GwtCompatible; 28 import com.google.common.annotations.GwtIncompatible; 29 import com.google.common.base.Function; 30 import com.google.common.util.concurrent.ForwardingListenableFuture.SimpleForwardingListenableFuture; 31 import java.util.concurrent.ExecutionException; 32 import java.util.concurrent.ScheduledExecutorService; 33 import java.util.concurrent.TimeoutException; 34 import junit.framework.TestCase; 35 36 /** 37 * Tests for {@link FluentFuture}. The tests cover only the basics for the API. The actual logic is 38 * tested in {@link FuturesTest}. 39 */ 40 @GwtCompatible(emulated = true) 41 public class FluentFutureTest extends TestCase { testFromFluentFuture()42 public void testFromFluentFuture() { 43 FluentFuture<String> f = FluentFuture.from(SettableFuture.<String>create()); 44 assertThat(FluentFuture.from(f)).isSameInstanceAs(f); 45 } 46 testFromFluentFuturePassingAsNonFluent()47 public void testFromFluentFuturePassingAsNonFluent() { 48 ListenableFuture<String> f = FluentFuture.from(SettableFuture.<String>create()); 49 assertThat(FluentFuture.from(f)).isSameInstanceAs(f); 50 } 51 testFromNonFluentFuture()52 public void testFromNonFluentFuture() throws Exception { 53 ListenableFuture<String> f = 54 new SimpleForwardingListenableFuture<String>(immediateFuture("a")) {}; 55 verify(!(f instanceof FluentFuture)); 56 assertThat(FluentFuture.from(f).get()).isEqualTo("a"); 57 // TODO(cpovirk): Test forwarding more extensively. 58 } 59 testAddCallback()60 public void testAddCallback() { 61 FluentFuture<String> f = FluentFuture.from(immediateFuture("a")); 62 final boolean[] called = new boolean[1]; 63 f.addCallback( 64 new FutureCallback<String>() { 65 @Override 66 public void onSuccess(String result) { 67 called[0] = true; 68 } 69 70 @Override 71 public void onFailure(Throwable t) {} 72 }, 73 directExecutor()); 74 assertThat(called[0]).isTrue(); 75 } 76 testCatching()77 public void testCatching() throws Exception { 78 FluentFuture<?> f = 79 FluentFuture.from(immediateFailedFuture(new RuntimeException())) 80 .catching( 81 Throwable.class, 82 new Function<Throwable, Class<?>>() { 83 @Override 84 public Class<?> apply(Throwable input) { 85 return input.getClass(); 86 } 87 }, 88 directExecutor()); 89 assertThat(f.get()).isEqualTo(RuntimeException.class); 90 } 91 testCatchingAsync()92 public void testCatchingAsync() throws Exception { 93 FluentFuture<?> f = 94 FluentFuture.from(immediateFailedFuture(new RuntimeException())) 95 .catchingAsync( 96 Throwable.class, 97 new AsyncFunction<Throwable, Class<?>>() { 98 @Override 99 public ListenableFuture<Class<?>> apply(Throwable input) { 100 return Futures.<Class<?>>immediateFuture(input.getClass()); 101 } 102 }, 103 directExecutor()); 104 assertThat(f.get()).isEqualTo(RuntimeException.class); 105 } 106 testTransform()107 public void testTransform() throws Exception { 108 FluentFuture<Integer> f = 109 FluentFuture.from(immediateFuture(1)) 110 .transform( 111 new Function<Integer, Integer>() { 112 @Override 113 public Integer apply(Integer input) { 114 return input + 1; 115 } 116 }, 117 directExecutor()); 118 assertThat(f.get()).isEqualTo(2); 119 } 120 testTransformAsync()121 public void testTransformAsync() throws Exception { 122 FluentFuture<Integer> f = 123 FluentFuture.from(immediateFuture(1)) 124 .transformAsync( 125 new AsyncFunction<Integer, Integer>() { 126 @Override 127 public ListenableFuture<Integer> apply(Integer input) { 128 return immediateFuture(input + 1); 129 } 130 }, 131 directExecutor()); 132 assertThat(f.get()).isEqualTo(2); 133 } 134 135 @GwtIncompatible // withTimeout testWithTimeout()136 public void testWithTimeout() throws Exception { 137 ScheduledExecutorService executor = newScheduledThreadPool(1); 138 try { 139 FluentFuture<?> f = 140 FluentFuture.from(SettableFuture.create()).withTimeout(0, SECONDS, executor); 141 try { 142 f.get(); 143 fail(); 144 } catch (ExecutionException e) { 145 assertThat(e).hasCauseThat().isInstanceOf(TimeoutException.class); 146 } 147 } finally { 148 executor.shutdown(); 149 } 150 } 151 } 152