1 package com.atlassian.httpclient.api;
2
3 import com.atlassian.util.concurrent.Effect;
4 import com.atlassian.util.concurrent.Promise;
5 import com.google.common.base.Function;
6 import com.google.common.util.concurrent.SettableFuture;
7 import org.junit.Test;
8 import org.junit.runner.RunWith;
9 import org.mockito.Mock;
10 import org.mockito.runners.MockitoJUnitRunner;
11
12 import javax.annotation.Nullable;
13
14 import static com.atlassian.util.concurrent.Promises.forListenableFuture;
15 import static org.junit.Assert.assertEquals;
16 import static org.junit.Assert.assertTrue;
17
18 @RunWith(MockitoJUnitRunner.class)
19 public final class WrappingResponsePromiseTest {
20 @Mock
21 private Response response;
22
23 @Test
24 public final void testThatWhenMapFunctionThrowsExceptionThenMappedPromiseIsFailWithException() {
25 final String message = "This is the message for the test!";
26
27 final SettableFuture<Response> future = SettableFuture.create();
28 final ResponsePromise responsePromise = new WrappingResponsePromise(forListenableFuture(future));
29
30 final OnTimeEffect onFail = new OnTimeEffect() {
31 @Override
32 void doApply(Throwable t) {
33 assertEquals(message, t.getMessage());
34 }
35 };
36
37 final Promise<Object> mappedPromise = responsePromise.map(newExceptionFunction(message)).fail(onFail);
38
39 future.set(response);
40
41 assertTrue(onFail.isCalled());
42 assertTrue(mappedPromise.isDone());
43 }
44
45 private <I, O> ExceptionThrowingFunction<I, O> newExceptionFunction(String message) {
46 return new ExceptionThrowingFunction<I, O>(message);
47 }
48
49 private static abstract class OnTimeEffect implements Effect<Throwable> {
50 private boolean called = false;
51
52 @Override
53 public void apply(Throwable t) {
54 if (called) {
55 throw new IllegalStateException("This effect method already has been called!");
56 }
57 called = true;
58 doApply(t);
59 }
60
61 abstract void doApply(Throwable t);
62
63 boolean isCalled() {
64 return called;
65 }
66 }
67
68 private static final class ExceptionThrowingFunction<I, O> implements Function<I, O> {
69 private final String message;
70
71 public ExceptionThrowingFunction(String message) {
72 this.message = message;
73 }
74
75 @Override
76 public O apply(@Nullable I input) {
77 throw new RuntimeException(message);
78 }
79 }
80 }