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